| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/prefs/pref_service.h" |
| 5 #include "base/strings/stringprintf.h" | 6 #include "base/strings/stringprintf.h" |
| 7 #include "chrome/browser/browser_process.h" |
| 8 #include "chrome/browser/chromeos/policy/affiliation_test_helper.h" |
| 6 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" | 9 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
| 7 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" | 10 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" |
| 8 #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h" | 11 #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h" |
| 9 #include "chrome/browser/extensions/extension_apitest.h" | 12 #include "chrome/browser/extensions/extension_apitest.h" |
| 10 #include "chrome/browser/net/url_request_mock_util.h" | 13 #include "chrome/browser/net/url_request_mock_util.h" |
| 14 #include "chrome/test/base/ui_test_utils.h" |
| 11 #include "chromeos/dbus/fake_session_manager_client.h" | 15 #include "chromeos/dbus/fake_session_manager_client.h" |
| 12 #include "chromeos/login/user_names.h" | 16 #include "chromeos/login/user_names.h" |
| 13 #include "components/policy/core/common/mock_configuration_policy_provider.h" | 17 #include "components/policy/core/common/mock_configuration_policy_provider.h" |
| 14 #include "components/policy/core/common/policy_types.h" | |
| 15 #include "components/signin/core/account_id/account_id.h" | 18 #include "components/signin/core/account_id/account_id.h" |
| 19 #include "components/user_manager/user_manager.h" |
| 16 #include "content/public/browser/notification_service.h" | 20 #include "content/public/browser/notification_service.h" |
| 17 #include "content/public/test/test_utils.h" | 21 #include "content/public/test/test_utils.h" |
| 18 #include "extensions/browser/api_test_utils.h" | 22 #include "extensions/browser/api_test_utils.h" |
| 19 #include "extensions/browser/extension_registry.h" | 23 #include "extensions/browser/extension_registry.h" |
| 20 #include "extensions/browser/test_extension_registry_observer.h" | 24 #include "extensions/browser/test_extension_registry_observer.h" |
| 25 #include "extensions/test/result_catcher.h" |
| 21 #include "net/test/url_request/url_request_mock_http_job.h" | 26 #include "net/test/url_request/url_request_mock_http_job.h" |
| 22 #include "policy/policy_constants.h" | 27 #include "policy/policy_constants.h" |
| 23 | 28 |
| 24 namespace { | 29 namespace { |
| 25 | 30 |
| 26 const char kDeviceId[] = "device_id"; | 31 const char kDeviceId[] = "device_id"; |
| 27 const base::FilePath::CharType kTestExtensionDir[] = | 32 const base::FilePath::CharType kTestExtensionDir[] = |
| 28 FILE_PATH_LITERAL("extensions/api_test/enterprise_device_attributes"); | 33 FILE_PATH_LITERAL("extensions/api_test/enterprise_device_attributes"); |
| 29 const base::FilePath::CharType kUpdateManifestFileName[] = | 34 const base::FilePath::CharType kUpdateManifestFileName[] = |
| 30 FILE_PATH_LITERAL("update_manifest.xml"); | 35 FILE_PATH_LITERAL("update_manifest.xml"); |
| 31 | 36 |
| 37 const char kAffiliatedUserEmail[] = "user@example.com"; |
| 38 const char kAffiliationID[] = "some-affiliation-id"; |
| 39 const char kAnotherAffiliationID[] = "another-affiliation-id"; |
| 40 |
| 32 // The managed_storage extension has a key defined in its manifest, so that | 41 // The managed_storage extension has a key defined in its manifest, so that |
| 33 // its extension ID is well-known and the policy system can push policies for | 42 // its extension ID is well-known and the policy system can push policies for |
| 34 // the extension. | 43 // the extension. |
| 35 const char kTestExtensionID[] = "nbiliclbejdndfpchgkbmfoppjplbdok"; | 44 const char kTestExtensionID[] = "nbiliclbejdndfpchgkbmfoppjplbdok"; |
| 36 | 45 |
| 46 struct Params { |
| 47 explicit Params(bool affiliated) : affiliated_(affiliated) {} |
| 48 bool affiliated_; |
| 49 }; |
| 50 |
| 37 } // namespace | 51 } // namespace |
| 38 | 52 |
| 39 namespace extensions { | 53 namespace extensions { |
| 40 | 54 |
| 41 class EnterpriseDeviceAttributesTest : public ExtensionApiTest { | 55 class EnterpriseDeviceAttributesTest : |
| 56 public ExtensionApiTest, |
| 57 public ::testing::WithParamInterface<Params> { |
| 42 public: | 58 public: |
| 43 explicit EnterpriseDeviceAttributesTest(const std::string& domain) | 59 EnterpriseDeviceAttributesTest() { |
| 44 : fake_session_manager_client_(new chromeos::FakeSessionManagerClient), | 60 set_exit_when_last_browser_closes(false); |
| 45 test_domain_(domain) {} | 61 set_chromeos_user_ = false; |
| 62 } |
| 46 | 63 |
| 47 protected: | 64 protected: |
| 65 // ExtensionApiTest |
| 66 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 67 ExtensionApiTest::SetUpCommandLine(command_line); |
| 68 chromeos::affiliation_test_helper:: |
| 69 AppendCommandLineSwitchesForLoginManager(command_line); |
| 70 } |
| 71 |
| 48 void SetUpInProcessBrowserTestFixture() override { | 72 void SetUpInProcessBrowserTestFixture() override { |
| 73 ExtensionApiTest::SetUpInProcessBrowserTestFixture(); |
| 74 |
| 75 chromeos::FakeSessionManagerClient* fake_session_manager_client = |
| 76 new chromeos::FakeSessionManagerClient; |
| 49 chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( | 77 chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( |
| 50 make_scoped_ptr(fake_session_manager_client_)); | 78 scoped_ptr<chromeos::SessionManagerClient>( |
| 51 ExtensionApiTest::SetUpInProcessBrowserTestFixture(); | 79 fake_session_manager_client)); |
| 80 |
| 81 std::set<std::string> device_affiliation_ids; |
| 82 device_affiliation_ids.insert(kAffiliationID); |
| 83 chromeos::affiliation_test_helper::SetDeviceAffiliationID( |
| 84 &test_helper_, fake_session_manager_client, device_affiliation_ids); |
| 85 |
| 86 std::set<std::string> user_affiliation_ids; |
| 87 if (GetParam().affiliated_) { |
| 88 user_affiliation_ids.insert(kAffiliationID); |
| 89 } else { |
| 90 user_affiliation_ids.insert(kAnotherAffiliationID); |
| 91 } |
| 92 policy::UserPolicyBuilder user_policy; |
| 93 chromeos::affiliation_test_helper::SetUserAffiliationIDs( |
| 94 &user_policy, fake_session_manager_client, |
| 95 affiliated_account_id_.GetUserEmail(), user_affiliation_ids); |
| 52 | 96 |
| 53 // Set up fake install attributes. | 97 // Set up fake install attributes. |
| 54 scoped_ptr<policy::StubEnterpriseInstallAttributes> attributes( | 98 scoped_ptr<policy::StubEnterpriseInstallAttributes> attributes( |
| 55 new policy::StubEnterpriseInstallAttributes()); | 99 new policy::StubEnterpriseInstallAttributes()); |
| 56 | 100 |
| 57 attributes->SetDomain(test_domain_); | 101 attributes->SetRegistrationUser(affiliated_account_id_.GetUserEmail()); |
| 58 attributes->SetRegistrationUser( | |
| 59 chromeos::login::StubAccountId().GetUserEmail()); | |
| 60 policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting( | 102 policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting( |
| 61 attributes.release()); | 103 attributes.release()); |
| 62 | 104 |
| 63 test_helper_.InstallOwnerKey(); | 105 test_helper_.InstallOwnerKey(); |
| 64 // Init the device policy. | 106 // Init the device policy. |
| 65 policy::DevicePolicyBuilder* device_policy = test_helper_.device_policy(); | 107 policy::DevicePolicyBuilder* device_policy = test_helper_.device_policy(); |
| 66 device_policy->SetDefaultSigningKey(); | 108 device_policy->SetDefaultSigningKey(); |
| 67 device_policy->policy_data().set_directory_api_id(kDeviceId); | 109 device_policy->policy_data().set_directory_api_id(kDeviceId); |
| 68 device_policy->Build(); | 110 device_policy->Build(); |
| 69 | 111 |
| 70 fake_session_manager_client_->set_device_policy(device_policy->GetBlob()); | 112 fake_session_manager_client->set_device_policy(device_policy->GetBlob()); |
| 71 fake_session_manager_client_->OnPropertyChangeComplete(true); | 113 fake_session_manager_client->OnPropertyChangeComplete(true); |
| 72 | 114 |
| 73 // Init the user policy provider. | 115 // Init the user policy provider. |
| 74 EXPECT_CALL(policy_provider_, IsInitializationComplete(testing::_)) | 116 EXPECT_CALL(policy_provider_, IsInitializationComplete(testing::_)) |
| 75 .WillRepeatedly(testing::Return(true)); | 117 .WillRepeatedly(testing::Return(true)); |
| 76 policy_provider_.SetAutoRefresh(); | 118 policy_provider_.SetAutoRefresh(); |
| 77 policy::BrowserPolicyConnector::SetPolicyProviderForTesting( | 119 policy::BrowserPolicyConnector::SetPolicyProviderForTesting( |
| 78 &policy_provider_); | 120 &policy_provider_); |
| 79 } | 121 } |
| 80 | 122 |
| 81 void SetUpOnMainThread() override { | 123 void SetUpOnMainThread() override { |
| 124 const base::ListValue* users = |
| 125 g_browser_process->local_state()->GetList("LoggedInUsers"); |
| 126 if (!users->empty()) { |
| 127 chromeos::affiliation_test_helper::LoginUser( |
| 128 affiliated_account_id_.GetUserEmail()); |
| 129 } |
| 130 |
| 82 ExtensionApiTest::SetUpOnMainThread(); | 131 ExtensionApiTest::SetUpOnMainThread(); |
| 83 | |
| 84 // Enable the URLRequestMock, which is required for force-installing the | |
| 85 // test extension through policy. | |
| 86 content::BrowserThread::PostTask( | |
| 87 content::BrowserThread::IO, FROM_HERE, | |
| 88 base::Bind(chrome_browser_net::SetUrlRequestMocksEnabled, true)); | |
| 89 | |
| 90 SetPolicy(); | |
| 91 } | 132 } |
| 92 | 133 |
| 93 private: | |
| 94 void SetPolicy() { | 134 void SetPolicy() { |
| 95 // Extensions that are force-installed come from an update URL, which | 135 // Extensions that are force-installed come from an update URL, which |
| 96 // defaults to the webstore. Use a mock URL for this test with an update | 136 // defaults to the webstore. Use a mock URL for this test with an update |
| 97 // manifest that includes the crx file of the test extension. | 137 // manifest that includes the crx file of the test extension. |
| 98 base::FilePath update_manifest_path = | 138 base::FilePath update_manifest_path = |
| 99 base::FilePath(kTestExtensionDir).Append(kUpdateManifestFileName); | 139 base::FilePath(kTestExtensionDir).Append(kUpdateManifestFileName); |
| 100 GURL update_manifest_url(net::URLRequestMockHTTPJob::GetMockUrl( | 140 GURL update_manifest_url(net::URLRequestMockHTTPJob::GetMockUrl( |
| 101 update_manifest_path.MaybeAsASCII())); | 141 update_manifest_path.MaybeAsASCII())); |
| 102 | 142 |
| 103 scoped_ptr<base::ListValue> forcelist(new base::ListValue); | 143 scoped_ptr<base::ListValue> forcelist(new base::ListValue); |
| 104 forcelist->AppendString(base::StringPrintf( | 144 forcelist->AppendString(base::StringPrintf( |
| 105 "%s;%s", kTestExtensionID, update_manifest_url.spec().c_str())); | 145 "%s;%s", kTestExtensionID, update_manifest_url.spec().c_str())); |
| 106 | 146 |
| 107 policy::PolicyMap policy; | 147 policy::PolicyMap policy; |
| 108 policy.Set(policy::key::kExtensionInstallForcelist, | 148 policy.Set(policy::key::kExtensionInstallForcelist, |
| 109 policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE, | 149 policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE, |
| 110 policy::POLICY_SOURCE_CLOUD, forcelist.release(), nullptr); | 150 policy::POLICY_SOURCE_CLOUD, forcelist.release(), nullptr); |
| 111 | 151 |
| 112 // Set the policy and wait until the extension is installed. | 152 // Set the policy and wait until the extension is installed. |
| 113 extensions::TestExtensionRegistryObserver observer( | 153 extensions::TestExtensionRegistryObserver observer( |
| 114 ExtensionRegistry::Get(profile())); | 154 ExtensionRegistry::Get(profile())); |
| 115 policy_provider_.UpdateChromePolicy(policy); | 155 policy_provider_.UpdateChromePolicy(policy); |
| 116 observer.WaitForExtensionLoaded(); | 156 observer.WaitForExtensionLoaded(); |
| 117 } | 157 } |
| 118 | 158 |
| 119 chromeos::FakeSessionManagerClient* const fake_session_manager_client_; | 159 // Load |page_url| in |browser| and wait for PASSED or FAILED notification. |
| 160 // The functionality of this function is reduced functionality of |
| 161 // RunExtensionSubtest(), but we don't use it here because it requires |
| 162 // function InProcessBrowserTest::browser() to return non-NULL pointer. |
| 163 // Unfortunately it returns the value which is set in constructor and can't be |
| 164 // modified. Because on login flow there is no browser, the function |
| 165 // InProcessBrowserTest::browser() always returns NULL. Besides this we need |
| 166 // only very little functionality from RunExtensionSubtest(). Thus so that |
| 167 // don't make RunExtensionSubtest() to complex we just introduce a new |
| 168 // function. |
| 169 bool TestExtension(Browser* browser, const std::string& page_url) { |
| 170 DCHECK(!page_url.empty()) << "page_url cannot be empty"; |
| 171 |
| 172 extensions::ResultCatcher catcher; |
| 173 ui_test_utils::NavigateToURL(browser, GURL(page_url)); |
| 174 |
| 175 if (!catcher.GetNextResult()) { |
| 176 message_ = catcher.message(); |
| 177 return false; |
| 178 } |
| 179 return true; |
| 180 } |
| 181 |
| 182 const AccountId affiliated_account_id_ = |
| 183 AccountId::FromUserEmail(kAffiliatedUserEmail); |
| 184 |
| 185 private: |
| 120 policy::MockConfigurationPolicyProvider policy_provider_; | 186 policy::MockConfigurationPolicyProvider policy_provider_; |
| 121 policy::DevicePolicyCrosTestHelper test_helper_; | 187 policy::DevicePolicyCrosTestHelper test_helper_; |
| 122 const std::string test_domain_; | |
| 123 }; | 188 }; |
| 124 | 189 |
| 125 // Creates affiliated user before browser initializes. | 190 IN_PROC_BROWSER_TEST_P(EnterpriseDeviceAttributesTest, PRE_Success) { |
| 126 class EnterpriseDeviceAttributesAffiliatedTest | 191 chromeos::affiliation_test_helper::PreLoginUser( |
| 127 : public EnterpriseDeviceAttributesTest { | 192 affiliated_account_id_.GetUserEmail()); |
| 128 public: | 193 } |
| 129 EnterpriseDeviceAttributesAffiliatedTest() | |
| 130 : EnterpriseDeviceAttributesTest("gmail.com") {} | |
| 131 }; | |
| 132 | 194 |
| 133 // Creates non-affiliated user before browser init. | 195 IN_PROC_BROWSER_TEST_P(EnterpriseDeviceAttributesTest, Success) { |
| 134 class EnterpriseDeviceAttributesNonAffiliatedTest | 196 content::BrowserThread::PostTask( |
| 135 : public EnterpriseDeviceAttributesTest { | 197 content::BrowserThread::IO, FROM_HERE, |
| 136 public: | 198 base::Bind(chrome_browser_net::SetUrlRequestMocksEnabled, true)); |
| 137 EnterpriseDeviceAttributesNonAffiliatedTest() | |
| 138 : EnterpriseDeviceAttributesTest("example.com") {} | |
| 139 }; | |
| 140 | 199 |
| 141 // Tests the case of an affiliated user and pre-installed extension. Fetches | 200 SetPolicy(); |
| 142 // the valid cloud directory device id. | 201 |
| 143 IN_PROC_BROWSER_TEST_F(EnterpriseDeviceAttributesAffiliatedTest, Success) { | 202 EXPECT_EQ(GetParam().affiliated_, user_manager::UserManager::Get()-> |
| 203 FindUser(affiliated_account_id_)->is_affiliated()); |
| 204 |
| 205 // Device ID is available only for affiliated user. |
| 206 std::string device_id = GetParam().affiliated_ ? kDeviceId : ""; |
| 207 |
| 144 // Pass the expected value (device_id) to test. | 208 // Pass the expected value (device_id) to test. |
| 145 ASSERT_TRUE(RunExtensionSubtest( | 209 ASSERT_TRUE(TestExtension(CreateBrowser(profile()), |
| 146 "", base::StringPrintf("chrome-extension://%s/basic.html?%s", | 210 base::StringPrintf("chrome-extension://%s/basic.html?%s", |
| 147 kTestExtensionID, kDeviceId))) | 211 kTestExtensionID, device_id.c_str()))) |
| 148 << message_; | 212 << message_; |
| 149 } | 213 } |
| 150 | 214 |
| 151 // Test the case of non-affiliated user and pre-installed by policy extension. | |
| 152 // Extension API is available, but fetches the empty string. | |
| 153 IN_PROC_BROWSER_TEST_F(EnterpriseDeviceAttributesNonAffiliatedTest, | |
| 154 EmptyString) { | |
| 155 // Pass the expected value (empty string) to test. | |
| 156 ASSERT_TRUE(RunExtensionSubtest( | |
| 157 "", base::StringPrintf("chrome-extension://%s/basic.html?%s", | |
| 158 kTestExtensionID, ""))) | |
| 159 << message_; | |
| 160 } | |
| 161 | |
| 162 // Ensure that extensions that are not pre-installed by policy throw an install | 215 // Ensure that extensions that are not pre-installed by policy throw an install |
| 163 // warning if they request the enterprise.deviceAttributes permission in the | 216 // warning if they request the enterprise.deviceAttributes permission in the |
| 164 // manifest and that such extensions don't see the | 217 // manifest and that such extensions don't see the |
| 165 // chrome.enterprise.deviceAttributes namespace. | 218 // chrome.enterprise.deviceAttributes namespace. |
| 166 IN_PROC_BROWSER_TEST_F( | 219 IN_PROC_BROWSER_TEST_F( |
| 167 ExtensionApiTest, | 220 ExtensionApiTest, |
| 168 EnterpriseDeviceAttributesIsRestrictedToPolicyExtension) { | 221 EnterpriseDeviceAttributesIsRestrictedToPolicyExtension) { |
| 169 ASSERT_TRUE(RunExtensionSubtest("enterprise_device_attributes", | 222 ASSERT_TRUE(RunExtensionSubtest("enterprise_device_attributes", |
| 170 "api_not_available.html", | 223 "api_not_available.html", |
| 171 kFlagIgnoreManifestWarnings)); | 224 kFlagIgnoreManifestWarnings)); |
| 172 | 225 |
| 173 base::FilePath extension_path = | 226 base::FilePath extension_path = |
| 174 test_data_dir_.AppendASCII("enterprise_device_attributes"); | 227 test_data_dir_.AppendASCII("enterprise_device_attributes"); |
| 175 extensions::ExtensionRegistry* registry = | 228 extensions::ExtensionRegistry* registry = |
| 176 extensions::ExtensionRegistry::Get(profile()); | 229 extensions::ExtensionRegistry::Get(profile()); |
| 177 const extensions::Extension* extension = | 230 const extensions::Extension* extension = |
| 178 GetExtensionByPath(registry->enabled_extensions(), extension_path); | 231 GetExtensionByPath(registry->enabled_extensions(), extension_path); |
| 179 ASSERT_FALSE(extension->install_warnings().empty()); | 232 ASSERT_FALSE(extension->install_warnings().empty()); |
| 180 EXPECT_EQ( | 233 EXPECT_EQ( |
| 181 "'enterprise.deviceAttributes' is not allowed for specified install " | 234 "'enterprise.deviceAttributes' is not allowed for specified install " |
| 182 "location.", | 235 "location.", |
| 183 extension->install_warnings()[0].message); | 236 extension->install_warnings()[0].message); |
| 184 } | 237 } |
| 185 | 238 |
| 239 // Both cases of affiliated and non-affiliated on the device user are tested. |
| 240 INSTANTIATE_TEST_CASE_P(AffiliationCheck, |
| 241 EnterpriseDeviceAttributesTest, |
| 242 ::testing::Values(Params(true), Params(false))); |
| 186 } // namespace extensions | 243 } // namespace extensions |
| OLD | NEW |