From 1687ef39e2d9ca97cdee1149f34fba254f628436 Mon Sep 17 00:00:00 2001 From: dpolukhin Date: Mon, 22 Jun 2015 04:12:37 -0700 Subject: [PATCH] Don't install marked default apps for enterprise users Some OEM default apps don't fir to enterprise or EDU environment. This CL allows to mark such inappropriate apps for enterprise users and restricts installation. BUG=492644 TEST=manual Review URL: https://codereview.chromium.org/1194543002 Cr-Commit-Position: refs/heads/master@{#335486} --- .../extensions/extension_service_unittest.cc | 30 +++++++++++++++++++ .../browser/extensions/external_provider_impl.cc | 34 ++++++++++++++++++++-- chrome/browser/extensions/external_provider_impl.h | 6 ++++ chrome/browser/policy/profile_policy_connector.cc | 6 ++++ chrome/browser/policy/profile_policy_connector.h | 2 ++ 5 files changed, 76 insertions(+), 2 deletions(-) diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index e213e77a7bdb..46d7411ab21c 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc @@ -62,6 +62,8 @@ #include "chrome/browser/extensions/test_extension_system.h" #include "chrome/browser/extensions/unpacked_installer.h" #include "chrome/browser/extensions/updater/extension_updater.h" +#include "chrome/browser/policy/profile_policy_connector.h" +#include "chrome/browser/policy/profile_policy_connector_factory.h" #include "chrome/browser/prefs/pref_service_syncable.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/profile_sync_service_factory.h" @@ -344,6 +346,7 @@ class MockProviderVisitor : ids_found_(0), fake_base_path_(fake_base_path), expected_creation_flags_(expected_creation_flags) { + profile_.reset(new TestingProfile); } int Visit(const std::string& json_data) { @@ -5534,6 +5537,33 @@ TEST_F(ExtensionServiceTest, ExternalPrefProvider) { EXPECT_EQ(3, min_profile_created_by_version_visitor.Visit(json_data)); } +TEST_F(ExtensionServiceTest, DoNotInstallForEnterprise) { + InitializeEmptyExtensionService(); + + const base::FilePath base_path(FILE_PATH_LITERAL("//base/path")); + ASSERT_TRUE(base_path.IsAbsolute()); + MockProviderVisitor visitor(base_path); + policy::ProfilePolicyConnector* const connector = + policy::ProfilePolicyConnectorFactory::GetForBrowserContext( + visitor.profile()); + connector->OverrideIsManagedForTesting(true); + EXPECT_TRUE(connector->IsManaged()); + + std::string json_data = + "{" + " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" + " \"external_crx\": \"RandomExtension.crx\"," + " \"external_version\": \"1.0\"," + " \"do_not_install_for_enterprise\": true" + " }," + " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {" + " \"external_crx\": \"RandomExtension2.crx\"," + " \"external_version\": \"1.0\"" + " }" + "}"; + EXPECT_EQ(1, visitor.Visit(json_data)); +} + // Test loading good extensions from the profile directory. TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) { // Ensure we're testing in "en" and leave global state untouched. diff --git a/chrome/browser/extensions/external_provider_impl.cc b/chrome/browser/extensions/external_provider_impl.cc index 12ab37ed85d7..3dbfd34e5b9d 100644 --- a/chrome/browser/extensions/external_provider_impl.cc +++ b/chrome/browser/extensions/external_provider_impl.cc @@ -24,6 +24,8 @@ #include "chrome/browser/extensions/external_component_loader.h" #include "chrome/browser/extensions/external_policy_loader.h" #include "chrome/browser/extensions/external_pref_loader.h" +#include "chrome/browser/policy/profile_policy_connector.h" +#include "chrome/browser/policy/profile_policy_connector_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" @@ -70,6 +72,8 @@ const char ExternalProviderImpl::kSupportedLocales[] = "supported_locales"; const char ExternalProviderImpl::kMayBeUntrusted[] = "may_be_untrusted"; const char ExternalProviderImpl::kMinProfileCreatedByVersion[] = "min_profile_created_by_version"; +const char ExternalProviderImpl::kDoNotInstallForEnterprise[] = + "do_not_install_for_enterprise"; ExternalProviderImpl::ExternalProviderImpl( VisitorInterface* service, @@ -240,9 +244,15 @@ void ExternalProviderImpl::SetPrefs(base::DictionaryValue* prefs) { creation_flags |= Extension::MAY_BE_UNTRUSTED; } - if (!ExternalProviderImpl::HandleMinProfileVersion(extension, extension_id, - &unsupported_extensions)) + if (!HandleMinProfileVersion(extension, extension_id, + &unsupported_extensions)) { continue; + } + + if (!HandleDoNotInstallForEnterprise(extension, extension_id, + &unsupported_extensions)) { + continue; + } std::string install_parameter; extension->GetString(kInstallParam, &install_parameter); @@ -393,6 +403,26 @@ bool ExternalProviderImpl::HandleMinProfileVersion( return true; } +bool ExternalProviderImpl::HandleDoNotInstallForEnterprise( + const base::DictionaryValue* extension, + const std::string& extension_id, + std::set* unsupported_extensions) { + bool do_not_install_for_enterprise = false; + if (extension->GetBoolean(kDoNotInstallForEnterprise, + &do_not_install_for_enterprise) && + do_not_install_for_enterprise) { + const policy::ProfilePolicyConnector* const connector = + policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile_); + if (connector->IsManaged()) { + unsupported_extensions->insert(extension_id); + VLOG(1) << "Skip installing (or uninstall) external extension " + << extension_id << " restricted for managed user"; + return false; + } + } + return true; +} + // static void ExternalProviderImpl::CreateExternalProviders( VisitorInterface* service, diff --git a/chrome/browser/extensions/external_provider_impl.h b/chrome/browser/extensions/external_provider_impl.h index 5a69b3129817..a75bdfe2b3a5 100644 --- a/chrome/browser/extensions/external_provider_impl.h +++ b/chrome/browser/extensions/external_provider_impl.h @@ -75,6 +75,7 @@ class ExternalProviderImpl : public ExternalProviderInterface { static const char kWasInstalledByOem[]; static const char kMayBeUntrusted[]; static const char kMinProfileCreatedByVersion[]; + static const char kDoNotInstallForEnterprise[]; void set_auto_acknowledge(bool auto_acknowledge) { auto_acknowledge_ = auto_acknowledge; @@ -89,6 +90,11 @@ class ExternalProviderImpl : public ExternalProviderInterface { const std::string& extension_id, std::set* unsupported_extensions); + bool HandleDoNotInstallForEnterprise( + const base::DictionaryValue* extension, + const std::string& extension_id, + std::set* unsupported_extensions); + // Location for external extensions that are provided by this provider from // local crx files. const Manifest::Location crx_location_; diff --git a/chrome/browser/policy/profile_policy_connector.cc b/chrome/browser/policy/profile_policy_connector.cc index 12b5b44e6556..ea55dfdf2abf 100644 --- a/chrome/browser/policy/profile_policy_connector.cc +++ b/chrome/browser/policy/profile_policy_connector.cc @@ -135,6 +135,10 @@ void ProfilePolicyConnector::InitForTesting(scoped_ptr service) { policy_service_ = service.Pass(); } +void ProfilePolicyConnector::OverrideIsManagedForTesting(bool is_managed) { + is_managed_override_.reset(new bool(is_managed)); +} + void ProfilePolicyConnector::Shutdown() { #if defined(OS_CHROMEOS) BrowserPolicyConnectorChromeOS* connector = @@ -149,6 +153,8 @@ void ProfilePolicyConnector::Shutdown() { } bool ProfilePolicyConnector::IsManaged() const { + if (is_managed_override_) + return *is_managed_override_; return !GetManagementDomain().empty(); } diff --git a/chrome/browser/policy/profile_policy_connector.h b/chrome/browser/policy/profile_policy_connector.h index b8a32951d2a4..957caa6310e6 100644 --- a/chrome/browser/policy/profile_policy_connector.h +++ b/chrome/browser/policy/profile_policy_connector.h @@ -38,6 +38,7 @@ class ProfilePolicyConnector : public KeyedService { CloudPolicyManager* user_cloud_policy_manager); void InitForTesting(scoped_ptr service); + void OverrideIsManagedForTesting(bool is_managed); // KeyedService: void Shutdown() override; @@ -74,6 +75,7 @@ class ProfilePolicyConnector : public KeyedService { #endif // defined(ENABLE_CONFIGURATION_POLICY) scoped_ptr policy_service_; + scoped_ptr is_managed_override_; DISALLOW_COPY_AND_ASSIGN(ProfilePolicyConnector); }; -- 2.11.4.GIT