consumer_management_service_unittest.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
1// Copyright 2014 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/consumer_management_service.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/callback.h" 10#include "base/prefs/pref_registry_simple.h" 11#include "base/prefs/testing_pref_service.h" 12#include "base/run_loop.h" 13#include "chrome/browser/browser_process.h" 14#include "chrome/browser/browser_process_platform_part.h" 15#include "chrome/browser/chrome_notification_types.h" 16#include "chrome/browser/chromeos/login/users/mock_user_manager.h" 17#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" 18#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" 19#include "chrome/browser/chromeos/policy/device_cloud_policy_initializer.h" 20#include "chrome/browser/chromeos/policy/enrollment_status_chromeos.h" 21#include "chrome/browser/chromeos/policy/fake_device_cloud_policy_initializer.h" 22#include "chrome/browser/profiles/profile.h" 23#include "chrome/browser/signin/fake_profile_oauth2_token_service.h" 24#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h" 25#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 26#include "chrome/browser/signin/signin_manager_factory.h" 27#include "chrome/common/pref_names.h" 28#include "chrome/test/base/scoped_testing_local_state.h" 29#include "chrome/test/base/testing_browser_process.h" 30#include "chrome/test/base/testing_profile.h" 31#include "chromeos/dbus/cryptohome/rpc.pb.h" 32#include "chromeos/dbus/cryptohome_client.h" 33#include "chromeos/dbus/mock_cryptohome_client.h" 34#include "components/signin/core/browser/profile_oauth2_token_service.h" 35#include "components/signin/core/browser/signin_manager_base.h" 36#include "content/public/browser/notification_details.h" 37#include "content/public/browser/notification_source.h" 38#include "content/public/test/test_browser_thread_bundle.h" 39#include "google_apis/gaia/google_service_auth_error.h" 40#include "testing/gmock/include/gmock/gmock.h" 41#include "testing/gtest/include/gtest/gtest.h" 42 43using testing::Invoke; 44using testing::NiceMock; 45using testing::Return; 46using testing::_; 47 48namespace { 49const char* kAttributeOwnerId = "consumer_management.owner_id"; 50const char* kTestOwner = "test@chromium.org.test"; 51} 52 53namespace policy { 54 55class ConsumerManagementServiceTest : public testing::Test { 56 public: 57 ConsumerManagementServiceTest() 58 : testing_local_state_(TestingBrowserProcess::GetGlobal()), 59 cryptohome_result_(false), 60 set_owner_status_(false) { 61 ON_CALL(mock_cryptohome_client_, GetBootAttribute(_, _)) 62 .WillByDefault( 63 Invoke(this, &ConsumerManagementServiceTest::MockGetBootAttribute)); 64 ON_CALL(mock_cryptohome_client_, SetBootAttribute(_, _)) 65 .WillByDefault( 66 Invoke(this, &ConsumerManagementServiceTest::MockSetBootAttribute)); 67 ON_CALL(mock_cryptohome_client_, FlushAndSignBootAttributes(_, _)) 68 .WillByDefault( 69 Invoke(this, 70 &ConsumerManagementServiceTest:: 71 MockFlushAndSignBootAttributes)); 72 } 73 74 virtual void SetUp() OVERRIDE { 75 service_.reset(new ConsumerManagementService(&mock_cryptohome_client_)); 76 } 77 78 virtual void TearDown() OVERRIDE { 79 service_.reset(); 80 } 81 82 ConsumerManagementService::ConsumerEnrollmentState GetEnrollmentState() { 83 return static_cast<ConsumerManagementService::ConsumerEnrollmentState>( 84 testing_local_state_.Get()->GetInteger( 85 prefs::kConsumerManagementEnrollmentState)); 86 } 87 88 void SetEnrollmentState( 89 ConsumerManagementService::ConsumerEnrollmentState state) { 90 testing_local_state_.Get()->SetInteger( 91 prefs::kConsumerManagementEnrollmentState, state); 92 } 93 94 void MockGetBootAttribute( 95 const cryptohome::GetBootAttributeRequest& request, 96 const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) { 97 get_boot_attribute_request_ = request; 98 callback.Run(cryptohome_status_, cryptohome_result_, cryptohome_reply_); 99 } 100 101 void MockSetBootAttribute( 102 const cryptohome::SetBootAttributeRequest& request, 103 const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) { 104 set_boot_attribute_request_ = request; 105 callback.Run(cryptohome_status_, cryptohome_result_, cryptohome_reply_); 106 } 107 108 void MockFlushAndSignBootAttributes( 109 const cryptohome::FlushAndSignBootAttributesRequest& request, 110 const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) { 111 callback.Run(cryptohome_status_, cryptohome_result_, cryptohome_reply_); 112 } 113 114 void OnGetOwnerDone(const std::string& owner) { 115 owner_ = owner; 116 } 117 118 void OnSetOwnerDone(bool status) { 119 set_owner_status_ = status; 120 } 121 122 ScopedTestingLocalState testing_local_state_; 123 NiceMock<chromeos::MockCryptohomeClient> mock_cryptohome_client_; 124 scoped_ptr<ConsumerManagementService> service_; 125 126 chromeos::DBusMethodCallStatus cryptohome_status_; 127 bool cryptohome_result_; 128 cryptohome::BaseReply cryptohome_reply_; 129 cryptohome::GetBootAttributeRequest get_boot_attribute_request_; 130 cryptohome::SetBootAttributeRequest set_boot_attribute_request_; 131 132 std::string owner_; 133 bool set_owner_status_; 134}; 135 136TEST_F(ConsumerManagementServiceTest, CanGetEnrollmentState) { 137 EXPECT_EQ(ConsumerManagementService::ENROLLMENT_NONE, 138 service_->GetEnrollmentState()); 139 140 SetEnrollmentState(ConsumerManagementService::ENROLLMENT_REQUESTED); 141 142 EXPECT_EQ(ConsumerManagementService::ENROLLMENT_REQUESTED, 143 service_->GetEnrollmentState()); 144} 145 146TEST_F(ConsumerManagementServiceTest, CanSetEnrollmentState) { 147 EXPECT_EQ(ConsumerManagementService::ENROLLMENT_NONE, GetEnrollmentState()); 148 149 service_->SetEnrollmentState(ConsumerManagementService::ENROLLMENT_REQUESTED); 150 151 EXPECT_EQ(ConsumerManagementService::ENROLLMENT_REQUESTED, 152 GetEnrollmentState()); 153} 154 155TEST_F(ConsumerManagementServiceTest, CanGetOwner) { 156 cryptohome_status_ = chromeos::DBUS_METHOD_CALL_SUCCESS; 157 cryptohome_result_ = true; 158 cryptohome_reply_.MutableExtension(cryptohome::GetBootAttributeReply::reply)-> 159 set_value(kTestOwner); 160 161 service_->GetOwner(base::Bind(&ConsumerManagementServiceTest::OnGetOwnerDone, 162 base::Unretained(this))); 163 164 EXPECT_EQ(kAttributeOwnerId, get_boot_attribute_request_.name()); 165 EXPECT_EQ(kTestOwner, owner_); 166} 167 168TEST_F(ConsumerManagementServiceTest, GetOwnerReturnsAnEmptyStringWhenItFails) { 169 cryptohome_status_ = chromeos::DBUS_METHOD_CALL_FAILURE; 170 cryptohome_result_ = false; 171 cryptohome_reply_.MutableExtension(cryptohome::GetBootAttributeReply::reply)-> 172 set_value(kTestOwner); 173 174 service_->GetOwner(base::Bind(&ConsumerManagementServiceTest::OnGetOwnerDone, 175 base::Unretained(this))); 176 177 EXPECT_EQ("", owner_); 178} 179 180TEST_F(ConsumerManagementServiceTest, CanSetOwner) { 181 cryptohome_status_ = chromeos::DBUS_METHOD_CALL_SUCCESS; 182 cryptohome_result_ = true; 183 184 service_->SetOwner(kTestOwner, 185 base::Bind(&ConsumerManagementServiceTest::OnSetOwnerDone, 186 base::Unretained(this))); 187 188 EXPECT_EQ(kAttributeOwnerId, set_boot_attribute_request_.name()); 189 EXPECT_EQ(kTestOwner, set_boot_attribute_request_.value()); 190 EXPECT_TRUE(set_owner_status_); 191} 192 193TEST_F(ConsumerManagementServiceTest, SetOwnerReturnsFalseWhenItFails) { 194 cryptohome_status_ = chromeos::DBUS_METHOD_CALL_FAILURE; 195 cryptohome_result_ = false; 196 197 service_->SetOwner(kTestOwner, 198 base::Bind(&ConsumerManagementServiceTest::OnSetOwnerDone, 199 base::Unretained(this))); 200 201 EXPECT_FALSE(set_owner_status_); 202} 203 204class ConsumerManagementServiceEnrollmentTest 205 : public ConsumerManagementServiceTest { 206 public: 207 ConsumerManagementServiceEnrollmentTest() 208 : mock_user_manager_(new NiceMock<chromeos::MockUserManager>()), 209 scoped_user_manager_enabler_(mock_user_manager_), 210 fake_initializer_(new FakeDeviceCloudPolicyInitializer()), 211 enrollment_status_(EnrollmentStatus::ForStatus( 212 EnrollmentStatus::STATUS_SUCCESS)){ 213 // Set up MockUserManager. The first user will be the owner. 214 mock_user_manager_->AddUser(kTestOwner); 215 216 // Return false for IsCurrentUserOwner() so that the enrollment state is not 217 // reset. 218 ON_CALL(*mock_user_manager_, IsCurrentUserOwner()) 219 .WillByDefault(Return(false)); 220 221 // Create test profile and set up FakeProfileOAuth2TokenService. 222 TestingProfile::Builder builder; 223 builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(), 224 &BuildAutoIssuingFakeProfileOAuth2TokenService); 225 testing_owner_profile_ = builder.Build(); 226 testing_owner_profile_->set_profile_name(kTestOwner); 227 228 // Set up the authenticated user name and ID. 229 SigninManagerFactory::GetForProfile(testing_owner_profile_.get())-> 230 SetAuthenticatedUsername(kTestOwner); 231 232 // Issue a fake refresh token. 233 GetFakeProfileOAuth2TokenService()-> 234 IssueRefreshTokenForUser(kTestOwner, "fake_token"); 235 236 // Inject FakeDeviceCloudPolicyInitializer. 237 BrowserPolicyConnectorChromeOS* connector = 238 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 239 connector->SetDeviceCloudPolicyInitializerForTesting( 240 scoped_ptr<DeviceCloudPolicyInitializer>(fake_initializer_)); 241 242 // The service should continue the enrollment process if the state is 243 // ENROLLMENT_OWNER_STORED. 244 SetEnrollmentState(ConsumerManagementService::ENROLLMENT_OWNER_STORED); 245 } 246 247 FakeProfileOAuth2TokenService* GetFakeProfileOAuth2TokenService() { 248 return static_cast<FakeProfileOAuth2TokenService*>( 249 ProfileOAuth2TokenServiceFactory::GetForProfile( 250 testing_owner_profile_.get())); 251 } 252 253 void RunEnrollmentTest() { 254 // Send the profile prepared notification to continue the enrollment. 255 service_->Observe(chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, 256 content::Source<void>(NULL), // Not used. 257 content::Details<Profile>(testing_owner_profile_.get())); 258 base::RunLoop().RunUntilIdle(); 259 } 260 261 content::TestBrowserThreadBundle thread_bundle_; 262 263 NiceMock<chromeos::MockUserManager>* mock_user_manager_; 264 chromeos::ScopedUserManagerEnabler scoped_user_manager_enabler_; 265 scoped_ptr<TestingProfile> testing_owner_profile_; 266 FakeDeviceCloudPolicyInitializer* fake_initializer_; 267 EnrollmentStatus enrollment_status_; 268}; 269 270TEST_F(ConsumerManagementServiceEnrollmentTest, EnrollsSuccessfully) { 271 EXPECT_FALSE(fake_initializer_->was_start_enrollment_called()); 272 273 RunEnrollmentTest(); 274 275 EXPECT_TRUE(fake_initializer_->was_start_enrollment_called()); 276 EXPECT_EQ(ConsumerManagementService::ENROLLMENT_SUCCESS, 277 GetEnrollmentState()); 278} 279 280TEST_F(ConsumerManagementServiceEnrollmentTest, 281 EnrollmentStateIsResetIfCurrentUserIsOwner) { 282 EXPECT_EQ(ConsumerManagementService::ENROLLMENT_OWNER_STORED, 283 GetEnrollmentState()); 284 285 EXPECT_CALL(*mock_user_manager_, IsCurrentUserOwner()) 286 .WillOnce(Return(true)); 287 288 RunEnrollmentTest(); 289 290 EXPECT_EQ(ConsumerManagementService::ENROLLMENT_NONE, GetEnrollmentState()); 291} 292 293TEST_F(ConsumerManagementServiceEnrollmentTest, FailsToGetAccessToken) { 294 // Disable auto-posting so that RunEnrollmentTest() should stop and wait for 295 // the access token to be available. 296 GetFakeProfileOAuth2TokenService()-> 297 set_auto_post_fetch_response_on_message_loop(false); 298 299 RunEnrollmentTest(); 300 301 // The service should have a pending token request. 302 OAuth2TokenService::Request* token_request = 303 service_->GetTokenRequestForTesting(); 304 EXPECT_TRUE(token_request); 305 306 // Tell the service that the access token is not available because of some 307 // backend issue. 308 service_->OnGetTokenFailure( 309 token_request, 310 GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_ERROR)); 311 312 EXPECT_FALSE(fake_initializer_->was_start_enrollment_called()); 313 EXPECT_EQ(ConsumerManagementService::ENROLLMENT_GET_TOKEN_FAILED, 314 GetEnrollmentState()); 315} 316 317TEST_F(ConsumerManagementServiceEnrollmentTest, FailsToRegister) { 318 EXPECT_FALSE(fake_initializer_->was_start_enrollment_called()); 319 fake_initializer_->set_enrollment_status(EnrollmentStatus::ForStatus( 320 EnrollmentStatus::STATUS_REGISTRATION_FAILED)); 321 322 RunEnrollmentTest(); 323 324 EXPECT_TRUE(fake_initializer_->was_start_enrollment_called()); 325 EXPECT_EQ(ConsumerManagementService::ENROLLMENT_DM_SERVER_FAILED, 326 GetEnrollmentState()); 327} 328 329TEST_F(ConsumerManagementServiceEnrollmentTest, ShowsDesktopNotificationOnly) { 330 SetEnrollmentState(ConsumerManagementService::ENROLLMENT_CANCELED); 331 332 RunEnrollmentTest(); 333 334 // TODO(davidyu): Check that the desktop notification was shown. 335 336 EXPECT_FALSE(fake_initializer_->was_start_enrollment_called()); 337 EXPECT_EQ(ConsumerManagementService::ENROLLMENT_NONE, GetEnrollmentState()); 338} 339 340} // namespace policy 341