OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/sync/signin_manager.h" | 5 #include "chrome/browser/sync/signin_manager.h" |
6 | 6 |
| 7 #include "base/command_line.h" |
7 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "chrome/browser/sync/signin_manager_client_login.h" |
| 10 #include "chrome/browser/sync/signin_manager_oauth.h" |
8 #include "chrome/browser/net/gaia/token_service.h" | 11 #include "chrome/browser/net/gaia/token_service.h" |
9 #include "chrome/browser/prefs/pref_service.h" | 12 #include "chrome/browser/prefs/pref_service.h" |
10 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/common/chrome_switches.h" |
| 15 #include "chrome/common/net/gaia/gaia_auth_fetcher.h" |
11 #include "chrome/common/net/gaia/gaia_constants.h" | 16 #include "chrome/common/net/gaia/gaia_constants.h" |
| 17 #include "chrome/common/net/gaia/authentication_fetcher_oauth.h" |
12 #include "chrome/common/pref_names.h" | 18 #include "chrome/common/pref_names.h" |
13 #include "content/common/notification_service.h" | 19 #include "content/common/notification_service.h" |
14 | 20 |
15 const char kGetInfoEmailKey[] = "email"; | 21 const char kGetInfoEmailKey[] = "email"; |
16 | 22 |
| 23 // static |
| 24 const char* SigninManager::kClientLoginVariant = |
| 25 SigninManagerClientLogin::kSigninManagerVariantName; |
| 26 |
| 27 // static |
| 28 const char* SigninManager::kOAuthVariant = |
| 29 SigninManagerOAuth::kSigninManagerVariantName; |
| 30 |
17 SigninManager::SigninManager() | 31 SigninManager::SigninManager() |
18 : profile_(NULL), had_two_factor_error_(false) {} | 32 : profile_(NULL), had_two_factor_error_(false) {} |
19 | 33 |
20 SigninManager::~SigninManager() {} | 34 SigninManager::~SigninManager() {} |
21 | 35 |
22 // static | 36 // static |
| 37 SigninManager* |
| 38 SigninManager::CreateSigninManager() { |
| 39 return new SigninManagerClientLogin(); |
| 40 } |
| 41 |
| 42 // static |
| 43 SigninManager* |
| 44 SigninManager::CreateSigninManager(const std::string& variant) { |
| 45 if (variant == SigninManagerOAuth::kSigninManagerVariantName) |
| 46 return new SigninManagerOAuth(); |
| 47 if (variant == SigninManagerClientLogin::kSigninManagerVariantName) |
| 48 return new SigninManagerClientLogin(); |
| 49 NOTREACHED(); |
| 50 return CreateSigninManager(); |
| 51 } |
| 52 |
| 53 // static |
23 void SigninManager::RegisterUserPrefs(PrefService* user_prefs) { | 54 void SigninManager::RegisterUserPrefs(PrefService* user_prefs) { |
24 user_prefs->RegisterStringPref(prefs::kGoogleServicesUsername, ""); | 55 user_prefs->RegisterStringPref(prefs::kGoogleServicesUsername, ""); |
25 } | 56 } |
26 | 57 |
27 void SigninManager::Initialize(Profile* profile) { | |
28 profile_ = profile; | |
29 username_ = profile_->GetPrefs()->GetString(prefs::kGoogleServicesUsername); | |
30 profile_->GetTokenService()->Initialize( | |
31 GaiaConstants::kChromeSource, profile_); | |
32 if (!username_.empty()) { | |
33 profile_->GetTokenService()->LoadTokensFromDB(); | |
34 } | |
35 } | |
36 | |
37 // If a username already exists, the user is logged in. | 58 // If a username already exists, the user is logged in. |
38 const std::string& SigninManager::GetUsername() { | 59 const std::string& SigninManager::GetUsername() { |
39 return username_; | 60 return username_; |
40 } | 61 } |
41 | 62 |
42 void SigninManager::SetUsername(const std::string& username) { | 63 void SigninManager::SetUsername(const std::string& username) { |
43 username_ = username; | 64 username_ = username; |
44 } | 65 } |
45 | |
46 // Users must always sign out before they sign in again. | |
47 void SigninManager::StartSignIn(const std::string& username, | |
48 const std::string& password, | |
49 const std::string& login_token, | |
50 const std::string& login_captcha) { | |
51 DCHECK(username_.empty()); | |
52 #if !defined(OS_CHROMEOS) | |
53 // The Sign out should clear the token service credentials. | |
54 // Note: In CHROMEOS we might have valid credentials but still need to | |
55 // set up 2-factor authentication. | |
56 DCHECK(!profile_->GetTokenService()->AreCredentialsValid()); | |
57 #endif | |
58 username_.assign(username); | |
59 password_.assign(password); | |
60 | |
61 client_login_.reset(new GaiaAuthFetcher(this, | |
62 GaiaConstants::kChromeSource, | |
63 profile_->GetRequestContext())); | |
64 client_login_->StartClientLogin(username, | |
65 password, | |
66 "", | |
67 login_token, | |
68 login_captcha, | |
69 GaiaAuthFetcher::HostedAccountsNotAllowed); | |
70 } | |
71 | |
72 void SigninManager::ProvideSecondFactorAccessCode( | |
73 const std::string& access_code) { | |
74 DCHECK(!username_.empty() && !password_.empty() && | |
75 last_result_.data.empty()); | |
76 | |
77 client_login_.reset(new GaiaAuthFetcher(this, | |
78 GaiaConstants::kChromeSource, | |
79 profile_->GetRequestContext())); | |
80 client_login_->StartClientLogin(username_, | |
81 access_code, | |
82 "", | |
83 std::string(), | |
84 std::string(), | |
85 GaiaAuthFetcher::HostedAccountsNotAllowed); | |
86 } | |
87 | |
88 void SigninManager::SignOut() { | |
89 if (!profile_) | |
90 return; | |
91 | |
92 client_login_.reset(); | |
93 last_result_ = ClientLoginResult(); | |
94 username_.clear(); | |
95 password_.clear(); | |
96 had_two_factor_error_ = false; | |
97 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, username_); | |
98 profile_->GetPrefs()->ScheduleSavePersistentPrefs(); | |
99 profile_->GetTokenService()->ResetCredentialsInMemory(); | |
100 profile_->GetTokenService()->EraseTokensFromDB(); | |
101 } | |
102 | |
103 void SigninManager::OnClientLoginSuccess(const ClientLoginResult& result) { | |
104 last_result_ = result; | |
105 // Make a request for the canonical email address. | |
106 client_login_->StartGetUserInfo(result.lsid, kGetInfoEmailKey); | |
107 } | |
108 | |
109 void SigninManager::OnGetUserInfoSuccess(const std::string& key, | |
110 const std::string& value) { | |
111 DCHECK(key == kGetInfoEmailKey); | |
112 | |
113 username_ = value; | |
114 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, username_); | |
115 profile_->GetPrefs()->ScheduleSavePersistentPrefs(); | |
116 | |
117 GoogleServiceSigninSuccessDetails details(username_, password_); | |
118 NotificationService::current()->Notify( | |
119 NotificationType::GOOGLE_SIGNIN_SUCCESSFUL, | |
120 Source<Profile>(profile_), | |
121 Details<const GoogleServiceSigninSuccessDetails>(&details)); | |
122 | |
123 password_.clear(); // Don't need it anymore. | |
124 | |
125 profile_->GetTokenService()->UpdateCredentials(last_result_); | |
126 DCHECK(profile_->GetTokenService()->AreCredentialsValid()); | |
127 profile_->GetTokenService()->StartFetchingTokens(); | |
128 } | |
129 | |
130 void SigninManager::OnGetUserInfoKeyNotFound(const std::string& key) { | |
131 DCHECK(key == kGetInfoEmailKey); | |
132 LOG(ERROR) << "Account is not associated with a valid email address. " | |
133 << "Login failed."; | |
134 OnClientLoginFailure(GoogleServiceAuthError( | |
135 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); | |
136 } | |
137 | |
138 void SigninManager::OnGetUserInfoFailure(const GoogleServiceAuthError& error) { | |
139 LOG(ERROR) << "Unable to retreive the canonical email address. Login failed."; | |
140 OnClientLoginFailure(error); | |
141 } | |
142 | |
143 void SigninManager::OnClientLoginFailure(const GoogleServiceAuthError& error) { | |
144 NotificationService::current()->Notify( | |
145 NotificationType::GOOGLE_SIGNIN_FAILED, | |
146 Source<Profile>(profile_), | |
147 Details<const GoogleServiceAuthError>(&error)); | |
148 | |
149 // We don't sign-out if the password was valid and we're just dealing with | |
150 // a second factor error, and we don't sign out if we're dealing with | |
151 // an invalid access code (again, because the password was valid). | |
152 bool invalid_gaia = error.state() == | |
153 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS; | |
154 if (error.state() == GoogleServiceAuthError::TWO_FACTOR || | |
155 (had_two_factor_error_ && invalid_gaia)) { | |
156 had_two_factor_error_ = true; | |
157 return; | |
158 } | |
159 | |
160 SignOut(); | |
161 } | |
OLD | NEW |