base::Time multiplicative operator overloading
[chromium-blink-merge.git] / chrome / browser / signin / signin_manager_unittest.cc
blob22fb797a2320c17d6c7c622c2e2a02db806a0083
1 // Copyright (c) 2012 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 "components/signin/core/browser/signin_manager.h"
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/compiler_specific.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/prefs/testing_pref_service.h"
14 #include "base/run_loop.h"
15 #include "base/strings/stringprintf.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/chrome_notification_types.h"
18 #include "chrome/browser/prefs/browser_prefs.h"
19 #include "chrome/browser/signin/account_tracker_service_factory.h"
20 #include "chrome/browser/signin/chrome_signin_client_factory.h"
21 #include "chrome/browser/signin/fake_account_tracker_service.h"
22 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
23 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
24 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
25 #include "chrome/browser/signin/signin_manager_factory.h"
26 #include "chrome/browser/signin/test_signin_client_builder.h"
27 #include "chrome/common/pref_names.h"
28 #include "chrome/common/url_constants.h"
29 #include "chrome/test/base/testing_browser_process.h"
30 #include "chrome/test/base/testing_profile.h"
31 #include "components/signin/core/browser/profile_oauth2_token_service.h"
32 #include "components/signin/core/browser/test_signin_client.h"
33 #include "content/public/browser/child_process_security_policy.h"
34 #include "content/public/browser/notification_source.h"
35 #include "content/public/test/test_browser_thread_bundle.h"
36 #include "google_apis/gaia/gaia_constants.h"
37 #include "google_apis/gaia/gaia_urls.h"
38 #include "net/cookies/cookie_monster.h"
39 #include "net/url_request/test_url_fetcher_factory.h"
40 #include "net/url_request/url_request.h"
41 #include "net/url_request/url_request_context_getter.h"
42 #include "net/url_request/url_request_status.h"
44 #include "testing/gmock/include/gmock/gmock.h"
45 #include "testing/gtest/include/gtest/gtest.h"
47 namespace {
49 KeyedService* SigninManagerBuild(content::BrowserContext* context) {
50 SigninManager* service = NULL;
51 Profile* profile = static_cast<Profile*>(context);
52 service = new SigninManager(
53 ChromeSigninClientFactory::GetInstance()->GetForProfile(profile),
54 ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
55 AccountTrackerServiceFactory::GetForProfile(profile));
56 service->Initialize(NULL);
57 return service;
60 class TestSigninManagerObserver : public SigninManagerBase::Observer {
61 public:
62 TestSigninManagerObserver() : num_failed_signins_(0),
63 num_successful_signins_(0),
64 num_signouts_(0) {
67 ~TestSigninManagerObserver() override {}
69 int num_failed_signins_;
70 int num_successful_signins_;
71 int num_signouts_;
73 private:
74 // SigninManagerBase::Observer:
75 void GoogleSigninFailed(const GoogleServiceAuthError& error) override {
76 num_failed_signins_++;
79 void GoogleSigninSucceeded(const std::string& account_id,
80 const std::string& username,
81 const std::string& password) override {
82 num_successful_signins_++;
85 void GoogleSignedOut(const std::string& account_id,
86 const std::string& username) override {
87 num_signouts_++;
91 } // namespace
94 class SigninManagerTest : public testing::Test {
95 public:
96 SigninManagerTest() : manager_(NULL) {}
97 ~SigninManagerTest() override {}
99 void SetUp() override {
100 manager_ = NULL;
101 prefs_.reset(new TestingPrefServiceSimple);
102 chrome::RegisterLocalState(prefs_->registry());
103 TestingBrowserProcess::GetGlobal()->SetLocalState(
104 prefs_.get());
105 TestingProfile::Builder builder;
106 builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
107 BuildFakeProfileOAuth2TokenService);
108 builder.AddTestingFactory(ChromeSigninClientFactory::GetInstance(),
109 signin::BuildTestSigninClient);
110 builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
111 SigninManagerBuild);
112 builder.AddTestingFactory(AccountTrackerServiceFactory::GetInstance(),
113 FakeAccountTrackerService::Build);
114 profile_ = builder.Build();
116 signin_client()->SetURLRequestContext(profile_->GetRequestContext());
119 void TearDown() override {
120 if (manager_)
121 manager_->RemoveObserver(&test_observer_);
123 // Destroy the SigninManager here, because it relies on profile() which is
124 // freed in the base class.
125 if (naked_manager_) {
126 naked_manager_->Shutdown();
127 naked_manager_.reset(NULL);
129 TestingBrowserProcess::GetGlobal()->SetLocalState(NULL);
131 // Manually destroy PrefService and Profile so that they are shutdown
132 // in the correct order. Both need to be destroyed before the
133 // |thread_bundle_| member.
134 profile_.reset();
135 prefs_.reset(); // LocalState needs to outlive the profile.
138 TestingProfile* profile() { return profile_.get(); }
140 TestSigninClient* signin_client() {
141 return static_cast<TestSigninClient*>(
142 ChromeSigninClientFactory::GetInstance()->GetForProfile(profile()));
145 // Sets up the signin manager as a service if other code will try to get it as
146 // a PKS.
147 void SetUpSigninManagerAsService() {
148 DCHECK(!manager_);
149 DCHECK(!naked_manager_);
150 manager_ = static_cast<SigninManager*>(
151 SigninManagerFactory::GetForProfile(profile()));
152 manager_->AddObserver(&test_observer_);
155 // Create a naked signin manager if integration with PKSs is not needed.
156 void CreateNakedSigninManager() {
157 DCHECK(!manager_);
158 naked_manager_.reset(new SigninManager(
159 ChromeSigninClientFactory::GetInstance()->GetForProfile(profile()),
160 ProfileOAuth2TokenServiceFactory::GetForProfile(profile()),
161 AccountTrackerServiceFactory::GetForProfile(profile())));
163 manager_ = naked_manager_.get();
164 manager_->AddObserver(&test_observer_);
167 // Shuts down |manager_|.
168 void ShutDownManager() {
169 DCHECK(manager_);
170 manager_->RemoveObserver(&test_observer_);
171 manager_->Shutdown();
172 if (naked_manager_)
173 naked_manager_.reset(NULL);
174 manager_ = NULL;
177 void ExpectSignInWithRefreshTokenSuccess() {
178 EXPECT_TRUE(manager_->IsAuthenticated());
180 ProfileOAuth2TokenService* token_service =
181 ProfileOAuth2TokenServiceFactory::GetForProfile(profile());
182 EXPECT_TRUE(token_service->RefreshTokenIsAvailable(
183 manager_->GetAuthenticatedUsername()));
185 // Should go into token service and stop.
186 EXPECT_EQ(1, test_observer_.num_successful_signins_);
187 EXPECT_EQ(0, test_observer_.num_failed_signins_);
190 void CompleteSigninCallback(const std::string& oauth_token) {
191 oauth_tokens_fetched_.push_back(oauth_token);
192 manager_->CompletePendingSignin();
195 content::TestBrowserThreadBundle thread_bundle_;
196 net::TestURLFetcherFactory factory_;
197 scoped_ptr<SigninManager> naked_manager_;
198 SigninManager* manager_;
199 TestSigninManagerObserver test_observer_;
200 scoped_ptr<TestingProfile> profile_;
201 std::vector<std::string> oauth_tokens_fetched_;
202 scoped_ptr<TestingPrefServiceSimple> prefs_;
203 std::vector<std::string> cookies_;
206 TEST_F(SigninManagerTest, SignInWithRefreshToken) {
207 SetUpSigninManagerAsService();
208 EXPECT_FALSE(manager_->IsAuthenticated());
210 manager_->StartSignInWithRefreshToken(
211 "rt1",
212 "user@gmail.com",
213 "password",
214 SigninManager::OAuthTokenFetchedCallback());
216 ExpectSignInWithRefreshTokenSuccess();
218 // Should persist across resets.
219 ShutDownManager();
220 CreateNakedSigninManager();
221 manager_->Initialize(NULL);
222 EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedUsername());
225 TEST_F(SigninManagerTest, SignInWithRefreshTokenCallbackComplete) {
226 SetUpSigninManagerAsService();
227 EXPECT_FALSE(manager_->IsAuthenticated());
229 // Since the password is empty, must verify the gaia cookies first.
230 SigninManager::OAuthTokenFetchedCallback callback =
231 base::Bind(&SigninManagerTest::CompleteSigninCallback,
232 base::Unretained(this));
233 manager_->StartSignInWithRefreshToken(
234 "rt1",
235 "user@gmail.com",
236 "password",
237 callback);
239 ExpectSignInWithRefreshTokenSuccess();
240 ASSERT_EQ(1U, oauth_tokens_fetched_.size());
241 EXPECT_EQ(oauth_tokens_fetched_[0], "rt1");
244 TEST_F(SigninManagerTest, SignInWithRefreshTokenCallsPostSignout) {
245 SetUpSigninManagerAsService();
246 EXPECT_FALSE(manager_->IsAuthenticated());
248 std::string gaia_id = "12345";
249 std::string email = "user@google.com";
251 FakeAccountTrackerService* account_tracker_service =
252 static_cast<FakeAccountTrackerService*>(
253 AccountTrackerServiceFactory::GetForProfile(profile()));
254 account_tracker_service->SeedAccountInfo(gaia_id, email);
255 account_tracker_service->EnableNetworkFetches();
256 std::string account_id = account_tracker_service->PickAccountIdForAccount(
257 gaia_id, email);
259 ASSERT_TRUE(signin_client()->get_signed_in_password().empty());
261 manager_->StartSignInWithRefreshToken(
262 "rt1",
263 email,
264 "password",
265 SigninManager::OAuthTokenFetchedCallback());
267 // PostSignedIn is not called until the AccountTrackerService returns.
268 ASSERT_EQ("", signin_client()->get_signed_in_password());
270 account_tracker_service->FakeUserInfoFetchSuccess(
271 account_id, email, gaia_id, "google.com");
273 // AccountTracker and SigninManager are both done and PostSignedIn was called.
274 ASSERT_EQ("password", signin_client()->get_signed_in_password());
276 ExpectSignInWithRefreshTokenSuccess();
280 TEST_F(SigninManagerTest, SignOut) {
281 SetUpSigninManagerAsService();
282 manager_->StartSignInWithRefreshToken(
283 "rt1",
284 "user@gmail.com",
285 "password",
286 SigninManager::OAuthTokenFetchedCallback());
287 manager_->SignOut(signin_metrics::SIGNOUT_TEST);
288 EXPECT_FALSE(manager_->IsAuthenticated());
289 // Should not be persisted anymore
290 ShutDownManager();
291 CreateNakedSigninManager();
292 manager_->Initialize(NULL);
293 EXPECT_FALSE(manager_->IsAuthenticated());
296 TEST_F(SigninManagerTest, SignOutWhileProhibited) {
297 SetUpSigninManagerAsService();
298 EXPECT_FALSE(manager_->IsAuthenticated());
300 manager_->SetAuthenticatedUsername("user@gmail.com");
301 manager_->ProhibitSignout(true);
302 manager_->SignOut(signin_metrics::SIGNOUT_TEST);
303 EXPECT_TRUE(manager_->IsAuthenticated());
304 manager_->ProhibitSignout(false);
305 manager_->SignOut(signin_metrics::SIGNOUT_TEST);
306 EXPECT_FALSE(manager_->IsAuthenticated());
309 TEST_F(SigninManagerTest, TestIsWebBasedSigninFlowURL) {
310 EXPECT_FALSE(SigninManager::IsWebBasedSigninFlowURL(
311 GURL("http://www.google.com")));
312 EXPECT_TRUE(SigninManager::IsWebBasedSigninFlowURL(
313 GURL("https://accounts.google.com/ServiceLogin?service=chromiumsync")));
314 EXPECT_FALSE(SigninManager::IsWebBasedSigninFlowURL(
315 GURL("http://accounts.google.com/ServiceLogin?service=chromiumsync")));
316 // http, not https, should not be treated as web based signin.
317 EXPECT_FALSE(SigninManager::IsWebBasedSigninFlowURL(
318 GURL("http://accounts.google.com/ServiceLogin?service=googlemail")));
319 // chromiumsync is double-embedded in a continue query param.
320 EXPECT_TRUE(SigninManager::IsWebBasedSigninFlowURL(
321 GURL("https://accounts.google.com/CheckCookie?"
322 "continue=https%3A%2F%2Fwww.google.com%2Fintl%2Fen-US%2Fchrome"
323 "%2Fblank.html%3Fsource%3D3%26nonadv%3D1&service=chromiumsync")));
326 TEST_F(SigninManagerTest, Prohibited) {
327 g_browser_process->local_state()->SetString(
328 prefs::kGoogleServicesUsernamePattern, ".*@google.com");
329 CreateNakedSigninManager();
330 manager_->Initialize(g_browser_process->local_state());
331 EXPECT_TRUE(manager_->IsAllowedUsername("test@google.com"));
332 EXPECT_TRUE(manager_->IsAllowedUsername("happy@google.com"));
333 EXPECT_FALSE(manager_->IsAllowedUsername("test@invalid.com"));
334 EXPECT_FALSE(manager_->IsAllowedUsername("test@notgoogle.com"));
335 EXPECT_FALSE(manager_->IsAllowedUsername(std::string()));
338 TEST_F(SigninManagerTest, TestAlternateWildcard) {
339 // Test to make sure we accept "*@google.com" as a pattern (treat it as if
340 // the admin entered ".*@google.com").
341 g_browser_process->local_state()->SetString(
342 prefs::kGoogleServicesUsernamePattern, "*@google.com");
343 CreateNakedSigninManager();
344 manager_->Initialize(g_browser_process->local_state());
345 EXPECT_TRUE(manager_->IsAllowedUsername("test@google.com"));
346 EXPECT_TRUE(manager_->IsAllowedUsername("happy@google.com"));
347 EXPECT_FALSE(manager_->IsAllowedUsername("test@invalid.com"));
348 EXPECT_FALSE(manager_->IsAllowedUsername("test@notgoogle.com"));
349 EXPECT_FALSE(manager_->IsAllowedUsername(std::string()));
352 TEST_F(SigninManagerTest, ProhibitedAtStartup) {
353 profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
354 "monkey@invalid.com");
355 g_browser_process->local_state()->SetString(
356 prefs::kGoogleServicesUsernamePattern, ".*@google.com");
357 CreateNakedSigninManager();
358 manager_->Initialize(g_browser_process->local_state());
359 // Currently signed in user is prohibited by policy, so should be signed out.
360 EXPECT_EQ("", manager_->GetAuthenticatedUsername());
363 TEST_F(SigninManagerTest, ProhibitedAfterStartup) {
364 std::string user("monkey@invalid.com");
365 profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername, user);
366 CreateNakedSigninManager();
367 manager_->Initialize(g_browser_process->local_state());
368 EXPECT_EQ(user, manager_->GetAuthenticatedUsername());
369 // Update the profile - user should be signed out.
370 g_browser_process->local_state()->SetString(
371 prefs::kGoogleServicesUsernamePattern, ".*@google.com");
372 EXPECT_EQ("", manager_->GetAuthenticatedUsername());
375 TEST_F(SigninManagerTest, ExternalSignIn) {
376 CreateNakedSigninManager();
377 manager_->Initialize(g_browser_process->local_state());
378 EXPECT_EQ("",
379 profile()->GetPrefs()->GetString(prefs::kGoogleServicesUsername));
380 EXPECT_EQ("", manager_->GetAuthenticatedUsername());
381 EXPECT_EQ(0, test_observer_.num_successful_signins_);
383 manager_->OnExternalSigninCompleted("external@example.com");
384 EXPECT_EQ(1, test_observer_.num_successful_signins_);
385 EXPECT_EQ(0, test_observer_.num_failed_signins_);
386 EXPECT_EQ("external@example.com",
387 profile()->GetPrefs()->GetString(prefs::kGoogleServicesUsername));
388 EXPECT_EQ("external@example.com", manager_->GetAuthenticatedUsername());
391 TEST_F(SigninManagerTest, SigninNotAllowed) {
392 std::string user("user@google.com");
393 profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername, user);
394 profile()->GetPrefs()->SetBoolean(prefs::kSigninAllowed, false);
395 SetUpSigninManagerAsService();