• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
MockCloudPolicyIdentityStrategy()36   MockCloudPolicyIdentityStrategy() {}
~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*));
OnDeviceTokenAvailable(const std::string &)47   virtual void OnDeviceTokenAvailable(const std::string&) {}
48 
49  private:
50   DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyIdentityStrategy);
51 };
52 
ACTION_P2(MockCloudPolicyIdentityStrategyGetCredentials,username,auth_token)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:
MockDeviceTokenFetcher(CloudPolicyCacheBase * cache)61   explicit MockDeviceTokenFetcher(CloudPolicyCacheBase* cache)
62       : DeviceTokenFetcher(NULL, cache, NULL) {}
~MockDeviceTokenFetcher()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:
CloudPolicyControllerTest()78   CloudPolicyControllerTest()
79       : ui_thread_(BrowserThread::UI, &loop_),
80         file_thread_(BrowserThread::FILE, &loop_) {}
81 
~CloudPolicyControllerTest()82   virtual ~CloudPolicyControllerTest() {}
83 
SetUp()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 
TearDown()92   virtual void TearDown() {
93     controller_.reset();  // Unregisters observers.
94   }
95 
96   // Takes ownership of |backend|.
CreateNewController()97   void CreateNewController() {
98     controller_.reset(new CloudPolicyController(
99         &service_, cache_.get(), token_fetcher_.get(), &identity_strategy_,
100         &notifier_));
101   }
102 
CreateNewController(int64 policy_refresh_rate_ms,int policy_refresh_deviation_factor_percent,int64 policy_refresh_deviation_max_ms,int64 policy_refresh_error_delay_ms)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 
ExpectHasSpdyPolicy()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 
SetupIdentityStrategy(const std::string & device_token,const std::string & device_id,const std::string & machine_id,const std::string & machine_model,const std::string & policy_type,const em::DeviceRegisterRequest_Type & policy_register_type,const std::string & user_name,const std::string & auth_token)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.
TEST_F(CloudPolicyControllerTest,StartupWithDeviceToken)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.
TEST_F(CloudPolicyControllerTest,StartupWithoutDeviceToken)185 TEST_F(CloudPolicyControllerTest, StartupWithoutDeviceToken) {
186   SetupIdentityStrategy("", "device_id", "machine_id", "machine_model",
187                         "google/chromeos/user", em::DeviceRegisterRequest::USER,
188                         "a@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.
TEST_F(CloudPolicyControllerTest,StartupUnmanagedUser)196 TEST_F(CloudPolicyControllerTest, StartupUnmanagedUser) {
197   SetupIdentityStrategy("", "device_id",  "machine_id", "machine_mode",
198                         "google/chromeos/user", em::DeviceRegisterRequest::USER,
199                         "DannoHelper@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.
TEST_F(CloudPolicyControllerTest,RefreshAfterSuccessfulPolicy)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@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.
TEST_F(CloudPolicyControllerTest,RefreshAfterError)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@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.
TEST_F(CloudPolicyControllerTest,InvalidToken)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@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.
TEST_F(CloudPolicyControllerTest,DeviceNotFound)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@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).
TEST_F(CloudPolicyControllerTest,NoLongerManaged)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@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