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.
5 #include "chrome/browser/chromeos/policy/device_cloud_policy_invalidator.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/run_loop.h"
12 #include "chrome/browser/browser_process_platform_part.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
15 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
16 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
17 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
18 #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h"
19 #include "chrome/browser/chromeos/settings/cros_settings.h"
20 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
21 #include "chrome/browser/chromeos/settings/device_settings_service.h"
22 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
23 #include "chrome/browser/chromeos/settings/mock_owner_key_util.h"
24 #include "chrome/browser/invalidation/fake_invalidation_service.h"
25 #include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
26 #include "chrome/browser/policy/cloud/cloud_policy_invalidator.h"
27 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/test/base/testing_browser_process.h"
29 #include "chrome/test/base/testing_profile_manager.h"
30 #include "chromeos/cryptohome/system_salt_getter.h"
31 #include "chromeos/dbus/dbus_thread_manager.h"
32 #include "components/invalidation/invalidation_service.h"
33 #include "components/invalidation/invalidator_state.h"
34 #include "components/invalidation/profile_invalidation_provider.h"
35 #include "components/invalidation/ticl_invalidation_service.h"
36 #include "components/keyed_service/core/keyed_service.h"
37 #include "components/policy/core/common/cloud/cloud_policy_client.h"
38 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
39 #include "components/policy/core/common/cloud/cloud_policy_core.h"
40 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
41 #include "content/public/browser/browser_context.h"
42 #include "content/public/browser/notification_details.h"
43 #include "content/public/browser/notification_service.h"
44 #include "content/public/test/test_browser_thread_bundle.h"
45 #include "net/url_request/url_request_context_getter.h"
46 #include "net/url_request/url_request_test_util.h"
47 #include "policy/proto/device_management_backend.pb.h"
48 #include "testing/gmock/include/gmock/gmock.h"
49 #include "testing/gtest/include/gtest/gtest.h"
55 KeyedService* BuildProfileInvalidationProvider(
56 content::BrowserContext* context) {
57 scoped_ptr<invalidation::FakeInvalidationService> invalidation_service(
58 new invalidation::FakeInvalidationService);
59 invalidation_service->SetInvalidatorState(
60 syncer::TRANSIENT_INVALIDATION_ERROR);
61 return new invalidation::ProfileInvalidationProvider(
62 invalidation_service.PassAs<invalidation::InvalidationService>());
67 class DeviceCloudPolicyInvalidatorTest : public testing::Test {
69 DeviceCloudPolicyInvalidatorTest();
70 virtual ~DeviceCloudPolicyInvalidatorTest();
73 virtual void SetUp() OVERRIDE;
74 virtual void TearDown() OVERRIDE;
76 // Ownership is not passed. The Profile is owned by the global ProfileManager.
77 Profile *CreateProfile(const std::string& profile_name);
79 invalidation::TiclInvalidationService* GetDeviceInvalidationService();
80 bool HasDeviceInvalidationServiceObserver() const;
82 invalidation::FakeInvalidationService* GetProfileInvalidationService(
84 int GetProfileInvalidationServiceObserverCount() const;
86 const invalidation::InvalidationService* GetInvalidationService() const;
87 CloudPolicyInvalidator* GetCloudPolicyInvalidator() const;
89 void ConnectDeviceInvalidationService();
92 DevicePolicyBuilder device_policy_;
95 content::TestBrowserThreadBundle thread_bundle_;
96 scoped_refptr<net::URLRequestContextGetter> system_request_context_;
97 TestingProfileManager profile_manager_;
98 ScopedStubEnterpriseInstallAttributes install_attributes_;
99 scoped_ptr<chromeos::ScopedTestDeviceSettingsService>
100 test_device_settings_service_;
101 scoped_ptr<chromeos::ScopedTestCrosSettings> test_cros_settings_;
102 chromeos::DeviceSettingsTestHelper device_settings_test_helper_;
104 scoped_ptr<DeviceCloudPolicyInvalidator> invalidator_;
107 DeviceCloudPolicyInvalidatorTest::DeviceCloudPolicyInvalidatorTest()
108 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
109 system_request_context_(new net::TestURLRequestContextGetter(
110 base::MessageLoopProxy::current())),
111 profile_manager_(TestingBrowserProcess::GetGlobal()),
112 install_attributes_("example.com",
115 DEVICE_MODE_ENTERPRISE) {
118 DeviceCloudPolicyInvalidatorTest::~DeviceCloudPolicyInvalidatorTest() {
121 void DeviceCloudPolicyInvalidatorTest::SetUp() {
122 chromeos::SystemSaltGetter::Initialize();
123 chromeos::DBusThreadManager::InitializeWithStub();
124 chromeos::DeviceOAuth2TokenServiceFactory::Initialize();
125 TestingBrowserProcess::GetGlobal()->SetSystemRequestContext(
126 system_request_context_.get());
127 ASSERT_TRUE(profile_manager_.SetUp());
129 test_device_settings_service_.reset(new
130 chromeos::ScopedTestDeviceSettingsService);
131 test_cros_settings_.reset(new chromeos::ScopedTestCrosSettings);
132 scoped_refptr<chromeos::MockOwnerKeyUtil> owner_key_util(
133 new chromeos::MockOwnerKeyUtil);
134 owner_key_util->SetPublicKeyFromPrivateKey(
135 *device_policy_.GetSigningKey());
136 chromeos::DeviceSettingsService::Get()->SetSessionManager(
137 &device_settings_test_helper_,
140 device_policy_.policy_data().set_invalidation_source(123);
141 device_policy_.policy_data().set_invalidation_name("invalidation");
142 device_policy_.Build();
143 device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob());
144 device_settings_test_helper_.Flush();
146 scoped_ptr<MockCloudPolicyClient> policy_client(new MockCloudPolicyClient);
147 EXPECT_CALL(*policy_client, SetupRegistration("token", "device-id"));
148 CloudPolicyCore* core = TestingBrowserProcess::GetGlobal()->platform_part()->
149 browser_policy_connector_chromeos()->GetDeviceCloudPolicyManager()->
151 core->Connect(policy_client.PassAs<CloudPolicyClient>());
152 core->StartRefreshScheduler();
154 invalidation::ProfileInvalidationProviderFactory::GetInstance()->
155 RegisterTestingFactory(BuildProfileInvalidationProvider);
157 invalidator_.reset(new DeviceCloudPolicyInvalidator);
160 void DeviceCloudPolicyInvalidatorTest::TearDown() {
161 invalidator_.reset();
162 base::RunLoop().RunUntilIdle();
164 invalidation::ProfileInvalidationProviderFactory::GetInstance()->
165 RegisterTestingFactory(NULL);
166 chromeos::DeviceSettingsService::Get()->UnsetSessionManager();
167 TestingBrowserProcess::GetGlobal()->SetBrowserPolicyConnector(NULL);
168 chromeos::DeviceOAuth2TokenServiceFactory::Shutdown();
169 chromeos::DBusThreadManager::Shutdown();
170 chromeos::SystemSaltGetter::Shutdown();
173 Profile *DeviceCloudPolicyInvalidatorTest::CreateProfile(
174 const std::string& profile_name) {
175 Profile* profile = profile_manager_.CreateTestingProfile(profile_name);
176 content::NotificationService::current()->Notify(
177 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
178 content::NotificationService::AllSources(),
179 content::Details<Profile>(profile));
183 invalidation::TiclInvalidationService*
184 DeviceCloudPolicyInvalidatorTest::GetDeviceInvalidationService() {
185 return invalidator_->device_invalidation_service_.get();
188 bool DeviceCloudPolicyInvalidatorTest::HasDeviceInvalidationServiceObserver(
190 return invalidator_->device_invalidation_service_observer_.get();
193 invalidation::FakeInvalidationService*
194 DeviceCloudPolicyInvalidatorTest::GetProfileInvalidationService(
196 invalidation::ProfileInvalidationProvider* invalidation_provider =
197 static_cast<invalidation::ProfileInvalidationProvider*>(
198 invalidation::ProfileInvalidationProviderFactory::GetInstance()->
199 GetServiceForBrowserContext(profile, false));
200 if (!invalidation_provider)
202 return static_cast<invalidation::FakeInvalidationService*>(
203 invalidation_provider->GetInvalidationService());
206 int DeviceCloudPolicyInvalidatorTest::
207 GetProfileInvalidationServiceObserverCount() const {
208 return invalidator_->profile_invalidation_service_observers_.size();
211 const invalidation::InvalidationService*
212 DeviceCloudPolicyInvalidatorTest::GetInvalidationService() const {
213 return invalidator_->invalidation_service_;
216 CloudPolicyInvalidator*
217 DeviceCloudPolicyInvalidatorTest::GetCloudPolicyInvalidator() const {
218 return invalidator_->invalidator_.get();
221 void DeviceCloudPolicyInvalidatorTest::ConnectDeviceInvalidationService() {
222 // Verify that a device-global invalidation service has been created.
223 ASSERT_TRUE(GetDeviceInvalidationService());
224 EXPECT_TRUE(HasDeviceInvalidationServiceObserver());
226 // Verify that no per-profile invalidation service observers have been
228 EXPECT_EQ(0, GetProfileInvalidationServiceObserverCount());
230 // Verify that no invalidator exists yet
231 EXPECT_FALSE(GetCloudPolicyInvalidator());
232 EXPECT_FALSE(GetInvalidationService());
234 // Indicate that the device-global invalidation service has connected.
235 GetDeviceInvalidationService()->OnInvalidatorStateChange(
236 syncer::INVALIDATIONS_ENABLED);
237 base::RunLoop().RunUntilIdle();
239 // Verify that the device-global invalidation service still exists.
240 EXPECT_TRUE(GetDeviceInvalidationService());
241 EXPECT_TRUE(HasDeviceInvalidationServiceObserver());
243 // Verify that an invalidator backed by the device-global invalidation service
245 EXPECT_TRUE(GetCloudPolicyInvalidator());
246 EXPECT_EQ(GetDeviceInvalidationService(), GetInvalidationService());
249 // Verifies that a DeviceCloudPolicyInvalidator backed by a device-global
250 // invalidation service is created/destroyed as the service
251 // connects/disconnects.
252 TEST_F(DeviceCloudPolicyInvalidatorTest, UseDeviceInvalidationService) {
253 // Verify that an invalidator backed by the device-global invalidation service
254 // is created when the service connects.
255 ConnectDeviceInvalidationService();
256 ASSERT_TRUE(GetDeviceInvalidationService());
258 // Indicate that the device-global invalidation service has disconnected.
259 GetDeviceInvalidationService()->OnInvalidatorStateChange(
260 syncer::INVALIDATION_CREDENTIALS_REJECTED);
261 base::RunLoop().RunUntilIdle();
263 // Verify that the device-global invalidation service still exists.
264 EXPECT_TRUE(GetDeviceInvalidationService());
265 EXPECT_TRUE(HasDeviceInvalidationServiceObserver());
267 // Verify that the invalidator has been destroyed.
268 EXPECT_FALSE(GetCloudPolicyInvalidator());
269 EXPECT_FALSE(GetInvalidationService());
272 // Verifies that a DeviceCloudPolicyInvalidator backed by a per-profile
273 // invalidation service is created/destroyed as the service
274 // connects/disconnects.
275 TEST_F(DeviceCloudPolicyInvalidatorTest, UseProfileInvalidationService) {
276 // Create a user profile.
277 Profile* profile = CreateProfile("test");
278 ASSERT_TRUE(profile);
280 // Verify that a device-global invalidation service has been created.
281 EXPECT_TRUE(GetDeviceInvalidationService());
282 EXPECT_TRUE(HasDeviceInvalidationServiceObserver());
284 // Verify that a per-profile invalidation service has been created.
285 invalidation::FakeInvalidationService* profile_invalidation_service =
286 GetProfileInvalidationService(profile);
287 ASSERT_TRUE(profile_invalidation_service);
288 EXPECT_EQ(1, GetProfileInvalidationServiceObserverCount());
290 // Verify that no invalidator exists yet
291 EXPECT_FALSE(GetCloudPolicyInvalidator());
292 EXPECT_FALSE(GetInvalidationService());
294 // Indicate that the per-profile invalidation service has connected.
295 profile_invalidation_service->SetInvalidatorState(
296 syncer::INVALIDATIONS_ENABLED);
298 // Verify that the device-global invalidator has been destroyed.
299 EXPECT_FALSE(GetDeviceInvalidationService());
300 EXPECT_FALSE(HasDeviceInvalidationServiceObserver());
302 // Verify that a per-profile invalidation service still exists.
303 profile_invalidation_service = GetProfileInvalidationService(profile);
304 ASSERT_TRUE(profile_invalidation_service);
305 EXPECT_EQ(1, GetProfileInvalidationServiceObserverCount());
307 // Verify that an invalidator backed by the per-profile invalidation service
309 EXPECT_TRUE(GetCloudPolicyInvalidator());
310 EXPECT_EQ(profile_invalidation_service, GetInvalidationService());
312 // Indicate that the per-profile invalidation service has disconnected.
313 profile_invalidation_service->SetInvalidatorState(
314 syncer::INVALIDATION_CREDENTIALS_REJECTED);
316 // Verify that a device-global invalidation service has been created.
317 EXPECT_TRUE(GetDeviceInvalidationService());
318 EXPECT_TRUE(HasDeviceInvalidationServiceObserver());
320 // Verify that a per-profile invalidation service still exists.
321 profile_invalidation_service = GetProfileInvalidationService(profile);
322 EXPECT_TRUE(profile_invalidation_service);
323 EXPECT_EQ(1, GetProfileInvalidationServiceObserverCount());
325 // Verify that the invalidator has been destroyed.
326 EXPECT_FALSE(GetCloudPolicyInvalidator());
327 EXPECT_FALSE(GetInvalidationService());
330 // Verifies that a DeviceCloudPolicyInvalidator exists whenever a connected
331 // invalidation service is available, automatically switching between
332 // device-global and per-profile invalidation services as they
333 // connect/disconnect, giving priority to per-profile invalidation services.
334 // Also verifies that the highest handled invalidation version is preserved when
335 // switching invalidation services.
336 TEST_F(DeviceCloudPolicyInvalidatorTest, SwitchInvalidationServices) {
337 CloudPolicyStore* store = static_cast<CloudPolicyStore*>(
338 TestingBrowserProcess::GetGlobal()->platform_part()->
339 browser_policy_connector_chromeos()->GetDeviceCloudPolicyManager()->
343 // Verify that an invalidator backed by the device-global invalidation service
344 // is created when the service connects.
345 ConnectDeviceInvalidationService();
346 CloudPolicyInvalidator* invalidator = GetCloudPolicyInvalidator();
347 ASSERT_TRUE(invalidator);
348 ASSERT_TRUE(GetDeviceInvalidationService());
350 // Verify that the invalidator's highest handled invalidation version starts
352 EXPECT_EQ(0, invalidator->highest_handled_invalidation_version());
354 // Create a first user profile.
355 Profile* profile_1 = CreateProfile("test_1");
356 ASSERT_TRUE(profile_1);
358 // Verify that the device-global invalidation service still exists.
359 EXPECT_TRUE(GetDeviceInvalidationService());
360 EXPECT_TRUE(HasDeviceInvalidationServiceObserver());
362 // Verify that a per-profile invalidation service has been created for the
363 // first user profile.
364 invalidation::FakeInvalidationService* profile_1_invalidation_service =
365 GetProfileInvalidationService(profile_1);
366 ASSERT_TRUE(profile_1_invalidation_service);
367 EXPECT_EQ(1, GetProfileInvalidationServiceObserverCount());
369 // Verify that an invalidator backed by the device-global invalidation service
371 EXPECT_TRUE(GetCloudPolicyInvalidator());
372 EXPECT_EQ(GetDeviceInvalidationService(), GetInvalidationService());
374 // Indicate that the first user profile's per-profile invalidation service has
376 profile_1_invalidation_service->SetInvalidatorState(
377 syncer::INVALIDATIONS_ENABLED);
379 // Verify that the device-global invalidator has been destroyed.
380 EXPECT_FALSE(GetDeviceInvalidationService());
381 EXPECT_FALSE(HasDeviceInvalidationServiceObserver());
383 // Verify that a per-profile invalidation service still exists for the first
385 profile_1_invalidation_service = GetProfileInvalidationService(profile_1);
386 EXPECT_TRUE(profile_1_invalidation_service);
387 EXPECT_EQ(1, GetProfileInvalidationServiceObserverCount());
389 // Verify that an invalidator backed by the per-profile invalidation service
390 // for the first user profile has been created.
391 invalidator = GetCloudPolicyInvalidator();
392 ASSERT_TRUE(invalidator);
393 EXPECT_EQ(profile_1_invalidation_service, GetInvalidationService());
395 // Verify that the invalidator's highest handled invalidation version starts
397 EXPECT_EQ(0, invalidator->highest_handled_invalidation_version());
399 // Handle an invalidation with version 1. Verify that the invalidator's
400 // highest handled invalidation version is updated accordingly.
401 store->Store(device_policy_.policy(), 1);
402 invalidator->OnStoreLoaded(store);
403 EXPECT_EQ(1, invalidator->highest_handled_invalidation_version());
405 // Create a second user profile.
406 Profile* profile_2 = CreateProfile("test_2");
407 ASSERT_TRUE(profile_2);
409 // Verify that the device-global invalidator still does not exist.
410 EXPECT_FALSE(GetDeviceInvalidationService());
411 EXPECT_FALSE(HasDeviceInvalidationServiceObserver());
413 // Verify that a per-profile invalidation service still exists for the first
414 // user profile and one has been created for the second user profile.
415 profile_1_invalidation_service = GetProfileInvalidationService(profile_1);
416 EXPECT_TRUE(profile_1_invalidation_service);
417 invalidation::FakeInvalidationService* profile_2_invalidation_service =
418 GetProfileInvalidationService(profile_2);
419 ASSERT_TRUE(profile_2_invalidation_service);
420 EXPECT_EQ(2, GetProfileInvalidationServiceObserverCount());
422 // Verify that an invalidator backed by the per-profile invalidation service
423 // for the first user profile still exists.
424 EXPECT_TRUE(GetCloudPolicyInvalidator());
425 EXPECT_EQ(profile_1_invalidation_service, GetInvalidationService());
427 // Indicate that the second user profile's per-profile invalidation service
429 profile_2_invalidation_service->SetInvalidatorState(
430 syncer::INVALIDATIONS_ENABLED);
432 // Verify that the device-global invalidator still does not exist.
433 EXPECT_FALSE(GetDeviceInvalidationService());
434 EXPECT_FALSE(HasDeviceInvalidationServiceObserver());
436 // Verify that per-profile invalidation services still exist for both user
438 profile_1_invalidation_service = GetProfileInvalidationService(profile_1);
439 ASSERT_TRUE(profile_1_invalidation_service);
440 profile_2_invalidation_service = GetProfileInvalidationService(profile_2);
441 EXPECT_TRUE(profile_2_invalidation_service);
442 EXPECT_EQ(2, GetProfileInvalidationServiceObserverCount());
444 // Verify that an invalidator backed by the per-profile invalidation service
445 // for the first user profile still exists.
446 EXPECT_TRUE(GetCloudPolicyInvalidator());
447 EXPECT_EQ(profile_1_invalidation_service, GetInvalidationService());
449 // Indicate that the per-profile invalidation service for the first user
450 // profile has disconnected.
451 profile_1_invalidation_service->SetInvalidatorState(
452 syncer::INVALIDATION_CREDENTIALS_REJECTED);
454 // Verify that the device-global invalidator still does not exist.
455 EXPECT_FALSE(GetDeviceInvalidationService());
456 EXPECT_FALSE(HasDeviceInvalidationServiceObserver());
458 // Verify that per-profile invalidation services still exist for both user
460 profile_1_invalidation_service = GetProfileInvalidationService(profile_1);
461 EXPECT_TRUE(profile_1_invalidation_service);
462 profile_2_invalidation_service = GetProfileInvalidationService(profile_2);
463 ASSERT_TRUE(profile_2_invalidation_service);
464 EXPECT_EQ(2, GetProfileInvalidationServiceObserverCount());
466 // Verify that an invalidator backed by the per-profile invalidation service
467 // for the second user profile has been created.
468 invalidator = GetCloudPolicyInvalidator();
469 ASSERT_TRUE(invalidator);
470 EXPECT_EQ(profile_2_invalidation_service, GetInvalidationService());
472 // Verify that the invalidator's highest handled invalidation version starts
474 EXPECT_EQ(1, invalidator->highest_handled_invalidation_version());
476 // Handle an invalidation with version 2. Verify that the invalidator's
477 // highest handled invalidation version is updated accordingly.
478 store->Store(device_policy_.policy(), 2);
479 invalidator->OnStoreLoaded(store);
480 EXPECT_EQ(2, invalidator->highest_handled_invalidation_version());
482 // Indicate that the per-profile invalidation service for the second user
483 // profile has disconnected.
484 profile_2_invalidation_service->SetInvalidatorState(
485 syncer::INVALIDATION_CREDENTIALS_REJECTED);
487 // Verify that a device-global invalidation service has been created.
488 ASSERT_TRUE(GetDeviceInvalidationService());
489 EXPECT_TRUE(HasDeviceInvalidationServiceObserver());
491 // Verify that per-profile invalidation services still exist for both user
493 profile_1_invalidation_service = GetProfileInvalidationService(profile_1);
494 EXPECT_TRUE(profile_1_invalidation_service);
495 profile_2_invalidation_service = GetProfileInvalidationService(profile_2);
496 EXPECT_TRUE(profile_2_invalidation_service);
497 EXPECT_EQ(2, GetProfileInvalidationServiceObserverCount());
499 // Verify that the invalidator has been destroyed.
500 EXPECT_FALSE(GetCloudPolicyInvalidator());
501 EXPECT_FALSE(GetInvalidationService());
503 // Indicate that the device-global invalidation service has connected.
504 GetDeviceInvalidationService()->OnInvalidatorStateChange(
505 syncer::INVALIDATIONS_ENABLED);
506 base::RunLoop().RunUntilIdle();
508 // Verify that the device-global invalidation service still exists.
509 EXPECT_TRUE(GetDeviceInvalidationService());
510 EXPECT_TRUE(HasDeviceInvalidationServiceObserver());
512 // Verify that per-profile invalidation services still exist for both user
514 profile_1_invalidation_service = GetProfileInvalidationService(profile_1);
515 EXPECT_TRUE(profile_1_invalidation_service);
516 profile_2_invalidation_service = GetProfileInvalidationService(profile_2);
517 EXPECT_TRUE(profile_2_invalidation_service);
518 EXPECT_EQ(2, GetProfileInvalidationServiceObserverCount());
520 // Verify that an invalidator backed by the device-global invalidation service
522 invalidator = GetCloudPolicyInvalidator();
523 ASSERT_TRUE(invalidator);
524 EXPECT_EQ(GetDeviceInvalidationService(), GetInvalidationService());
526 // Verify that the invalidator's highest handled invalidation version starts
528 EXPECT_EQ(2, invalidator->highest_handled_invalidation_version());
531 } // namespace policy