device_cloud_policy_manager_chromeos_unittest.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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. 4 5#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" 6 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/cryptohome/mock_cryptohome_library.h" 30#include "chromeos/dbus/cryptohome_client_stub.h" 31#include "chromeos/dbus/dbus_client_implementation_type.h" 32#include "google_apis/gaia/gaia_oauth_client.h" 33#include "net/url_request/test_url_fetcher_factory.h" 34#include "net/url_request/url_request_test_util.h" 35#include "policy/policy_constants.h" 36#include "testing/gmock/include/gmock/gmock.h" 37#include "testing/gtest/include/gtest/gtest.h" 38 39using testing::AnyNumber; 40using testing::AtMost; 41using testing::DoAll; 42using testing::Mock; 43using testing::SaveArg; 44using testing::_; 45 46namespace em = enterprise_management; 47 48namespace policy { 49namespace { 50 51void CopyLockResult(base::RunLoop* loop, 52 EnterpriseInstallAttributes::LockResult* out, 53 EnterpriseInstallAttributes::LockResult result) { 54 *out = result; 55 loop->Quit(); 56} 57 58class DeviceCloudPolicyManagerChromeOSTest 59 : public chromeos::DeviceSettingsTestBase { 60 protected: 61 DeviceCloudPolicyManagerChromeOSTest() 62 : cryptohome_library_(chromeos::CryptohomeLibrary::GetTestImpl()), 63 stub_cryptohome_client_(new chromeos::CryptohomeClientStubImpl()), 64 install_attributes_(cryptohome_library_.get(), 65 stub_cryptohome_client_.get()), 66 store_(new DeviceCloudPolicyStoreChromeOS(&device_settings_service_, 67 &install_attributes_)), 68 manager_(make_scoped_ptr(store_), 69 loop_.message_loop_proxy(), 70 &install_attributes_) { 71 stub_cryptohome_client_->Init(NULL /* no dbus::Bus */); 72 } 73 74 virtual void SetUp() OVERRIDE { 75 DeviceSettingsTestBase::SetUp(); 76 chrome::RegisterLocalState(local_state_.registry()); 77 manager_.Init(); 78 79 // DeviceOAuth2TokenService uses the system request context to fetch 80 // OAuth tokens, then writes the token to local state, encrypting it 81 // first with methods in CryptohomeLibrary. 82 request_context_getter_ = new net::TestURLRequestContextGetter( 83 loop_.message_loop_proxy()); 84 TestingBrowserProcess::GetGlobal()->SetSystemRequestContext( 85 request_context_getter_.get()); 86 TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_); 87 chromeos::DeviceOAuth2TokenServiceFactory::Initialize(); 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\"}"; 93 } 94 95 virtual void TearDown() OVERRIDE { 96 manager_.Shutdown(); 97 DeviceSettingsTestBase::TearDown(); 98 99 chromeos::DeviceOAuth2TokenServiceFactory::Shutdown(); 100 chromeos::CryptohomeLibrary::SetForTest(NULL); 101 TestingBrowserProcess::GetGlobal()->SetLocalState(NULL); 102 } 103 104 scoped_ptr<chromeos::CryptohomeLibrary> cryptohome_library_; 105 scoped_ptr<chromeos::CryptohomeClientStubImpl> stub_cryptohome_client_; 106 EnterpriseInstallAttributes install_attributes_; 107 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_; 116 117 DeviceCloudPolicyStoreChromeOS* store_; 118 DeviceCloudPolicyManagerChromeOS manager_; 119 120 private: 121 DISALLOW_COPY_AND_ASSIGN(DeviceCloudPolicyManagerChromeOSTest); 122}; 123 124TEST_F(DeviceCloudPolicyManagerChromeOSTest, FreshDevice) { 125 owner_key_util_->Clear(); 126 FlushDeviceSettings(); 127 EXPECT_TRUE(manager_.IsInitializationComplete(POLICY_DOMAIN_CHROME)); 128 129 manager_.Connect(&local_state_, 130 &device_management_service_, 131 scoped_ptr<CloudPolicyClient::StatusProvider>()); 132 133 PolicyBundle bundle; 134 EXPECT_TRUE(manager_.policies().Equals(bundle)); 135} 136 137TEST_F(DeviceCloudPolicyManagerChromeOSTest, EnrolledDevice) { 138 base::RunLoop loop; 139 EnterpriseInstallAttributes::LockResult result; 140 install_attributes_.LockDevice(PolicyBuilder::kFakeUsername, 141 DEVICE_MODE_ENTERPRISE, 142 PolicyBuilder::kFakeDeviceId, 143 base::Bind(&CopyLockResult, &loop, &result)); 144 loop.Run(); 145 ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS, result); 146 147 FlushDeviceSettings(); 148 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 149 EXPECT_TRUE(manager_.IsInitializationComplete(POLICY_DOMAIN_CHROME)); 150 151 PolicyBundle bundle; 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), 157 NULL); 158 EXPECT_TRUE(manager_.policies().Equals(bundle)); 159 160 manager_.Connect(&local_state_, 161 &device_management_service_, 162 scoped_ptr<CloudPolicyClient::StatusProvider>()); 163 EXPECT_TRUE(manager_.policies().Equals(bundle)); 164 165 manager_.Shutdown(); 166 EXPECT_TRUE(manager_.policies().Equals(bundle)); 167 168 EXPECT_EQ(manager_.GetRobotAccountId(), 169 PolicyBuilder::kFakeServiceAccountIdentity); 170} 171 172TEST_F(DeviceCloudPolicyManagerChromeOSTest, ConsumerDevice) { 173 FlushDeviceSettings(); 174 EXPECT_EQ(CloudPolicyStore::STATUS_BAD_STATE, store_->status()); 175 EXPECT_TRUE(manager_.IsInitializationComplete(POLICY_DOMAIN_CHROME)); 176 177 PolicyBundle bundle; 178 EXPECT_TRUE(manager_.policies().Equals(bundle)); 179 180 manager_.Connect(&local_state_, 181 &device_management_service_, 182 scoped_ptr<CloudPolicyClient::StatusProvider>()); 183 EXPECT_TRUE(manager_.policies().Equals(bundle)); 184 185 manager_.Shutdown(); 186 EXPECT_TRUE(manager_.policies().Equals(bundle)); 187} 188 189class DeviceCloudPolicyManagerChromeOSEnrollmentTest 190 : public DeviceCloudPolicyManagerChromeOSTest { 191 public: 192 void Done(EnrollmentStatus status) { 193 status_ = status; 194 done_ = true; 195 } 196 197 protected: 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), 203 store_result_(true), 204 status_(EnrollmentStatus::ForStatus(EnrollmentStatus::STATUS_SUCCESS)), 205 done_(false) {} 206 207 virtual void SetUp() OVERRIDE { 208 DeviceCloudPolicyManagerChromeOSTest::SetUp(); 209 210 // Set up test data. 211 device_policy_.SetDefaultNewSigningKey(); 212 device_policy_.policy_data().set_timestamp( 213 (base::Time::NowFromSystemTime() - 214 base::Time::UnixEpoch()).InMilliseconds()); 215 device_policy_.Build(); 216 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(); 224 225 // Initialize the manager. 226 FlushDeviceSettings(); 227 EXPECT_EQ(CloudPolicyStore::STATUS_BAD_STATE, store_->status()); 228 EXPECT_TRUE(manager_.IsInitializationComplete(POLICY_DOMAIN_CHROME)); 229 230 PolicyBundle bundle; 231 EXPECT_TRUE(manager_.policies().Equals(bundle)); 232 233 manager_.Connect(&local_state_, 234 &device_management_service_, 235 scoped_ptr<CloudPolicyClient::StatusProvider>()); 236 } 237 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)); 243 } 244 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()); 252 253 PolicyBundle bundle; 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), 259 NULL); 260 EXPECT_TRUE(manager_.policies().Equals(bundle)); 261 } 262 263 void RunTest() { 264 // Trigger enrollment. 265 MockDeviceManagementJob* register_job = NULL; 266 EXPECT_CALL(device_management_service_, 267 CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION)) 268 .Times(AtMost(1)) 269 .WillOnce(device_management_service_.CreateAsyncJob(®ister_job)); 270 EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _)) 271 .Times(AtMost(1)) 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_); 281 282 if (done_) 283 return; 284 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)) 290 .Times(AtMost(1)) 291 .WillOnce(device_management_service_.CreateAsyncJob(&policy_fetch_job)); 292 EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _)) 293 .Times(AtMost(1)); 294 register_job->SendResponse(register_status_, register_response_); 295 Mock::VerifyAndClearExpectations(&device_management_service_); 296 297 if (done_) 298 return; 299 300 // Process policy fetch. 301 ASSERT_TRUE(policy_fetch_job); 302 policy_fetch_job->SendResponse(policy_fetch_status_, 303 policy_fetch_response_); 304 305 if (done_) 306 return; 307 308 // Process verification. 309 MockDeviceManagementJob* robot_auth_fetch_job = NULL; 310 EXPECT_CALL(device_management_service_, 311 CreateJob(DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH)) 312 .Times(AtMost(1)) 313 .WillOnce(device_management_service_.CreateAsyncJob( 314 &robot_auth_fetch_job)); 315 EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _)) 316 .Times(AtMost(1)); 317 base::RunLoop().RunUntilIdle(); 318 Mock::VerifyAndClearExpectations(&device_management_service_); 319 320 if (done_) 321 return; 322 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_); 328 329 if (done_) 330 return; 331 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); 346 } 347 base::RunLoop().RunUntilIdle(); 348 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()); 354 355 if (done_) 356 return; 357 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(); 363 364 if (done_) 365 return; 366 367 // Process robot refresh token store. 368 EXPECT_EQ( 369 "refreshToken4Test", 370 chromeos::DeviceOAuth2TokenServiceFactory::Get()->GetRefreshToken()); 371 } 372 373 bool is_auto_enrollment_; 374 375 DeviceManagementStatus register_status_; 376 em::DeviceManagementResponse register_response_; 377 378 DeviceManagementStatus policy_fetch_status_; 379 em::DeviceManagementResponse policy_fetch_response_; 380 381 DeviceManagementStatus robot_auth_fetch_status_; 382 em::DeviceManagementResponse robot_auth_fetch_response_; 383 384 bool store_result_; 385 std::string loaded_blob_; 386 387 em::DeviceManagementRequest register_request_; 388 std::string client_id_; 389 EnrollmentStatus status_; 390 391 bool done_; 392 393 private: 394 DISALLOW_COPY_AND_ASSIGN(DeviceCloudPolicyManagerChromeOSEnrollmentTest); 395}; 396 397TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, Success) { 398 RunTest(); 399 ExpectSuccessfulEnrollment(); 400} 401 402TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, AutoEnrollment) { 403 is_auto_enrollment_ = true; 404 RunTest(); 405 ExpectSuccessfulEnrollment(); 406 EXPECT_TRUE(register_request_.register_request().auto_enrolled()); 407} 408 409TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, Reenrollment) { 410 base::RunLoop loop; 411 EnterpriseInstallAttributes::LockResult result; 412 install_attributes_.LockDevice(PolicyBuilder::kFakeUsername, 413 DEVICE_MODE_ENTERPRISE, 414 PolicyBuilder::kFakeDeviceId, 415 base::Bind(&CopyLockResult, &loop, &result)); 416 loop.Run(); 417 ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS, result); 418 419 RunTest(); 420 ExpectSuccessfulEnrollment(); 421 EXPECT_TRUE(register_request_.register_request().reregister()); 422 EXPECT_EQ(PolicyBuilder::kFakeDeviceId, client_id_); 423} 424 425TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, RegistrationFailed) { 426 register_status_ = DM_STATUS_REQUEST_FAILED; 427 RunTest(); 428 ExpectFailedEnrollment(EnrollmentStatus::STATUS_REGISTRATION_FAILED); 429 EXPECT_EQ(DM_STATUS_REQUEST_FAILED, status_.client_status()); 430} 431 432// Policy server implementations are not required to support robot auth 433// tokens, so the following 4 Robot* tests verify that enrollment succeeds 434// even if the robot auth token fetch fails. 435TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, 436 RobotAuthCodeFetchFailed) { 437 robot_auth_fetch_status_ = DM_STATUS_REQUEST_FAILED; 438 RunTest(); 439 ExpectSuccessfulEnrollment(); 440} 441 442TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, 443 RobotRefreshTokenFetchResponseCodeFailed) { 444 url_fetcher_response_code_ = 400; 445 RunTest(); 446 ExpectSuccessfulEnrollment(); 447} 448 449TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, 450 RobotRefreshTokenFetchResponseStringFailed) { 451 url_fetcher_response_string_ = "invalid response json"; 452 RunTest(); 453 ExpectSuccessfulEnrollment(); 454} 455 456TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, RobotRefreshSaveFailed) { 457 // Without a DeviceOAuth2TokenService, the refresh token can't be saved. 458 chromeos::DeviceOAuth2TokenServiceFactory::Shutdown(); 459 RunTest(); 460 ExpectSuccessfulEnrollment(); 461} 462 463TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, PolicyFetchFailed) { 464 policy_fetch_status_ = DM_STATUS_REQUEST_FAILED; 465 RunTest(); 466 ExpectFailedEnrollment(EnrollmentStatus::STATUS_POLICY_FETCH_FAILED); 467 EXPECT_EQ(DM_STATUS_REQUEST_FAILED, status_.client_status()); 468} 469 470TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, ValidationFailed) { 471 device_policy_.policy().set_policy_data_signature("bad"); 472 policy_fetch_response_.clear_policy_response(); 473 policy_fetch_response_.mutable_policy_response()->add_response()->CopyFrom( 474 device_policy_.policy()); 475 RunTest(); 476 ExpectFailedEnrollment(EnrollmentStatus::STATUS_VALIDATION_FAILED); 477 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_INITIAL_SIGNATURE, 478 status_.validation_status()); 479} 480 481TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, StoreError) { 482 store_result_ = false; 483 RunTest(); 484 ExpectFailedEnrollment(EnrollmentStatus::STATUS_STORE_ERROR); 485 EXPECT_EQ(CloudPolicyStore::STATUS_STORE_ERROR, 486 status_.store_status()); 487} 488 489TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, LoadError) { 490 loaded_blob_.clear(); 491 RunTest(); 492 ExpectFailedEnrollment(EnrollmentStatus::STATUS_STORE_ERROR); 493 EXPECT_EQ(CloudPolicyStore::STATUS_LOAD_ERROR, 494 status_.store_status()); 495} 496 497} // namespace 498} // namespace policy 499