Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: chrome/browser/chromeos/login/login_utils_browsertest.cc

Issue 8499021: UserPolicyCache only becomes ready after policy has been fetched. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/chromeos/login/login_utils.h"
6
7 #include "base/basictypes.h"
8 #include "base/command_line.h"
9 #include "base/message_loop.h"
10 #include "base/path_service.h"
11 #include "base/scoped_temp_dir.h"
12 #include "base/string_util.h"
13 #include "chrome/browser/chromeos/cros/cros_library.h"
14 #include "chrome/browser/chromeos/cros/mock_cryptohome_library.h"
15 #include "chrome/browser/chromeos/cros/mock_library_loader.h"
16 #include "chrome/browser/chromeos/dbus/mock_dbus_thread_manager.h"
17 #include "chrome/browser/chromeos/dbus/mock_session_manager_client.h"
18 #include "chrome/browser/chromeos/login/authenticator.h"
19 #include "chrome/browser/chromeos/login/login_status_consumer.h"
20 #include "chrome/browser/chromeos/login/user_manager.h"
21 #include "chrome/browser/io_thread.h"
22 #include "chrome/browser/net/predictor.h"
23 #include "chrome/browser/policy/browser_policy_connector.h"
24 #include "chrome/browser/policy/proto/device_management_backend.pb.h"
25 #include "chrome/browser/profiles/profile_manager.h"
26 #include "chrome/common/chrome_paths.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/net/gaia/gaia_urls.h"
29 #include "chrome/common/pref_names.h"
30 #include "chrome/common/net/gaia/gaia_auth_consumer.h"
31 #include "chrome/test/base/testing_browser_process.h"
32 #include "chrome/test/base/testing_pref_service.h"
33 #include "content/test/test_browser_thread.h"
34 #include "content/test/test_url_fetcher_factory.h"
35 #include "net/url_request/url_request.h"
36 #include "net/url_request/url_request_status.h"
37 #include "testing/gmock/include/gmock/gmock.h"
38 #include "testing/gtest/include/gtest/gtest.h"
39
40 namespace chromeos {
41
42 namespace {
43
44 namespace em = enterprise_management;
45
46 using ::testing::DoAll;
47 using ::testing::Return;
48 using ::testing::SetArgPointee;
49 using ::testing::_;
50
51 const char kTrue[] = "true";
52 const char kDomain[] = "domain.com";
53 const char kUsername[] = "user@domain.com";
54 const char kUsernameOtherDomain[] = "user@other.com";
55 const char kAttributeOwned[] = "enterprise.owned";
56 const char kAttributeOwner[] = "enterprise.user";
57
58 const char kOAuthTokenCookie[] = "oauth_token=1234";
59 const char kOAuthGetAccessTokenData[] =
60 "oauth_token=1234&oauth_token_secret=1234";
61 const char kOAuthServiceTokenData[] =
62 "wrap_access_token=1234&wrap_access_token_expires_in=123456789";
63
64 const char kDMServer[] = "http://server/device_management";
65 const char kDMRegisterRequest[] =
66 "http://server/device_management?request=register";
67 const char kDMPolicyRequest[] =
68 "http://server/device_management?request=policy";
69
70 const char kDMToken[] = "1234";
71
72 ACTION_P(MockSessionManagerClientPolicyCallback, policy) {
73 arg0.Run(policy);
74 }
75
76 // Subclass IOThread to expose set_message_loop.
77 class TestIOThread : public IOThread {
78 public:
79 explicit TestIOThread(PrefService* local_state)
80 : IOThread(local_state, NULL, NULL) {}
81
82 using IOThread::set_message_loop;
83 };
84
85 template<typename TESTBASE>
86 class LoginUtilsTestBase : public TESTBASE,
87 public LoginUtils::Delegate,
88 public LoginStatusConsumer {
89 public:
90 LoginUtilsTestBase()
91 : loop_(MessageLoop::TYPE_IO),
92 browser_process_(
93 static_cast<TestingBrowserProcess*>(g_browser_process)),
94 local_state_(browser_process_),
95 ui_thread_(content::BrowserThread::UI, &loop_),
96 file_thread_(content::BrowserThread::FILE, &loop_),
97 io_thread_(local_state_.Get()),
98 prepared_profile_(NULL) {}
99
100 virtual void SetUp() OVERRIDE {
101 ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
102 // BrowserPolicyConnector makes the UserPolicyCache read relative to this
103 // path. Make sure it's in a clean state.
104 PathService::Override(chrome::DIR_USER_DATA, scoped_temp_dir_.path());
105
106 CommandLine* command_line = CommandLine::ForCurrentProcess();
107 command_line->AppendSwitch(switches::kEnableDevicePolicy);
108 command_line->AppendSwitchASCII(switches::kDeviceManagementUrl, kDMServer);
109 command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
110
111 local_state_.Get()->RegisterStringPref(prefs::kApplicationLocale, "");
112
113 browser_process_->SetIOThread(&io_thread_);
114
115 DBusThreadManager::InitializeForTesting(&dbus_thread_manager_);
116
117 MockSessionManagerClient* session_managed_client =
118 dbus_thread_manager_.mock_session_manager_client();
119 EXPECT_CALL(*session_managed_client, RetrievePolicy(_))
120 .WillRepeatedly(MockSessionManagerClientPolicyCallback(""));
121
122 CrosLibrary::TestApi* test_api = CrosLibrary::Get()->GetTestApi();
123 ASSERT_TRUE(test_api);
124
125 MockLibraryLoader* loader = new MockLibraryLoader();
126 ON_CALL(*loader, Load(_)).WillByDefault(Return(true));
127 test_api->SetLibraryLoader(loader, true);
128
129 cryptohome_ = new MockCryptohomeLibrary();
130 EXPECT_CALL(*cryptohome_, InstallAttributesIsReady())
131 .WillRepeatedly(Return(true));
132 EXPECT_CALL(*cryptohome_, InstallAttributesIsInvalid())
133 .WillRepeatedly(Return(false));
134 EXPECT_CALL(*cryptohome_, InstallAttributesIsFirstInstall())
135 .WillRepeatedly(Return(true));
136 EXPECT_CALL(*cryptohome_, TpmIsEnabled())
137 .WillRepeatedly(Return(false));
138 EXPECT_CALL(*cryptohome_, IsMounted())
139 .WillRepeatedly(Return(true));
140 EXPECT_CALL(*cryptohome_, InstallAttributesSet(kAttributeOwned, kTrue))
141 .WillRepeatedly(Return(true));
142 EXPECT_CALL(*cryptohome_, InstallAttributesSet(kAttributeOwner,
143 kUsername))
144 .WillRepeatedly(Return(true));
145 EXPECT_CALL(*cryptohome_, InstallAttributesFinalize())
146 .WillRepeatedly(Return(true));
147 EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttributeOwned, _))
148 .WillRepeatedly(DoAll(SetArgPointee<1>(kTrue),
149 Return(true)));
150 EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttributeOwner, _))
151 .WillRepeatedly(DoAll(SetArgPointee<1>(kUsername),
152 Return(true)));
153 test_api->SetCryptohomeLibrary(cryptohome_, true);
154
155 browser_process_->SetProfileManager(
156 new ProfileManagerWithoutInit(scoped_temp_dir_.path()));
157 connector_ = policy::BrowserPolicyConnector::Create();
158 browser_process_->SetBrowserPolicyConnector(connector_);
159
160 loop_.RunAllPending();
161 }
162
163 virtual void TearDown() OVERRIDE {
164 loop_.RunAllPending();
165 {
166 // chrome_browser_net::Predictor usually skips its shutdown routines on
167 // unit_tests, but does the full thing when
168 // g_browser_process->profile_manager() is valid during initialization.
169 // Run a task on a temporary BrowserThread::IO that allows skipping
170 // these routines.
171 io_thread_.set_message_loop(&loop_);
172 loop_.PostTask(FROM_HERE,
173 base::Bind(&LoginUtilsTestBase::TearDownOnIO,
174 base::Unretained(this)));
175 loop_.RunAllPending();
176 io_thread_.set_message_loop(NULL);
177 }
178
179 // These trigger some tasks that have to run while BrowserThread::UI
180 // exists.
181 connector_ = NULL;
182 browser_process_->SetBrowserPolicyConnector(NULL);
183 browser_process_->SetProfileManager(NULL);
184 loop_.RunAllPending();
185 }
186
187 void TearDownOnIO() {
188 std::vector<Profile*> profiles =
189 browser_process_->profile_manager()->GetLoadedProfiles();
190 for (size_t i = 0; i < profiles.size(); ++i) {
191 chrome_browser_net::Predictor* predictor =
192 profiles[i]->GetNetworkPredictor();
193 if (predictor) {
194 predictor->EnablePredictorOnIOThread(false);
195 predictor->Shutdown();
196 }
197 }
198 }
199
200 virtual void OnProfilePrepared(Profile* profile) OVERRIDE {
201 EXPECT_FALSE(prepared_profile_);
202 prepared_profile_ = profile;
203 }
204
205 virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE {
206 FAIL() << "OnLoginFailure not expected";
207 }
208
209 virtual void OnLoginSuccess(const std::string& username,
210 const std::string& password,
211 const GaiaAuthConsumer::ClientLoginResult& creds,
212 bool pending_requests,
213 bool using_oauth) OVERRIDE {
214 FAIL() << "OnLoginSuccess not expected";
215 }
216
217 void LockDevice(const std::string& username) {
218 EXPECT_CALL(*cryptohome_, InstallAttributesIsFirstInstall())
219 .WillOnce(Return(true))
220 .WillRepeatedly(Return(false));
221 EXPECT_EQ(policy::EnterpriseInstallAttributes::LOCK_SUCCESS,
222 connector_->LockDevice(username));
223 loop_.RunAllPending();
224 }
225
226 void PrepareProfile(const std::string& username) {
227 MockSessionManagerClient* session_managed_client =
228 dbus_thread_manager_.mock_session_manager_client();
229 EXPECT_CALL(*session_managed_client, StartSession(_));
230
231 // crypto::Encryptor::SetCounter wants exactly 128 bits, and
232 // ParallelAuthenticator CHECKs on that.
233 CryptohomeBlob blob;
234 for (size_t i = 0; i < 16; ++i)
235 blob.push_back(i);
236 EXPECT_CALL(*cryptohome_, GetSystemSalt())
237 .WillRepeatedly(Return(blob));
238 EXPECT_CALL(*cryptohome_, AsyncMount(_, _, _, _))
239 .WillRepeatedly(Return(true));
240
241 scoped_refptr<Authenticator> authenticator =
242 LoginUtils::Get()->CreateAuthenticator(this);
243 authenticator->CompleteLogin(ProfileManager::GetDefaultProfile(),
244 username,
245 "password");
246
247 GaiaAuthConsumer::ClientLoginResult credentials;
248 LoginUtils::Get()->PrepareProfile(
249 username, "password", credentials, false, true, false, this);
250 loop_.RunAllPending();
251 }
252
253 TestURLFetcher* PrepareOAuthFetcher(const std::string& expected_url) {
254 TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0);
255 EXPECT_TRUE(fetcher);
256 EXPECT_TRUE(fetcher->delegate());
257 EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(),
258 expected_url,
259 true));
260 fetcher->set_url(fetcher->GetOriginalURL());
261 fetcher->set_response_code(200);
262 fetcher->set_status(net::URLRequestStatus());
263 return fetcher;
264 }
265
266 TestURLFetcher* PrepareDMServiceFetcher(
267 const std::string& expected_url,
268 const em::DeviceManagementResponse& response) {
269 TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0);
270 EXPECT_TRUE(fetcher);
271 EXPECT_TRUE(fetcher->delegate());
272 EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(),
273 expected_url,
274 true));
275 fetcher->set_url(fetcher->GetOriginalURL());
276 fetcher->set_response_code(200);
277 fetcher->set_status(net::URLRequestStatus());
278 std::string data;
279 EXPECT_TRUE(response.SerializeToString(&data));
280 fetcher->SetResponseString(data);
281 return fetcher;
282 }
283
284 TestURLFetcher* PrepareDMRegisterFetcher() {
285 em::DeviceManagementResponse response;
286 em::DeviceRegisterResponse* register_response =
287 response.mutable_register_response();
288 register_response->set_device_management_token(kDMToken);
289 return PrepareDMServiceFetcher(kDMRegisterRequest, response);
290 }
291
292 TestURLFetcher* PrepareDMPolicyFetcher() {
293 em::DeviceManagementResponse response;
294 response.mutable_policy_response()->add_response();
295 return PrepareDMServiceFetcher(kDMPolicyRequest, response);
296 }
297
298 protected:
299 ScopedStubCrosEnabler stub_cros_enabler_;
300
301 MessageLoop loop_;
302 TestingBrowserProcess* browser_process_;
303 ScopedTestingLocalState local_state_;
304
305 content::TestBrowserThread ui_thread_;
306 content::TestBrowserThread file_thread_;
307 TestIOThread io_thread_;
308
309 MockDBusThreadManager dbus_thread_manager_;
310 TestURLFetcherFactory test_url_fetcher_factory_;
311
312 policy::BrowserPolicyConnector* connector_;
313 MockCryptohomeLibrary* cryptohome_;
314 Profile* prepared_profile_;
315
316 private:
317 ScopedTempDir scoped_temp_dir_;
318
319 DISALLOW_COPY_AND_ASSIGN(LoginUtilsTestBase);
320 };
321
322 class LoginUtilsTest : public LoginUtilsTestBase<testing::Test> {
323 };
324
325 class LoginUtilsBlockingLoginTest
326 : public LoginUtilsTestBase<testing::TestWithParam<int> > {
327 };
328
329 TEST_F(LoginUtilsTest, NormalLoginDoesntBlock) {
330 UserManager* user_manager = UserManager::Get();
331 EXPECT_FALSE(user_manager->user_is_logged_in());
332 EXPECT_FALSE(connector_->IsEnterpriseManaged());
333 EXPECT_FALSE(prepared_profile_);
334
335 // The profile will be created without waiting for a policy response.
336 PrepareProfile(kUsername);
337
338 EXPECT_TRUE(prepared_profile_);
339 EXPECT_TRUE(user_manager->user_is_logged_in());
340 EXPECT_EQ(kUsername, user_manager->logged_in_user().email());
341 }
342
343 TEST_F(LoginUtilsTest, EnterpriseLoginDoesntBlockForNormalUser) {
344 UserManager* user_manager = UserManager::Get();
345 EXPECT_FALSE(user_manager->user_is_logged_in());
346 EXPECT_FALSE(connector_->IsEnterpriseManaged());
347 EXPECT_FALSE(prepared_profile_);
348
349 // Enroll the device.
350 LockDevice(kUsername);
351
352 EXPECT_FALSE(user_manager->user_is_logged_in());
353 EXPECT_TRUE(connector_->IsEnterpriseManaged());
354 EXPECT_EQ(kDomain, connector_->GetEnterpriseDomain());
355 EXPECT_FALSE(prepared_profile_);
356
357 // Login with a non-enterprise user shouldn't block.
358 PrepareProfile(kUsernameOtherDomain);
359
360 EXPECT_TRUE(prepared_profile_);
361 EXPECT_TRUE(user_manager->user_is_logged_in());
362 EXPECT_EQ(kUsernameOtherDomain, user_manager->logged_in_user().email());
363 }
364
365 TEST_P(LoginUtilsBlockingLoginTest, EnterpriseLoginBlocksForEnterpriseUser) {
366 UserManager* user_manager = UserManager::Get();
367 EXPECT_FALSE(user_manager->user_is_logged_in());
368 EXPECT_FALSE(connector_->IsEnterpriseManaged());
369 EXPECT_FALSE(prepared_profile_);
370
371 // Enroll the device.
372 LockDevice(kUsername);
373
374 EXPECT_FALSE(user_manager->user_is_logged_in());
375 EXPECT_TRUE(connector_->IsEnterpriseManaged());
376 EXPECT_EQ(kDomain, connector_->GetEnterpriseDomain());
377 EXPECT_FALSE(prepared_profile_);
378
379 // Login with a user of the enterprise domain waits for policy.
380 PrepareProfile(kUsername);
381
382 EXPECT_FALSE(prepared_profile_);
383 EXPECT_TRUE(user_manager->user_is_logged_in());
384
385 GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
386 TestURLFetcher* fetcher;
387
388 // |steps| is the test parameter, and is the number of successful fetches.
389 // The first incomplete fetch will fail. In any case, the profile creation
390 // should resume.
391 int steps = GetParam();
392
393 do {
394 if (steps < 1) break;
395
396 // Fake OAuth token retrieval:
397 fetcher = PrepareOAuthFetcher(gaia_urls->get_oauth_token_url());
398 net::ResponseCookies cookies;
399 cookies.push_back(kOAuthTokenCookie);
400 fetcher->set_cookies(cookies);
401 fetcher->delegate()->OnURLFetchComplete(fetcher);
402 if (steps < 2) break;
403
404 // Fake OAuth access token retrieval:
405 fetcher = PrepareOAuthFetcher(gaia_urls->oauth_get_access_token_url());
406 fetcher->SetResponseString(kOAuthGetAccessTokenData);
407 fetcher->delegate()->OnURLFetchComplete(fetcher);
408 if (steps < 3) break;
409
410 // Fake OAuth service token retrieval:
411 fetcher = PrepareOAuthFetcher(gaia_urls->oauth_wrap_bridge_url());
412 fetcher->SetResponseString(kOAuthServiceTokenData);
413 fetcher->delegate()->OnURLFetchComplete(fetcher);
414
415 // The cloud policy subsystem is now ready to fetch the dmtoken and the user
416 // policy.
417 loop_.RunAllPending();
418 if (steps < 4) break;
419
420 fetcher = PrepareDMRegisterFetcher();
421 fetcher->delegate()->OnURLFetchComplete(fetcher);
422 // The policy fetch job has now been scheduled, run it:
423 loop_.RunAllPending();
424 if (steps < 5) break;
425
426 // Verify that there is no profile prepared just before the policy fetch.
427 EXPECT_FALSE(prepared_profile_);
428
429 fetcher = PrepareDMPolicyFetcher();
430 fetcher->delegate()->OnURLFetchComplete(fetcher);
431 } while (0);
432
433 if (steps < 5) {
434 // Verify that the profile hasn't been created yet.
435 EXPECT_FALSE(prepared_profile_);
436
437 // Make the current fetcher fail.
438 TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0);
439 EXPECT_TRUE(fetcher);
440 EXPECT_TRUE(fetcher->delegate());
441 fetcher->set_url(fetcher->GetOriginalURL());
442 fetcher->set_response_code(500);
443 fetcher->delegate()->OnURLFetchComplete(fetcher);
444 }
445
446 // The profile is finally ready:
447 EXPECT_TRUE(prepared_profile_);
448 }
449
450 INSTANTIATE_TEST_CASE_P(
451 LoginUtilsBlockingLoginTestInstance,
452 LoginUtilsBlockingLoginTest,
453 testing::Values(0, 1, 2, 3, 4, 5));
454
455 } // namespace
456
457 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698