1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/pref_registry_simple.h"
12 #include "base/prefs/testing_pref_service.h"
13 #include "base/run_loop.h"
14 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
15 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
16 #include "chrome/browser/chromeos/settings/cros_settings.h"
17 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
18 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
19 #include "chrome/browser/chromeos/settings/device_settings_service.h"
20 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
21 #include "chrome/browser/policy/cloud/cloud_policy_client.h"
22 #include "chrome/browser/policy/cloud/mock_device_management_service.h"
23 #include "chrome/browser/policy/external_data_fetcher.h"
24 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h"
25 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
26 #include "chrome/browser/prefs/browser_prefs.h"
27 #include "chrome/test/base/testing_browser_process.h"
28 #include "chromeos/cryptohome/cryptohome_library.h"
29 #include "chromeos/dbus/dbus_client_implementation_type.h"
30 #include "chromeos/dbus/fake_cryptohome_client.h"
31 #include "google_apis/gaia/gaia_oauth_client.h"
32 #include "net/url_request/test_url_fetcher_factory.h"
33 #include "net/url_request/url_request_test_util.h"
34 #include "policy/policy_constants.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "testing/gtest/include/gtest/gtest.h"
38 using testing::AnyNumber
;
39 using testing::AtMost
;
42 using testing::SaveArg
;
45 namespace em
= enterprise_management
;
50 void CopyLockResult(base::RunLoop
* loop
,
51 EnterpriseInstallAttributes::LockResult
* out
,
52 EnterpriseInstallAttributes::LockResult result
) {
57 class DeviceCloudPolicyManagerChromeOSTest
58 : public chromeos::DeviceSettingsTestBase
{
60 DeviceCloudPolicyManagerChromeOSTest()
61 : cryptohome_library_(chromeos::CryptohomeLibrary::GetTestImpl()),
62 fake_cryptohome_client_(new chromeos::FakeCryptohomeClient()),
63 install_attributes_(fake_cryptohome_client_
.get()),
64 store_(new DeviceCloudPolicyStoreChromeOS(&device_settings_service_
,
65 &install_attributes_
)),
66 manager_(make_scoped_ptr(store_
),
67 loop_
.message_loop_proxy(),
68 &install_attributes_
) {
69 fake_cryptohome_client_
->Init(NULL
/* no dbus::Bus */);
72 virtual void SetUp() OVERRIDE
{
73 DeviceSettingsTestBase::SetUp();
74 chrome::RegisterLocalState(local_state_
.registry());
77 // DeviceOAuth2TokenService uses the system request context to fetch
78 // OAuth tokens, then writes the token to local state, encrypting it
79 // first with methods in CryptohomeLibrary.
80 request_context_getter_
= new net::TestURLRequestContextGetter(
81 loop_
.message_loop_proxy());
82 TestingBrowserProcess::GetGlobal()->SetSystemRequestContext(
83 request_context_getter_
.get());
84 TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_
);
85 chromeos::DeviceOAuth2TokenServiceFactory::Initialize();
86 // TODO(satorux): Remove CryptohomeLibrary::SetForTest() when it's ready.
87 // (removing it now breaks the unit test). crbug.com/141016.
88 chromeos::CryptohomeLibrary::SetForTest(cryptohome_library_
.get());
89 url_fetcher_response_code_
= 200;
90 url_fetcher_response_string_
= "{\"access_token\":\"accessToken4Test\","
91 "\"expires_in\":1234,"
92 "\"refresh_token\":\"refreshToken4Test\"}";
95 virtual void TearDown() OVERRIDE
{
97 DeviceSettingsTestBase::TearDown();
99 chromeos::DeviceOAuth2TokenServiceFactory::Shutdown();
100 chromeos::CryptohomeLibrary::SetForTest(NULL
);
101 TestingBrowserProcess::GetGlobal()->SetLocalState(NULL
);
104 scoped_ptr
<chromeos::CryptohomeLibrary
> cryptohome_library_
;
105 scoped_ptr
<chromeos::FakeCryptohomeClient
> fake_cryptohome_client_
;
106 EnterpriseInstallAttributes install_attributes_
;
108 scoped_refptr
<net::URLRequestContextGetter
> request_context_getter_
;
109 net::TestURLFetcherFactory url_fetcher_factory_
;
110 int url_fetcher_response_code_
;
111 string url_fetcher_response_string_
;
112 TestingPrefServiceSimple local_state_
;
113 MockDeviceManagementService device_management_service_
;
114 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_
;
115 chromeos::ScopedTestCrosSettings test_cros_settings_
;
117 DeviceCloudPolicyStoreChromeOS
* store_
;
118 DeviceCloudPolicyManagerChromeOS manager_
;
121 DISALLOW_COPY_AND_ASSIGN(DeviceCloudPolicyManagerChromeOSTest
);
124 TEST_F(DeviceCloudPolicyManagerChromeOSTest
, FreshDevice
) {
125 owner_key_util_
->Clear();
126 FlushDeviceSettings();
127 EXPECT_TRUE(manager_
.IsInitializationComplete(POLICY_DOMAIN_CHROME
));
129 manager_
.Connect(&local_state_
,
130 &device_management_service_
,
131 scoped_ptr
<CloudPolicyClient::StatusProvider
>());
134 EXPECT_TRUE(manager_
.policies().Equals(bundle
));
137 TEST_F(DeviceCloudPolicyManagerChromeOSTest
, EnrolledDevice
) {
139 EnterpriseInstallAttributes::LockResult result
;
140 install_attributes_
.LockDevice(PolicyBuilder::kFakeUsername
,
141 DEVICE_MODE_ENTERPRISE
,
142 PolicyBuilder::kFakeDeviceId
,
143 base::Bind(&CopyLockResult
, &loop
, &result
));
145 ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS
, result
);
147 FlushDeviceSettings();
148 EXPECT_EQ(CloudPolicyStore::STATUS_OK
, store_
->status());
149 EXPECT_TRUE(manager_
.IsInitializationComplete(POLICY_DOMAIN_CHROME
));
152 bundle
.Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()))
153 .Set(key::kDeviceMetricsReportingEnabled
,
154 POLICY_LEVEL_MANDATORY
,
155 POLICY_SCOPE_MACHINE
,
156 Value::CreateBooleanValue(false),
158 EXPECT_TRUE(manager_
.policies().Equals(bundle
));
160 manager_
.Connect(&local_state_
,
161 &device_management_service_
,
162 scoped_ptr
<CloudPolicyClient::StatusProvider
>());
163 EXPECT_TRUE(manager_
.policies().Equals(bundle
));
166 EXPECT_TRUE(manager_
.policies().Equals(bundle
));
168 EXPECT_EQ(manager_
.GetRobotAccountId(),
169 PolicyBuilder::kFakeServiceAccountIdentity
);
172 TEST_F(DeviceCloudPolicyManagerChromeOSTest
, ConsumerDevice
) {
173 FlushDeviceSettings();
174 EXPECT_EQ(CloudPolicyStore::STATUS_BAD_STATE
, store_
->status());
175 EXPECT_TRUE(manager_
.IsInitializationComplete(POLICY_DOMAIN_CHROME
));
178 EXPECT_TRUE(manager_
.policies().Equals(bundle
));
180 manager_
.Connect(&local_state_
,
181 &device_management_service_
,
182 scoped_ptr
<CloudPolicyClient::StatusProvider
>());
183 EXPECT_TRUE(manager_
.policies().Equals(bundle
));
186 EXPECT_TRUE(manager_
.policies().Equals(bundle
));
189 class DeviceCloudPolicyManagerChromeOSEnrollmentTest
190 : public DeviceCloudPolicyManagerChromeOSTest
{
192 void Done(EnrollmentStatus status
) {
198 DeviceCloudPolicyManagerChromeOSEnrollmentTest()
199 : is_auto_enrollment_(false),
200 register_status_(DM_STATUS_SUCCESS
),
201 policy_fetch_status_(DM_STATUS_SUCCESS
),
202 robot_auth_fetch_status_(DM_STATUS_SUCCESS
),
204 status_(EnrollmentStatus::ForStatus(EnrollmentStatus::STATUS_SUCCESS
)),
207 virtual void SetUp() OVERRIDE
{
208 DeviceCloudPolicyManagerChromeOSTest::SetUp();
211 device_policy_
.SetDefaultNewSigningKey();
212 device_policy_
.policy_data().set_timestamp(
213 (base::Time::NowFromSystemTime() -
214 base::Time::UnixEpoch()).InMilliseconds());
215 device_policy_
.Build();
217 register_response_
.mutable_register_response()->set_device_management_token(
218 PolicyBuilder::kFakeToken
);
219 policy_fetch_response_
.mutable_policy_response()->add_response()->CopyFrom(
220 device_policy_
.policy());
221 robot_auth_fetch_response_
.mutable_service_api_access_response()
222 ->set_auth_code("auth_code_for_test");
223 loaded_blob_
= device_policy_
.GetBlob();
225 // Initialize the manager.
226 FlushDeviceSettings();
227 EXPECT_EQ(CloudPolicyStore::STATUS_BAD_STATE
, store_
->status());
228 EXPECT_TRUE(manager_
.IsInitializationComplete(POLICY_DOMAIN_CHROME
));
231 EXPECT_TRUE(manager_
.policies().Equals(bundle
));
233 manager_
.Connect(&local_state_
,
234 &device_management_service_
,
235 scoped_ptr
<CloudPolicyClient::StatusProvider
>());
238 void ExpectFailedEnrollment(EnrollmentStatus::Status status
) {
239 EXPECT_EQ(status
, status_
.status());
240 EXPECT_FALSE(store_
->is_managed());
241 PolicyBundle empty_bundle
;
242 EXPECT_TRUE(manager_
.policies().Equals(empty_bundle
));
245 void ExpectSuccessfulEnrollment() {
246 EXPECT_EQ(EnrollmentStatus::STATUS_SUCCESS
, status_
.status());
247 EXPECT_EQ(DEVICE_MODE_ENTERPRISE
, install_attributes_
.GetMode());
248 EXPECT_TRUE(store_
->has_policy());
249 EXPECT_TRUE(store_
->is_managed());
250 ASSERT_TRUE(manager_
.core()->client());
251 EXPECT_TRUE(manager_
.core()->client()->is_registered());
254 bundle
.Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()))
255 .Set(key::kDeviceMetricsReportingEnabled
,
256 POLICY_LEVEL_MANDATORY
,
257 POLICY_SCOPE_MACHINE
,
258 Value::CreateBooleanValue(false),
260 EXPECT_TRUE(manager_
.policies().Equals(bundle
));
264 // Trigger enrollment.
265 MockDeviceManagementJob
* register_job
= NULL
;
266 EXPECT_CALL(device_management_service_
,
267 CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION
))
269 .WillOnce(device_management_service_
.CreateAsyncJob(®ister_job
));
270 EXPECT_CALL(device_management_service_
, StartJob(_
, _
, _
, _
, _
, _
, _
))
272 .WillOnce(DoAll(SaveArg
<5>(&client_id_
),
273 SaveArg
<6>(®ister_request_
)));
274 DeviceCloudPolicyManagerChromeOS::AllowedDeviceModes modes
;
275 modes
[DEVICE_MODE_ENTERPRISE
] = true;
276 manager_
.StartEnrollment(
277 "auth token", is_auto_enrollment_
, modes
,
278 base::Bind(&DeviceCloudPolicyManagerChromeOSEnrollmentTest::Done
,
279 base::Unretained(this)));
280 Mock::VerifyAndClearExpectations(&device_management_service_
);
285 // Process registration.
286 ASSERT_TRUE(register_job
);
287 MockDeviceManagementJob
* policy_fetch_job
= NULL
;
288 EXPECT_CALL(device_management_service_
,
289 CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH
))
291 .WillOnce(device_management_service_
.CreateAsyncJob(&policy_fetch_job
));
292 EXPECT_CALL(device_management_service_
, StartJob(_
, _
, _
, _
, _
, _
, _
))
294 register_job
->SendResponse(register_status_
, register_response_
);
295 Mock::VerifyAndClearExpectations(&device_management_service_
);
300 // Process policy fetch.
301 ASSERT_TRUE(policy_fetch_job
);
302 policy_fetch_job
->SendResponse(policy_fetch_status_
,
303 policy_fetch_response_
);
308 // Process verification.
309 MockDeviceManagementJob
* robot_auth_fetch_job
= NULL
;
310 EXPECT_CALL(device_management_service_
,
311 CreateJob(DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH
))
313 .WillOnce(device_management_service_
.CreateAsyncJob(
314 &robot_auth_fetch_job
));
315 EXPECT_CALL(device_management_service_
, StartJob(_
, _
, _
, _
, _
, _
, _
))
317 base::RunLoop().RunUntilIdle();
318 Mock::VerifyAndClearExpectations(&device_management_service_
);
323 // Process robot auth token fetch.
324 ASSERT_TRUE(robot_auth_fetch_job
);
325 robot_auth_fetch_job
->SendResponse(robot_auth_fetch_status_
,
326 robot_auth_fetch_response_
);
327 Mock::VerifyAndClearExpectations(&device_management_service_
);
332 // Process robot refresh token fetch if the auth code fetch succeeded.
333 // DeviceCloudPolicyManagerChromeOS holds an EnrollmentHandlerChromeOS which
334 // holds a GaiaOAuthClient that fetches the refresh token during enrollment.
335 // We return a successful OAuth response via a TestURLFetcher to trigger the
336 // happy path for these classes so that enrollment can continue.
337 if (robot_auth_fetch_status_
== DM_STATUS_SUCCESS
) {
338 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory_
.GetFetcherByID(
339 gaia::GaiaOAuthClient::kUrlFetcherId
);
340 ASSERT_TRUE(url_fetcher
);
341 url_fetcher
->SetMaxRetriesOn5xx(0);
342 url_fetcher
->set_status(net::URLRequestStatus());
343 url_fetcher
->set_response_code(url_fetcher_response_code_
);
344 url_fetcher
->SetResponseString(url_fetcher_response_string_
);
345 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
347 base::RunLoop().RunUntilIdle();
349 // Process policy store.
350 device_settings_test_helper_
.set_store_result(store_result_
);
351 device_settings_test_helper_
.FlushStore();
352 EXPECT_EQ(device_policy_
.GetBlob(),
353 device_settings_test_helper_
.policy_blob());
358 // Key installation, policy load and refresh token save.
359 device_settings_test_helper_
.set_policy_blob(loaded_blob_
);
360 owner_key_util_
->SetPublicKeyFromPrivateKey(
361 *device_policy_
.GetNewSigningKey());
362 ReloadDeviceSettings();
367 chromeos::DeviceOAuth2TokenService
* token_service
=
368 chromeos::DeviceOAuth2TokenServiceFactory::Get();
369 // Process robot refresh token store.
372 token_service
->GetRefreshToken(token_service
->GetRobotAccountId()));
375 bool is_auto_enrollment_
;
377 DeviceManagementStatus register_status_
;
378 em::DeviceManagementResponse register_response_
;
380 DeviceManagementStatus policy_fetch_status_
;
381 em::DeviceManagementResponse policy_fetch_response_
;
383 DeviceManagementStatus robot_auth_fetch_status_
;
384 em::DeviceManagementResponse robot_auth_fetch_response_
;
387 std::string loaded_blob_
;
389 em::DeviceManagementRequest register_request_
;
390 std::string client_id_
;
391 EnrollmentStatus status_
;
396 DISALLOW_COPY_AND_ASSIGN(DeviceCloudPolicyManagerChromeOSEnrollmentTest
);
399 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest
, Success
) {
401 ExpectSuccessfulEnrollment();
404 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest
, AutoEnrollment
) {
405 is_auto_enrollment_
= true;
407 ExpectSuccessfulEnrollment();
408 EXPECT_TRUE(register_request_
.register_request().auto_enrolled());
411 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest
, Reenrollment
) {
413 EnterpriseInstallAttributes::LockResult result
;
414 install_attributes_
.LockDevice(PolicyBuilder::kFakeUsername
,
415 DEVICE_MODE_ENTERPRISE
,
416 PolicyBuilder::kFakeDeviceId
,
417 base::Bind(&CopyLockResult
, &loop
, &result
));
419 ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS
, result
);
422 ExpectSuccessfulEnrollment();
423 EXPECT_TRUE(register_request_
.register_request().reregister());
424 EXPECT_EQ(PolicyBuilder::kFakeDeviceId
, client_id_
);
427 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest
, RegistrationFailed
) {
428 register_status_
= DM_STATUS_REQUEST_FAILED
;
430 ExpectFailedEnrollment(EnrollmentStatus::STATUS_REGISTRATION_FAILED
);
431 EXPECT_EQ(DM_STATUS_REQUEST_FAILED
, status_
.client_status());
434 // Policy server implementations are not required to support robot auth
435 // tokens, so the following 4 Robot* tests verify that enrollment succeeds
436 // even if the robot auth token fetch fails.
437 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest
,
438 RobotAuthCodeFetchFailed
) {
439 robot_auth_fetch_status_
= DM_STATUS_REQUEST_FAILED
;
441 ExpectSuccessfulEnrollment();
444 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest
,
445 RobotRefreshTokenFetchResponseCodeFailed
) {
446 url_fetcher_response_code_
= 400;
448 ExpectSuccessfulEnrollment();
451 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest
,
452 RobotRefreshTokenFetchResponseStringFailed
) {
453 url_fetcher_response_string_
= "invalid response json";
455 ExpectSuccessfulEnrollment();
458 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest
, RobotRefreshSaveFailed
) {
459 // Without a DeviceOAuth2TokenService, the refresh token can't be saved.
460 chromeos::DeviceOAuth2TokenServiceFactory::Shutdown();
462 ExpectSuccessfulEnrollment();
465 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest
, PolicyFetchFailed
) {
466 policy_fetch_status_
= DM_STATUS_REQUEST_FAILED
;
468 ExpectFailedEnrollment(EnrollmentStatus::STATUS_POLICY_FETCH_FAILED
);
469 EXPECT_EQ(DM_STATUS_REQUEST_FAILED
, status_
.client_status());
472 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest
, ValidationFailed
) {
473 device_policy_
.policy().set_policy_data_signature("bad");
474 policy_fetch_response_
.clear_policy_response();
475 policy_fetch_response_
.mutable_policy_response()->add_response()->CopyFrom(
476 device_policy_
.policy());
478 ExpectFailedEnrollment(EnrollmentStatus::STATUS_VALIDATION_FAILED
);
479 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_INITIAL_SIGNATURE
,
480 status_
.validation_status());
483 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest
, StoreError
) {
484 store_result_
= false;
486 ExpectFailedEnrollment(EnrollmentStatus::STATUS_STORE_ERROR
);
487 EXPECT_EQ(CloudPolicyStore::STATUS_STORE_ERROR
,
488 status_
.store_status());
491 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest
, LoadError
) {
492 loaded_blob_
.clear();
494 ExpectFailedEnrollment(EnrollmentStatus::STATUS_STORE_ERROR
);
495 EXPECT_EQ(CloudPolicyStore::STATUS_LOAD_ERROR
,
496 status_
.store_status());
500 } // namespace policy