c49673aaf59a72394fb71c409e07cea0fc171686
[platform/framework/web/crosswalk.git] / src / chrome / browser / signin / signin_manager_unittest.cc
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.
4
5 #include "components/signin/core/browser/signin_manager.h"
6
7 #include <vector>
8
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/chrome_signin_client_factory.h"
20 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
21 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
22 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
23 #include "chrome/browser/signin/signin_manager_factory.h"
24 #include "chrome/common/pref_names.h"
25 #include "chrome/common/url_constants.h"
26 #include "chrome/test/base/testing_browser_process.h"
27 #include "chrome/test/base/testing_profile.h"
28 #include "components/signin/core/browser/profile_oauth2_token_service.h"
29 #include "content/public/browser/child_process_security_policy.h"
30 #include "content/public/browser/notification_source.h"
31 #include "content/public/test/test_browser_thread_bundle.h"
32 #include "google_apis/gaia/gaia_constants.h"
33 #include "google_apis/gaia/gaia_urls.h"
34 #include "net/cookies/cookie_monster.h"
35 #include "net/url_request/test_url_fetcher_factory.h"
36 #include "net/url_request/url_request.h"
37 #include "net/url_request/url_request_context_getter.h"
38 #include "net/url_request/url_request_status.h"
39
40 #include "testing/gmock/include/gmock/gmock.h"
41 #include "testing/gtest/include/gtest/gtest.h"
42
43 namespace {
44
45 KeyedService* SigninManagerBuild(content::BrowserContext* context) {
46   SigninManager* service = NULL;
47   Profile* profile = static_cast<Profile*>(context);
48   service = new SigninManager(
49       ChromeSigninClientFactory::GetInstance()->GetForProfile(profile),
50       ProfileOAuth2TokenServiceFactory::GetForProfile(profile));
51   service->Initialize(NULL);
52   return service;
53 }
54
55 class TestSigninManagerObserver : public SigninManagerBase::Observer {
56  public:
57   TestSigninManagerObserver() : num_failed_signins_(0),
58                                 num_successful_signins_(0),
59                                 num_signouts_(0) {
60   }
61
62   virtual ~TestSigninManagerObserver() {}
63
64   int num_failed_signins_;
65   int num_successful_signins_;
66   int num_signouts_;
67
68  private:
69   // SigninManagerBase::Observer:
70   virtual void GoogleSigninFailed(
71       const GoogleServiceAuthError& error) OVERRIDE {
72     num_failed_signins_++;
73   }
74
75   virtual void GoogleSigninSucceeded(
76       const std::string& username, const std::string& password) OVERRIDE {
77     num_successful_signins_++;
78   }
79
80   virtual void GoogleSignedOut(const std::string& username) OVERRIDE {
81     num_signouts_++;
82   }
83 };
84
85 }  // namespace
86
87
88 class SigninManagerTest : public testing::Test {
89  public:
90   SigninManagerTest() : manager_(NULL) {}
91   virtual ~SigninManagerTest() {}
92
93   virtual void SetUp() OVERRIDE {
94     manager_ = NULL;
95     prefs_.reset(new TestingPrefServiceSimple);
96     chrome::RegisterLocalState(prefs_->registry());
97     TestingBrowserProcess::GetGlobal()->SetLocalState(
98         prefs_.get());
99     TestingProfile::Builder builder;
100     builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
101                               BuildFakeProfileOAuth2TokenService);
102     builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
103                               SigninManagerBuild);
104     profile_ = builder.Build();
105   }
106
107   virtual void TearDown() OVERRIDE {
108     if (manager_)
109       manager_->RemoveObserver(&test_observer_);
110
111     // Destroy the SigninManager here, because it relies on profile() which is
112     // freed in the base class.
113     if (naked_manager_) {
114       naked_manager_->Shutdown();
115       naked_manager_.reset(NULL);
116     }
117     TestingBrowserProcess::GetGlobal()->SetLocalState(NULL);
118
119     // Manually destroy PrefService and Profile so that they are shutdown
120     // in the correct order.  Both need to be destroyed before the
121     // |thread_bundle_| member.
122     profile_.reset();
123     prefs_.reset();  // LocalState needs to outlive the profile.
124   }
125
126   TestingProfile* profile() { return profile_.get(); }
127
128   // Sets up the signin manager as a service if other code will try to get it as
129   // a PKS.
130   void SetUpSigninManagerAsService() {
131     DCHECK(!manager_);
132     DCHECK(!naked_manager_);
133     manager_ = static_cast<SigninManager*>(
134         SigninManagerFactory::GetForProfile(profile()));
135     manager_->AddObserver(&test_observer_);
136   }
137
138   // Create a naked signin manager if integration with PKSs is not needed.
139   void CreateNakedSigninManager() {
140     DCHECK(!manager_);
141     naked_manager_.reset(new SigninManager(
142         ChromeSigninClientFactory::GetInstance()->GetForProfile(profile()),
143         ProfileOAuth2TokenServiceFactory::GetForProfile(profile())));
144
145     manager_ = naked_manager_.get();
146     manager_->AddObserver(&test_observer_);
147   }
148
149   // Shuts down |manager_|.
150   void ShutDownManager() {
151     DCHECK(manager_);
152     manager_->RemoveObserver(&test_observer_);
153     manager_->Shutdown();
154     if (naked_manager_)
155       naked_manager_.reset(NULL);
156     manager_ = NULL;
157   }
158
159   void ExpectSignInWithRefreshTokenSuccess() {
160     EXPECT_FALSE(manager_->GetAuthenticatedUsername().empty());
161
162     ProfileOAuth2TokenService* token_service =
163         ProfileOAuth2TokenServiceFactory::GetForProfile(profile());
164     EXPECT_TRUE(token_service->RefreshTokenIsAvailable(
165         manager_->GetAuthenticatedUsername()));
166
167     // Should go into token service and stop.
168     EXPECT_EQ(1, test_observer_.num_successful_signins_);
169     EXPECT_EQ(0, test_observer_.num_failed_signins_);
170   }
171
172   void CompleteSigninCallback(const std::string& oauth_token) {
173     oauth_tokens_fetched_.push_back(oauth_token);
174     manager_->CompletePendingSignin();
175   }
176
177   content::TestBrowserThreadBundle thread_bundle_;
178   net::TestURLFetcherFactory factory_;
179   scoped_ptr<SigninManager> naked_manager_;
180   SigninManager* manager_;
181   TestSigninManagerObserver test_observer_;
182   scoped_ptr<TestingProfile> profile_;
183   std::vector<std::string> oauth_tokens_fetched_;
184   scoped_ptr<TestingPrefServiceSimple> prefs_;
185   std::vector<std::string> cookies_;
186 };
187
188 TEST_F(SigninManagerTest, SignInWithRefreshToken) {
189   SetUpSigninManagerAsService();
190   EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());
191
192   manager_->StartSignInWithRefreshToken(
193       "rt1",
194       "user@gmail.com",
195       "password",
196       SigninManager::OAuthTokenFetchedCallback());
197
198   ExpectSignInWithRefreshTokenSuccess();
199
200   // Should persist across resets.
201   ShutDownManager();
202   CreateNakedSigninManager();
203   manager_->Initialize(NULL);
204   EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedUsername());
205 }
206
207 TEST_F(SigninManagerTest, SignInWithRefreshTokenCallbackComplete) {
208   SetUpSigninManagerAsService();
209   EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());
210
211   // Since the password is empty, must verify the gaia cookies first.
212   SigninManager::OAuthTokenFetchedCallback callback =
213       base::Bind(&SigninManagerTest::CompleteSigninCallback,
214                  base::Unretained(this));
215   manager_->StartSignInWithRefreshToken(
216       "rt1",
217       "user@gmail.com",
218       "password",
219       callback);
220
221   ExpectSignInWithRefreshTokenSuccess();
222   ASSERT_EQ(1U, oauth_tokens_fetched_.size());
223   EXPECT_EQ(oauth_tokens_fetched_[0], "rt1");
224 }
225
226 TEST_F(SigninManagerTest, SignOut) {
227   SetUpSigninManagerAsService();
228   manager_->StartSignInWithRefreshToken(
229       "rt1",
230       "user@gmail.com",
231       "password",
232       SigninManager::OAuthTokenFetchedCallback());
233   manager_->SignOut();
234   EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());
235   // Should not be persisted anymore
236   ShutDownManager();
237   CreateNakedSigninManager();
238   manager_->Initialize(NULL);
239   EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());
240 }
241
242 TEST_F(SigninManagerTest, SignOutWhileProhibited) {
243   SetUpSigninManagerAsService();
244   EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());
245
246   manager_->SetAuthenticatedUsername("user@gmail.com");
247   manager_->ProhibitSignout(true);
248   manager_->SignOut();
249   EXPECT_FALSE(manager_->GetAuthenticatedUsername().empty());
250   manager_->ProhibitSignout(false);
251   manager_->SignOut();
252   EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());
253 }
254
255 TEST_F(SigninManagerTest, TestIsWebBasedSigninFlowURL) {
256   EXPECT_FALSE(SigninManager::IsWebBasedSigninFlowURL(
257       GURL("http://www.google.com")));
258   EXPECT_TRUE(SigninManager::IsWebBasedSigninFlowURL(
259       GURL("https://accounts.google.com/ServiceLogin?service=chromiumsync")));
260   EXPECT_FALSE(SigninManager::IsWebBasedSigninFlowURL(
261       GURL("http://accounts.google.com/ServiceLogin?service=chromiumsync")));
262   // http, not https, should not be treated as web based signin.
263   EXPECT_FALSE(SigninManager::IsWebBasedSigninFlowURL(
264       GURL("http://accounts.google.com/ServiceLogin?service=googlemail")));
265   // chromiumsync is double-embedded in a continue query param.
266   EXPECT_TRUE(SigninManager::IsWebBasedSigninFlowURL(
267       GURL("https://accounts.google.com/CheckCookie?"
268            "continue=https%3A%2F%2Fwww.google.com%2Fintl%2Fen-US%2Fchrome"
269            "%2Fblank.html%3Fsource%3D3%26nonadv%3D1&service=chromiumsync")));
270 }
271
272 TEST_F(SigninManagerTest, Prohibited) {
273   g_browser_process->local_state()->SetString(
274       prefs::kGoogleServicesUsernamePattern, ".*@google.com");
275   CreateNakedSigninManager();
276   manager_->Initialize(g_browser_process->local_state());
277   EXPECT_TRUE(manager_->IsAllowedUsername("test@google.com"));
278   EXPECT_TRUE(manager_->IsAllowedUsername("happy@google.com"));
279   EXPECT_FALSE(manager_->IsAllowedUsername("test@invalid.com"));
280   EXPECT_FALSE(manager_->IsAllowedUsername("test@notgoogle.com"));
281   EXPECT_FALSE(manager_->IsAllowedUsername(std::string()));
282 }
283
284 TEST_F(SigninManagerTest, TestAlternateWildcard) {
285   // Test to make sure we accept "*@google.com" as a pattern (treat it as if
286   // the admin entered ".*@google.com").
287   g_browser_process->local_state()->SetString(
288       prefs::kGoogleServicesUsernamePattern, "*@google.com");
289   CreateNakedSigninManager();
290   manager_->Initialize(g_browser_process->local_state());
291   EXPECT_TRUE(manager_->IsAllowedUsername("test@google.com"));
292   EXPECT_TRUE(manager_->IsAllowedUsername("happy@google.com"));
293   EXPECT_FALSE(manager_->IsAllowedUsername("test@invalid.com"));
294   EXPECT_FALSE(manager_->IsAllowedUsername("test@notgoogle.com"));
295   EXPECT_FALSE(manager_->IsAllowedUsername(std::string()));
296 }
297
298 TEST_F(SigninManagerTest, ProhibitedAtStartup) {
299   profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
300                                    "monkey@invalid.com");
301   g_browser_process->local_state()->SetString(
302       prefs::kGoogleServicesUsernamePattern, ".*@google.com");
303   CreateNakedSigninManager();
304   manager_->Initialize(g_browser_process->local_state());
305   // Currently signed in user is prohibited by policy, so should be signed out.
306   EXPECT_EQ("", manager_->GetAuthenticatedUsername());
307 }
308
309 TEST_F(SigninManagerTest, ProhibitedAfterStartup) {
310   std::string user("monkey@invalid.com");
311   profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername, user);
312   CreateNakedSigninManager();
313   manager_->Initialize(g_browser_process->local_state());
314   EXPECT_EQ(user, manager_->GetAuthenticatedUsername());
315   // Update the profile - user should be signed out.
316   g_browser_process->local_state()->SetString(
317       prefs::kGoogleServicesUsernamePattern, ".*@google.com");
318   EXPECT_EQ("", manager_->GetAuthenticatedUsername());
319 }
320
321 TEST_F(SigninManagerTest, ExternalSignIn) {
322   CreateNakedSigninManager();
323   manager_->Initialize(g_browser_process->local_state());
324   EXPECT_EQ("",
325             profile()->GetPrefs()->GetString(prefs::kGoogleServicesUsername));
326   EXPECT_EQ("", manager_->GetAuthenticatedUsername());
327   EXPECT_EQ(0, test_observer_.num_successful_signins_);
328
329   manager_->OnExternalSigninCompleted("external@example.com");
330   EXPECT_EQ(1, test_observer_.num_successful_signins_);
331   EXPECT_EQ(0, test_observer_.num_failed_signins_);
332   EXPECT_EQ("external@example.com",
333             profile()->GetPrefs()->GetString(prefs::kGoogleServicesUsername));
334   EXPECT_EQ("external@example.com", manager_->GetAuthenticatedUsername());
335 }
336
337 TEST_F(SigninManagerTest, SigninNotAllowed) {
338   std::string user("user@google.com");
339   profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername, user);
340   profile()->GetPrefs()->SetBoolean(prefs::kSigninAllowed, false);
341   SetUpSigninManagerAsService();
342 }