Home | History | Annotate | Download | only in policy
      1 // Copyright (c) 2011 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/policy/cloud_policy_controller.h"
      6 
      7 #include "base/memory/scoped_temp_dir.h"
      8 #include "base/message_loop.h"
      9 #include "chrome/browser/policy/device_management_service.h"
     10 #include "chrome/browser/policy/device_token_fetcher.h"
     11 #include "chrome/browser/policy/mock_configuration_policy_store.h"
     12 #include "chrome/browser/policy/mock_device_management_backend.h"
     13 #include "chrome/browser/policy/mock_device_management_service.h"
     14 #include "chrome/browser/policy/policy_notifier.h"
     15 #include "chrome/browser/policy/proto/device_management_backend.pb.h"
     16 #include "chrome/browser/policy/user_policy_cache.h"
     17 #include "content/browser/browser_thread.h"
     18 #include "policy/policy_constants.h"
     19 #include "testing/gmock/include/gmock/gmock.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 
     22 const char kTestToken[] = "cloud_policy_controller_test_auth_token";
     23 
     24 namespace policy {
     25 
     26 namespace em = enterprise_management;
     27 
     28 using ::testing::_;
     29 using ::testing::AtLeast;
     30 using ::testing::InSequence;
     31 using ::testing::Mock;
     32 using ::testing::Return;
     33 
     34 class MockCloudPolicyIdentityStrategy : public CloudPolicyIdentityStrategy {
     35  public:
     36   MockCloudPolicyIdentityStrategy() {}
     37   virtual ~MockCloudPolicyIdentityStrategy() {}
     38 
     39   MOCK_METHOD0(GetDeviceToken, std::string());
     40   MOCK_METHOD0(GetDeviceID, std::string());
     41   MOCK_METHOD0(GetMachineID, std::string());
     42   MOCK_METHOD0(GetMachineModel, std::string());
     43   MOCK_METHOD0(GetPolicyType, std::string());
     44   MOCK_METHOD0(GetPolicyRegisterType, em::DeviceRegisterRequest_Type());
     45 
     46   MOCK_METHOD2(GetCredentials, bool(std::string*, std::string*));
     47   virtual void OnDeviceTokenAvailable(const std::string&) {}
     48 
     49  private:
     50   DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyIdentityStrategy);
     51 };
     52 
     53 ACTION_P2(MockCloudPolicyIdentityStrategyGetCredentials, username, auth_token) {
     54   *arg0 = username;
     55   *arg1 = auth_token;
     56   return true;
     57 }
     58 
     59 class MockDeviceTokenFetcher : public DeviceTokenFetcher {
     60  public:
     61   explicit MockDeviceTokenFetcher(CloudPolicyCacheBase* cache)
     62       : DeviceTokenFetcher(NULL, cache, NULL) {}
     63   virtual ~MockDeviceTokenFetcher() {}
     64 
     65   MOCK_METHOD0(GetDeviceToken, const std::string&());
     66   MOCK_METHOD5(FetchToken,
     67       void(const std::string&, const std::string&,
     68            em::DeviceRegisterRequest_Type,
     69            const std::string&, const std::string&));
     70   MOCK_METHOD0(SetUnmanagedState, void());
     71 
     72  private:
     73   DISALLOW_COPY_AND_ASSIGN(MockDeviceTokenFetcher);
     74 };
     75 
     76 class CloudPolicyControllerTest : public testing::Test {
     77  public:
     78   CloudPolicyControllerTest()
     79       : ui_thread_(BrowserThread::UI, &loop_),
     80         file_thread_(BrowserThread::FILE, &loop_) {}
     81 
     82   virtual ~CloudPolicyControllerTest() {}
     83 
     84   virtual void SetUp() {
     85     ASSERT_TRUE(temp_user_data_dir_.CreateUniqueTempDir());
     86     cache_.reset(new UserPolicyCache(
     87         temp_user_data_dir_.path().AppendASCII("CloudPolicyControllerTest")));
     88     token_fetcher_.reset(new MockDeviceTokenFetcher(cache_.get()));
     89     service_.set_backend(&backend_);
     90   }
     91 
     92   virtual void TearDown() {
     93     controller_.reset();  // Unregisters observers.
     94   }
     95 
     96   // Takes ownership of |backend|.
     97   void CreateNewController() {
     98     controller_.reset(new CloudPolicyController(
     99         &service_, cache_.get(), token_fetcher_.get(), &identity_strategy_,
    100         &notifier_));
    101   }
    102 
    103   void CreateNewController(int64 policy_refresh_rate_ms,
    104                            int policy_refresh_deviation_factor_percent,
    105                            int64 policy_refresh_deviation_max_ms,
    106                            int64 policy_refresh_error_delay_ms) {
    107     controller_.reset(new CloudPolicyController(
    108         &service_, cache_.get(), token_fetcher_.get(), &identity_strategy_,
    109         &notifier_,
    110         policy_refresh_rate_ms,
    111         policy_refresh_deviation_factor_percent,
    112         policy_refresh_deviation_max_ms,
    113         policy_refresh_error_delay_ms));
    114   }
    115 
    116   void ExpectHasSpdyPolicy() {
    117     MockConfigurationPolicyStore store;
    118     EXPECT_CALL(store, Apply(_, _)).Times(AtLeast(1));
    119     cache_->GetManagedPolicyProvider()->Provide(&store);
    120     FundamentalValue expected(true);
    121     ASSERT_TRUE(store.Get(kPolicyDisableSpdy) != NULL);
    122     EXPECT_TRUE(store.Get(kPolicyDisableSpdy)->Equals(&expected));
    123   }
    124 
    125   void SetupIdentityStrategy(
    126       const std::string& device_token,
    127       const std::string& device_id,
    128       const std::string& machine_id,
    129       const std::string& machine_model,
    130       const std::string& policy_type,
    131       const em::DeviceRegisterRequest_Type& policy_register_type,
    132       const std::string& user_name,
    133       const std::string& auth_token) {
    134     EXPECT_CALL(identity_strategy_, GetDeviceToken()).WillRepeatedly(
    135         Return(device_token));
    136     EXPECT_CALL(identity_strategy_, GetDeviceID()).WillRepeatedly(
    137         Return(device_id));
    138     EXPECT_CALL(identity_strategy_, GetMachineID()).WillRepeatedly(
    139         Return(machine_id));
    140     EXPECT_CALL(identity_strategy_, GetMachineModel()).WillRepeatedly(
    141         Return(machine_model));
    142     EXPECT_CALL(identity_strategy_, GetPolicyType()).WillRepeatedly(
    143         Return(policy_type));
    144     EXPECT_CALL(identity_strategy_, GetPolicyRegisterType()).WillRepeatedly(
    145         Return(policy_register_type));
    146     if (!user_name.empty()) {
    147       EXPECT_CALL(identity_strategy_, GetCredentials(_, _)).WillRepeatedly(
    148           MockCloudPolicyIdentityStrategyGetCredentials(user_name, auth_token));
    149     }
    150   }
    151 
    152  protected:
    153   scoped_ptr<CloudPolicyCacheBase> cache_;
    154   scoped_ptr<CloudPolicyController> controller_;
    155   scoped_ptr<MockDeviceTokenFetcher> token_fetcher_;
    156   MockCloudPolicyIdentityStrategy identity_strategy_;
    157   MockDeviceManagementBackend backend_;
    158   MockDeviceManagementService service_;
    159   PolicyNotifier notifier_;
    160   ScopedTempDir temp_user_data_dir_;
    161   MessageLoop loop_;
    162 
    163  private:
    164   BrowserThread ui_thread_;
    165   BrowserThread file_thread_;
    166 
    167   DISALLOW_COPY_AND_ASSIGN(CloudPolicyControllerTest);
    168 };
    169 
    170 // If a device token is present when the controller starts up, it should
    171 // fetch and apply policy.
    172 TEST_F(CloudPolicyControllerTest, StartupWithDeviceToken) {
    173   SetupIdentityStrategy("fake_device_token", "device_id", "machine_id",
    174                         "machine_model", "google/chromeos/user",
    175                         em::DeviceRegisterRequest::USER, "", "");
    176   EXPECT_CALL(backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
    177       MockDeviceManagementBackendSucceedSpdyCloudPolicy());
    178   CreateNewController();
    179   loop_.RunAllPending();
    180   ExpectHasSpdyPolicy();
    181 }
    182 
    183 // If no device token is present when the controller starts up, it should
    184 // instruct the token_fetcher_ to fetch one.
    185 TEST_F(CloudPolicyControllerTest, StartupWithoutDeviceToken) {
    186   SetupIdentityStrategy("", "device_id", "machine_id", "machine_model",
    187                         "google/chromeos/user", em::DeviceRegisterRequest::USER,
    188                         "a (at) b.com", "auth_token");
    189   EXPECT_CALL(*token_fetcher_.get(), FetchToken(_, _, _, _, _)).Times(1);
    190   CreateNewController();
    191   loop_.RunAllPending();
    192 }
    193 
    194 // If the current user belongs to a known non-managed domain, no token fetch
    195 // should be initiated.
    196 TEST_F(CloudPolicyControllerTest, StartupUnmanagedUser) {
    197   SetupIdentityStrategy("", "device_id",  "machine_id", "machine_mode",
    198                         "google/chromeos/user", em::DeviceRegisterRequest::USER,
    199                         "DannoHelper (at) gmail.com", "auth_token");
    200   EXPECT_CALL(*token_fetcher_.get(), FetchToken(_, _, _, _, _)).Times(0);
    201   CreateNewController();
    202   loop_.RunAllPending();
    203 }
    204 
    205 // After policy has been fetched successfully, a new fetch should be triggered
    206 // after the refresh interval has timed out.
    207 TEST_F(CloudPolicyControllerTest, RefreshAfterSuccessfulPolicy) {
    208   SetupIdentityStrategy("device_token", "device_id", "machine_id",
    209                         "machine_model", "google/chromeos/user",
    210                         em::DeviceRegisterRequest::USER,
    211                         "DannoHelperDelegate (at) b.com", "auth_token");
    212   EXPECT_CALL(backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
    213       MockDeviceManagementBackendSucceedSpdyCloudPolicy()).WillOnce(
    214       MockDeviceManagementBackendFailPolicy(
    215           DeviceManagementBackend::kErrorRequestFailed));
    216   CreateNewController(0, 0, 0, 1000 * 1000);
    217   loop_.RunAllPending();
    218   ExpectHasSpdyPolicy();
    219 }
    220 
    221 // If policy fetching failed, it should be retried.
    222 TEST_F(CloudPolicyControllerTest, RefreshAfterError) {
    223   SetupIdentityStrategy("device_token", "device_id", "machine_id",
    224                         "machine_model", "google/chromeos/user",
    225                         em::DeviceRegisterRequest::USER,
    226                         "DannoHelperDelegateImpl (at) b.com", "auth_token");
    227   EXPECT_CALL(backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
    228       MockDeviceManagementBackendFailPolicy(
    229           DeviceManagementBackend::kErrorRequestFailed)).WillOnce(
    230       MockDeviceManagementBackendSucceedSpdyCloudPolicy());
    231   CreateNewController(1000 * 1000, 0, 0, 0);
    232   loop_.RunAllPending();
    233   ExpectHasSpdyPolicy();
    234 }
    235 
    236 // If the backend reports that the device token was invalid, the controller
    237 // should instruct the token fetcher to fetch a new token.
    238 TEST_F(CloudPolicyControllerTest, InvalidToken) {
    239   SetupIdentityStrategy("device_token", "device_id", "machine_id",
    240                         "machine_model", "google/chromeos/user",
    241                         em::DeviceRegisterRequest::USER,
    242                         "standup (at) ten.am", "auth");
    243   EXPECT_CALL(backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
    244       MockDeviceManagementBackendFailPolicy(
    245           DeviceManagementBackend::kErrorServiceManagementTokenInvalid));
    246   EXPECT_CALL(*token_fetcher_.get(), FetchToken(_, _, _, _, _)).Times(1);
    247   CreateNewController(1000 * 1000, 0, 0, 0);
    248   loop_.RunAllPending();
    249 }
    250 
    251 // If the backend reports that the device is unknown to the server, the
    252 // controller should instruct the token fetcher to fetch a new token.
    253 TEST_F(CloudPolicyControllerTest, DeviceNotFound) {
    254   SetupIdentityStrategy("device_token", "device_id", "machine_id",
    255                         "machine_model", "google/chromeos/user",
    256                         em::DeviceRegisterRequest::USER,
    257                         "me (at) you.com", "auth");
    258   EXPECT_CALL(backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
    259       MockDeviceManagementBackendFailPolicy(
    260           DeviceManagementBackend::kErrorServiceDeviceNotFound));
    261   EXPECT_CALL(*token_fetcher_.get(), FetchToken(_, _, _, _, _)).Times(1);
    262   CreateNewController(1000 * 1000, 0, 0, 0);
    263   loop_.RunAllPending();
    264 }
    265 
    266 // If the backend reports that the device is no longer managed, the controller
    267 // should instruct the token fetcher to fetch a new token (which will in turn
    268 // set and persist the correct 'unmanaged' state).
    269 TEST_F(CloudPolicyControllerTest, NoLongerManaged) {
    270   SetupIdentityStrategy("device_token", "device_id", "machine_id",
    271                         "machine_model", "google/chromeos/user",
    272                         em::DeviceRegisterRequest::USER,
    273                         "who (at) what.com", "auth");
    274   EXPECT_CALL(backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
    275       MockDeviceManagementBackendFailPolicy(
    276           DeviceManagementBackend::kErrorServiceManagementNotSupported));
    277   EXPECT_CALL(*token_fetcher_.get(), SetUnmanagedState()).Times(1);
    278   CreateNewController(0, 0, 0, 1000 * 1000);
    279   loop_.RunAllPending();
    280 }
    281 
    282 }  // namespace policy
    283