Home | History | Annotate | Download | only in policy
      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/pref_service.h"
     12 #include "base/prefs/testing_pref_service.h"
     13 #include "base/run_loop.h"
     14 #include "chrome/browser/browser_process.h"
     15 #include "chrome/browser/browser_process_platform_part.h"
     16 #include "chrome/browser/chrome_notification_types.h"
     17 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
     18 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
     19 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
     20 #include "chrome/browser/chromeos/policy/device_cloud_policy_initializer.h"
     21 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
     22 #include "chrome/browser/chromeos/policy/enrollment_status_chromeos.h"
     23 #include "chrome/browser/chromeos/policy/fake_device_cloud_policy_initializer.h"
     24 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
     25 #include "chrome/browser/notifications/notification_ui_manager.h"
     26 #include "chrome/browser/profiles/profile.h"
     27 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
     28 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
     29 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
     30 #include "chrome/browser/signin/signin_manager_factory.h"
     31 #include "chrome/common/pref_names.h"
     32 #include "chrome/test/base/browser_with_test_window_test.h"
     33 #include "chrome/test/base/scoped_testing_local_state.h"
     34 #include "chrome/test/base/testing_browser_process.h"
     35 #include "chrome/test/base/testing_profile.h"
     36 #include "chrome/test/base/testing_profile_manager.h"
     37 #include "chromeos/dbus/cryptohome/rpc.pb.h"
     38 #include "chromeos/dbus/cryptohome_client.h"
     39 #include "chromeos/dbus/mock_cryptohome_client.h"
     40 #include "components/signin/core/browser/profile_oauth2_token_service.h"
     41 #include "components/signin/core/browser/signin_manager_base.h"
     42 #include "content/public/browser/notification_details.h"
     43 #include "content/public/browser/notification_source.h"
     44 #include "google_apis/gaia/google_service_auth_error.h"
     45 #include "policy/proto/device_management_backend.pb.h"
     46 #include "testing/gmock/include/gmock/gmock.h"
     47 #include "testing/gtest/include/gtest/gtest.h"
     48 
     49 using testing::Invoke;
     50 using testing::NiceMock;
     51 using testing::Return;
     52 using testing::_;
     53 
     54 namespace em = enterprise_management;
     55 
     56 namespace {
     57 const char* kAttributeOwnerId = "consumer_management.owner_id";
     58 const char* kTestOwner = "test (at) chromium.org.test";
     59 }
     60 
     61 namespace policy {
     62 
     63 class ConsumerManagementServiceTest : public BrowserWithTestWindowTest {
     64  public:
     65   ConsumerManagementServiceTest()
     66       : cryptohome_result_(false),
     67         set_owner_status_(false) {
     68     ON_CALL(mock_cryptohome_client_, GetBootAttribute(_, _))
     69         .WillByDefault(
     70             Invoke(this, &ConsumerManagementServiceTest::MockGetBootAttribute));
     71     ON_CALL(mock_cryptohome_client_, SetBootAttribute(_, _))
     72         .WillByDefault(
     73             Invoke(this, &ConsumerManagementServiceTest::MockSetBootAttribute));
     74     ON_CALL(mock_cryptohome_client_, FlushAndSignBootAttributes(_, _))
     75         .WillByDefault(
     76             Invoke(this,
     77                    &ConsumerManagementServiceTest::
     78                        MockFlushAndSignBootAttributes));
     79   }
     80 
     81   virtual void SetUp() OVERRIDE {
     82     BrowserWithTestWindowTest::SetUp();
     83 
     84     testing_profile_manager_.reset(new TestingProfileManager(
     85         TestingBrowserProcess::GetGlobal()));
     86     ASSERT_TRUE(testing_profile_manager_->SetUp());
     87 
     88     service_.reset(new ConsumerManagementService(&mock_cryptohome_client_,
     89                                                  NULL));
     90   }
     91 
     92   virtual void TearDown() OVERRIDE {
     93     testing_profile_manager_.reset();
     94 
     95     service_.reset();
     96 
     97     BrowserWithTestWindowTest::TearDown();
     98   }
     99 
    100   ConsumerManagementService::EnrollmentStage GetEnrollmentStage() {
    101     return static_cast<ConsumerManagementService::EnrollmentStage>(
    102         g_browser_process->local_state()->GetInteger(
    103             prefs::kConsumerManagementEnrollmentStage));
    104   }
    105 
    106   void SetEnrollmentStage(ConsumerManagementService::EnrollmentStage stage) {
    107     g_browser_process->local_state()->SetInteger(
    108         prefs::kConsumerManagementEnrollmentStage, stage);
    109   }
    110 
    111   void MockGetBootAttribute(
    112       const cryptohome::GetBootAttributeRequest& request,
    113       const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) {
    114     get_boot_attribute_request_ = request;
    115     callback.Run(cryptohome_status_, cryptohome_result_, cryptohome_reply_);
    116   }
    117 
    118   void MockSetBootAttribute(
    119       const cryptohome::SetBootAttributeRequest& request,
    120       const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) {
    121     set_boot_attribute_request_ = request;
    122     callback.Run(cryptohome_status_, cryptohome_result_, cryptohome_reply_);
    123   }
    124 
    125   void MockFlushAndSignBootAttributes(
    126       const cryptohome::FlushAndSignBootAttributesRequest& request,
    127       const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) {
    128     callback.Run(cryptohome_status_, cryptohome_result_, cryptohome_reply_);
    129   }
    130 
    131   void OnGetOwnerDone(const std::string& owner) {
    132     owner_ = owner;
    133   }
    134 
    135   void OnSetOwnerDone(bool status) {
    136     set_owner_status_ = status;
    137   }
    138 
    139   // Variables for building the service.
    140   NiceMock<chromeos::MockCryptohomeClient> mock_cryptohome_client_;
    141   scoped_ptr<ConsumerManagementService> service_;
    142 
    143   scoped_ptr<TestingProfileManager> testing_profile_manager_;
    144 
    145   // Variables for setting the return value or catching the arguments of mock
    146   // functions.
    147   chromeos::DBusMethodCallStatus cryptohome_status_;
    148   bool cryptohome_result_;
    149   cryptohome::BaseReply cryptohome_reply_;
    150   cryptohome::GetBootAttributeRequest get_boot_attribute_request_;
    151   cryptohome::SetBootAttributeRequest set_boot_attribute_request_;
    152   std::string owner_;
    153   bool set_owner_status_;
    154 };
    155 
    156 TEST_F(ConsumerManagementServiceTest, CanGetEnrollmentStage) {
    157   EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_NONE,
    158             service_->GetEnrollmentStage());
    159 
    160   SetEnrollmentStage(ConsumerManagementService::ENROLLMENT_STAGE_REQUESTED);
    161 
    162   EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_REQUESTED,
    163             service_->GetEnrollmentStage());
    164 }
    165 
    166 TEST_F(ConsumerManagementServiceTest, CanSetEnrollmentStage) {
    167   EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_NONE,
    168             GetEnrollmentStage());
    169 
    170   service_->SetEnrollmentStage(
    171       ConsumerManagementService::ENROLLMENT_STAGE_REQUESTED);
    172 
    173   EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_REQUESTED,
    174             GetEnrollmentStage());
    175 }
    176 
    177 TEST_F(ConsumerManagementServiceTest, CanGetOwner) {
    178   cryptohome_status_ = chromeos::DBUS_METHOD_CALL_SUCCESS;
    179   cryptohome_result_ = true;
    180   cryptohome_reply_.MutableExtension(cryptohome::GetBootAttributeReply::reply)->
    181       set_value(kTestOwner);
    182 
    183   service_->GetOwner(base::Bind(&ConsumerManagementServiceTest::OnGetOwnerDone,
    184                                 base::Unretained(this)));
    185 
    186   EXPECT_EQ(kAttributeOwnerId, get_boot_attribute_request_.name());
    187   EXPECT_EQ(kTestOwner, owner_);
    188 }
    189 
    190 TEST_F(ConsumerManagementServiceTest, GetOwnerReturnsAnEmptyStringWhenItFails) {
    191   cryptohome_status_ = chromeos::DBUS_METHOD_CALL_FAILURE;
    192   cryptohome_result_ = false;
    193   cryptohome_reply_.MutableExtension(cryptohome::GetBootAttributeReply::reply)->
    194       set_value(kTestOwner);
    195 
    196   service_->GetOwner(base::Bind(&ConsumerManagementServiceTest::OnGetOwnerDone,
    197                                 base::Unretained(this)));
    198 
    199   EXPECT_EQ("", owner_);
    200 }
    201 
    202 TEST_F(ConsumerManagementServiceTest, CanSetOwner) {
    203   cryptohome_status_ = chromeos::DBUS_METHOD_CALL_SUCCESS;
    204   cryptohome_result_ = true;
    205 
    206   service_->SetOwner(kTestOwner,
    207                      base::Bind(&ConsumerManagementServiceTest::OnSetOwnerDone,
    208                                 base::Unretained(this)));
    209 
    210   EXPECT_EQ(kAttributeOwnerId, set_boot_attribute_request_.name());
    211   EXPECT_EQ(kTestOwner, set_boot_attribute_request_.value());
    212   EXPECT_TRUE(set_owner_status_);
    213 }
    214 
    215 TEST_F(ConsumerManagementServiceTest, SetOwnerReturnsFalseWhenItFails) {
    216   cryptohome_status_ = chromeos::DBUS_METHOD_CALL_FAILURE;
    217   cryptohome_result_ = false;
    218 
    219   service_->SetOwner(kTestOwner,
    220                      base::Bind(&ConsumerManagementServiceTest::OnSetOwnerDone,
    221                                 base::Unretained(this)));
    222 
    223   EXPECT_FALSE(set_owner_status_);
    224 }
    225 
    226 class ConsumerManagementServiceEnrollmentTest
    227     : public ConsumerManagementServiceTest {
    228  public:
    229   ConsumerManagementServiceEnrollmentTest()
    230       : mock_user_manager_(new NiceMock<chromeos::MockUserManager>()),
    231         scoped_user_manager_enabler_(mock_user_manager_),
    232         fake_initializer_(new FakeDeviceCloudPolicyInitializer()),
    233         enrollment_status_(EnrollmentStatus::ForStatus(
    234             EnrollmentStatus::STATUS_SUCCESS)) {
    235     // Set up MockUserManager. The first user will be the owner.
    236     mock_user_manager_->AddUser(kTestOwner);
    237 
    238     // Return false for IsCurrentUserOwner() so that the enrollment stage is not
    239     // reset.
    240     ON_CALL(*mock_user_manager_, IsCurrentUserOwner())
    241         .WillByDefault(Return(false));
    242 
    243     // Inject FakeDeviceCloudPolicyInitializer.
    244     BrowserPolicyConnectorChromeOS* connector =
    245         g_browser_process->platform_part()->browser_policy_connector_chromeos();
    246     connector->SetDeviceCloudPolicyInitializerForTesting(
    247         scoped_ptr<DeviceCloudPolicyInitializer>(fake_initializer_));
    248   }
    249 
    250   virtual void SetUp() OVERRIDE {
    251     ConsumerManagementServiceTest::SetUp();
    252 
    253     // Set up the testing profile.
    254     profile()->set_profile_name(kTestOwner);
    255 
    256     // Set up FakeProfileOAuth2TokenService and issue a fake refresh token.
    257     ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
    258         profile(), &BuildAutoIssuingFakeProfileOAuth2TokenService);
    259     GetFakeProfileOAuth2TokenService()->
    260         IssueRefreshTokenForUser(kTestOwner, "fake_token");
    261 
    262     // Set up the authenticated user name and ID.
    263     SigninManagerFactory::GetForProfile(profile())->
    264         SetAuthenticatedUsername(kTestOwner);
    265 
    266     // The service should continue the enrollment process if the stage is
    267     // ENROLLMENT_STAGE_OWNER_STORED.
    268     SetEnrollmentStage(
    269         ConsumerManagementService::ENROLLMENT_STAGE_OWNER_STORED);
    270   }
    271 
    272   virtual void TearDown() OVERRIDE {
    273     g_browser_process->notification_ui_manager()->CancelAll();
    274 
    275     ConsumerManagementServiceTest::TearDown();
    276   }
    277 
    278   FakeProfileOAuth2TokenService* GetFakeProfileOAuth2TokenService() {
    279     return static_cast<FakeProfileOAuth2TokenService*>(
    280         ProfileOAuth2TokenServiceFactory::GetForProfile(profile()));
    281   }
    282 
    283   bool HasEnrollmentNotification() {
    284     return g_browser_process->notification_ui_manager()->
    285         FindById("consumer_management.enroll");
    286   }
    287 
    288   void RunEnrollmentTest() {
    289     // Send the profile prepared notification to continue the enrollment.
    290     service_->Observe(chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
    291                       content::Source<void>(NULL),  // Not used.
    292                       content::Details<Profile>(profile()));
    293     base::RunLoop().RunUntilIdle();
    294   }
    295 
    296   NiceMock<chromeos::MockUserManager>* mock_user_manager_;
    297   chromeos::ScopedUserManagerEnabler scoped_user_manager_enabler_;
    298   FakeDeviceCloudPolicyInitializer* fake_initializer_;
    299   EnrollmentStatus enrollment_status_;
    300 };
    301 
    302 TEST_F(ConsumerManagementServiceEnrollmentTest, EnrollsSuccessfully) {
    303   EXPECT_FALSE(fake_initializer_->was_start_enrollment_called());
    304 
    305   RunEnrollmentTest();
    306 
    307   EXPECT_TRUE(fake_initializer_->was_start_enrollment_called());
    308   EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_SUCCESS,
    309             GetEnrollmentStage());
    310   EXPECT_FALSE(HasEnrollmentNotification());
    311 }
    312 
    313 TEST_F(ConsumerManagementServiceEnrollmentTest,
    314        ShowsDesktopNotificationAndResetsEnrollmentStageIfCurrentUserIsOwner) {
    315   EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_OWNER_STORED,
    316             GetEnrollmentStage());
    317   EXPECT_FALSE(HasEnrollmentNotification());
    318   EXPECT_CALL(*mock_user_manager_, IsCurrentUserOwner())
    319       .WillOnce(Return(true));
    320 
    321   RunEnrollmentTest();
    322 
    323   EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_NONE,
    324             GetEnrollmentStage());
    325   EXPECT_TRUE(HasEnrollmentNotification());
    326 }
    327 
    328 TEST_F(ConsumerManagementServiceEnrollmentTest, FailsToGetAccessToken) {
    329   // Disable auto-posting so that RunEnrollmentTest() should stop and wait for
    330   // the access token to be available.
    331   GetFakeProfileOAuth2TokenService()->
    332       set_auto_post_fetch_response_on_message_loop(false);
    333 
    334   RunEnrollmentTest();
    335 
    336   // The service should have a pending token request.
    337   OAuth2TokenService::Request* token_request =
    338       service_->GetTokenRequestForTesting();
    339   EXPECT_TRUE(token_request);
    340 
    341   // Tell the service that the access token is not available because of some
    342   // backend issue.
    343   service_->OnGetTokenFailure(
    344       token_request,
    345       GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_ERROR));
    346 
    347   EXPECT_FALSE(fake_initializer_->was_start_enrollment_called());
    348   EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_GET_TOKEN_FAILED,
    349             GetEnrollmentStage());
    350 }
    351 
    352 TEST_F(ConsumerManagementServiceEnrollmentTest, FailsToRegister) {
    353   EXPECT_FALSE(fake_initializer_->was_start_enrollment_called());
    354   fake_initializer_->set_enrollment_status(EnrollmentStatus::ForStatus(
    355       EnrollmentStatus::STATUS_REGISTRATION_FAILED));
    356 
    357   RunEnrollmentTest();
    358 
    359   EXPECT_TRUE(fake_initializer_->was_start_enrollment_called());
    360   EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_DM_SERVER_FAILED,
    361             GetEnrollmentStage());
    362 }
    363 
    364 TEST_F(ConsumerManagementServiceEnrollmentTest,
    365        ShowsDesktopNotificationOnlyIfEnrollmentIsAlreadyCompleted) {
    366   SetEnrollmentStage(ConsumerManagementService::ENROLLMENT_STAGE_CANCELED);
    367   EXPECT_FALSE(HasEnrollmentNotification());
    368 
    369   RunEnrollmentTest();
    370 
    371   EXPECT_FALSE(fake_initializer_->was_start_enrollment_called());
    372   EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_NONE,
    373             GetEnrollmentStage());
    374   EXPECT_TRUE(HasEnrollmentNotification());
    375 }
    376 
    377 class ConsumerManagementServiceStatusTest
    378     : public chromeos::DeviceSettingsTestBase {
    379  public:
    380   ConsumerManagementServiceStatusTest()
    381       : testing_local_state_(TestingBrowserProcess::GetGlobal()),
    382         service_(NULL, &device_settings_service_) {
    383   }
    384 
    385   void SetEnrollmentStage(ConsumerManagementService::EnrollmentStage stage) {
    386     testing_local_state_.Get()->SetInteger(
    387         prefs::kConsumerManagementEnrollmentStage, stage);
    388   }
    389 
    390   void SetManagementMode(em::PolicyData::ManagementMode mode) {
    391     device_policy_.policy_data().set_management_mode(mode);
    392     device_policy_.Build();
    393     device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob());
    394     ReloadDeviceSettings();
    395   }
    396 
    397   ScopedTestingLocalState testing_local_state_;
    398   ConsumerManagementService service_;
    399 };
    400 
    401 TEST_F(ConsumerManagementServiceStatusTest, GetStatusAndGetStatusStringWork) {
    402   EXPECT_EQ(ConsumerManagementService::STATUS_UNKNOWN, service_.GetStatus());
    403   EXPECT_EQ("StatusUnknown", service_.GetStatusString());
    404 
    405   SetManagementMode(em::PolicyData::NOT_MANAGED);
    406   SetEnrollmentStage(ConsumerManagementService::ENROLLMENT_STAGE_NONE);
    407 
    408   EXPECT_EQ(ConsumerManagementService::STATUS_UNENROLLED, service_.GetStatus());
    409   EXPECT_EQ("StatusUnenrolled", service_.GetStatusString());
    410 
    411   SetEnrollmentStage(ConsumerManagementService::ENROLLMENT_STAGE_REQUESTED);
    412 
    413   EXPECT_EQ(ConsumerManagementService::STATUS_ENROLLING, service_.GetStatus());
    414   EXPECT_EQ("StatusEnrolling", service_.GetStatusString());
    415 
    416   SetManagementMode(em::PolicyData::CONSUMER_MANAGED);
    417   SetEnrollmentStage(ConsumerManagementService::ENROLLMENT_STAGE_SUCCESS);
    418 
    419   EXPECT_EQ(ConsumerManagementService::STATUS_ENROLLED, service_.GetStatus());
    420   EXPECT_EQ("StatusEnrolled", service_.GetStatusString());
    421 
    422   // TODO(davidyu): Test for STATUS_UNENROLLING when it is implemented.
    423   // http://crbug.com/353050.
    424 }
    425 
    426 }  // namespace policy
    427