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

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

Issue 11649055: OAuth2 sign-in flow for ChromeOS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: clang fix Created 7 years, 11 months 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) 2013 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/oauth2_login_manager.h"
6
7 #include "base/string_util.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/chromeos/login/user_manager.h"
10 #include "chrome/browser/policy/browser_policy_connector.h"
11 #include "chrome/browser/prefs/pref_service.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/signin/token_service.h"
14 #include "chrome/browser/signin/token_service_factory.h"
15 #include "chrome/common/chrome_notification_types.h"
16 #include "chrome/common/pref_names.h"
17 #include "content/public/browser/notification_service.h"
18 #include "google_apis/gaia/gaia_constants.h"
19 #include "net/url_request/url_request_context_getter.h"
20
21 namespace chromeos {
22
23 OAuth2LoginManager::OAuth2LoginManager(OAuthLoginManager::Delegate* delegate)
24 : OAuthLoginManager(delegate),
25 loading_reported_(false) {
26 }
27
28 OAuth2LoginManager::~OAuth2LoginManager() {
29 }
30
31 void OAuth2LoginManager::RestoreSession(
32 Profile* user_profile,
33 net::URLRequestContextGetter* auth_request_context,
34 bool restore_from_auth_cookies) {
35 user_profile_ = user_profile;
36 auth_request_context_ = auth_request_context;
37 state_ = OAuthLoginManager::SESSION_RESTORE_IN_PROGRESS;
38
39 // TODO(zelidrag): Remove eventually the next line in some future milestone.
40 RemoveLegacyTokens();
41
42 // Reuse the access token fetched by the OAuth2PolicyFetcher, if it was
43 // used to fetch policies before Profile creation.
44 if (oauth2_policy_fetcher_.get() &&
45 oauth2_policy_fetcher_->has_oauth2_tokens()) {
46 VLOG(1) << "Resuming profile creation after fetching policy token";
47 refresh_token_ = oauth2_policy_fetcher_->oauth2_tokens().refresh_token;
48 restore_from_auth_cookies = false;
49 }
50 restore_from_auth_cookies_ = restore_from_auth_cookies;
51 ContinueSessionRestore();
52 }
53
54 void OAuth2LoginManager::ContinueSessionRestore() {
55 if (restore_from_auth_cookies_) {
56 FetchOAuth2Tokens();
57 return;
58 }
59
60 // Did we already fetch the refresh token (either policy or db)?
61 if (!refresh_token_.empty()) {
62 // TODO(zelidrag): Figure out where to stick that refresh_token_ into.
63 // We probalby need bit more than that.
64 }
65 LoadAndVerifyOAuth2Tokens();
66 }
67
68 void OAuth2LoginManager::RestorePolicyTokens(
69 net::URLRequestContextGetter* auth_request_context) {
70 oauth2_policy_fetcher_.reset(
71 new OAuth2PolicyFetcher(auth_request_context,
72 g_browser_process->system_request_context()));
73 oauth2_policy_fetcher_->Start();
74 }
75
76 void OAuth2LoginManager::Stop() {
77 oauth2_token_fetcher_.reset();
78 login_verifier_.reset();
79 }
80
81 TokenService* OAuth2LoginManager::SetupTokenService() {
82 TokenService* token_service =
83 TokenServiceFactory::GetForProfile(user_profile_);
84 if (registrar_.IsEmpty()) {
85 registrar_.Add(this,
86 chrome::NOTIFICATION_TOKEN_LOADING_FINISHED,
87 content::Source<TokenService>(token_service));
88 registrar_.Add(this,
89 chrome::NOTIFICATION_TOKEN_AVAILABLE,
90 content::Source<TokenService>(token_service));
91 }
92 return token_service;
93 }
94
95 void OAuth2LoginManager::RemoveLegacyTokens() {
96 PrefServiceSyncable* prefs = user_profile_->GetPrefs();
97 prefs->RegisterStringPref(prefs::kOAuth1Token,
98 "",
99 PrefServiceSyncable::UNSYNCABLE_PREF);
100 prefs->RegisterStringPref(prefs::kOAuth1Secret,
101 "",
102 PrefServiceSyncable::UNSYNCABLE_PREF);
103 prefs->ClearPref(prefs::kOAuth1Token);
104 prefs->ClearPref(prefs::kOAuth1Secret);
105 prefs->UnregisterPreference(prefs::kOAuth1Token);
106 prefs->UnregisterPreference(prefs::kOAuth1Secret);
107 }
108
109 void OAuth2LoginManager::LoadAndVerifyOAuth2Tokens() {
110 // If we have no cookies, try to load saved OAuth2 token from TokenService.
111 TokenService* token_service = SetupTokenService();
112 token_service->Initialize(GaiaConstants::kChromeSource, user_profile_);
113 token_service->LoadTokensFromDB();
114 }
115
116 void OAuth2LoginManager::FetchOAuth2Tokens() {
117 DCHECK(auth_request_context_.get());
118 // If we have authenticated cookie jar, get OAuth1 token first, then fetch
119 // SID/LSID cookies through OAuthLogin call.
120 oauth2_token_fetcher_.reset(
121 new OAuth2TokenFetcher(this, auth_request_context_));
122 oauth2_token_fetcher_->Start();
123 }
124
125 void OAuth2LoginManager::OnOAuth2TokensAvailable(
126 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) {
127 LOG(INFO) << "OAuth2 tokens fetched";
128 TokenService* token_service = SetupTokenService();
129 token_service->UpdateCredentialsWithOAuth2(oauth2_tokens);
130 }
131
132 void OAuth2LoginManager::OnOAuth2TokensFetchFailed() {
133 LOG(ERROR) << "OAuth2 tokens fetch failed!";
134 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
135 UserManager::Get()->SaveUserOAuthStatus(
136 UserManager::Get()->GetLoggedInUser()->email(),
137 User::OAUTH2_TOKEN_STATUS_INVALID);
138 }
139
140 void OAuth2LoginManager::Observe(
141 int type,
142 const content::NotificationSource& source,
143 const content::NotificationDetails& details) {
144 TokenService* token_service =
145 TokenServiceFactory::GetForProfile(user_profile_);
146 switch (type) {
147 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: {
148 refresh_token_ = token_service->GetOAuth2LoginRefreshToken();
149 gaia_token_.clear();
150 // TODO(zelidrag): Figure out why just getting GaiaConstants::kGaiaService
151 // token does not do the trick here.
152 RestoreSessionCookies();
153 break;
154 }
155 case chrome::NOTIFICATION_TOKEN_AVAILABLE: {
156 // This path should kick on only when we mint a new OAuth2 refresh
157 // token for user cookies. Otherwise, wait for all tokens to load above.
158 if (!restore_from_auth_cookies_)
159 return;
160
161 TokenService::TokenAvailableDetails* token_details =
162 content::Details<TokenService::TokenAvailableDetails>(
163 details).ptr();
164 if (token_details->service() ==
165 GaiaConstants::kGaiaOAuth2LoginRefreshToken) {
166 DCHECK(!login_verifier_.get());
167 refresh_token_ = token_details->token();
168 gaia_token_.clear();
169 RestoreSessionCookies();
170 }
171 break;
172 }
173 default:
174 NOTREACHED();
175 break;
176 }
177 }
178
179 void OAuth2LoginManager::RestoreSessionCookies() {
180 if (refresh_token_.empty()) {
181 LOG(ERROR) << "OAuth2 refresh token is empty!";
182 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
183 UserManager::Get()->SaveUserOAuthStatus(
184 UserManager::Get()->GetLoggedInUser()->email(),
185 User::OAUTH2_TOKEN_STATUS_INVALID);
186 return;
187 }
188
189 DCHECK(!login_verifier_.get());
190 login_verifier_.reset(
191 new OAuth2LoginVerifier(this,
192 g_browser_process->system_request_context(),
193 user_profile_->GetRequestContext()));
194 login_verifier_->VerifyTokens(refresh_token_, gaia_token_);
195 FetchPolicyTokens();
196 }
197
198 void OAuth2LoginManager::FetchPolicyTokens() {
199 DCHECK(!refresh_token_.empty());
200 if (!oauth2_policy_fetcher_.get() || oauth2_policy_fetcher_->failed()) {
201 // Trigger OAuth2 token fetch for user policy.
202 oauth2_policy_fetcher_.reset(
203 new OAuth2PolicyFetcher(g_browser_process->system_request_context(),
204 refresh_token_));
205 oauth2_policy_fetcher_->Start();
206 }
207 }
208 void OAuth2LoginManager::OnOAuthLoginSuccess(
209 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) {
210 LOG(INFO) << "OAuth2 refresh token successfully exchanged for GAIA token.";
211 StartTokenService(gaia_credentials);
212 }
213
214 void OAuth2LoginManager::OnOAuthLoginFailure() {
215 LOG(ERROR) << "OAuth2 refresh token verification failed!";
216 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
217 UserManager::Get()->SaveUserOAuthStatus(
218 UserManager::Get()->GetLoggedInUser()->email(),
219 User::OAUTH2_TOKEN_STATUS_INVALID);
220 }
221
222 void OAuth2LoginManager::OnSessionMergeSuccess() {
223 LOG(INFO) << "OAuth2 refresh and/or GAIA token verification succeeded.";
224 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
225 UserManager::Get()->SaveUserOAuthStatus(
226 UserManager::Get()->GetLoggedInUser()->email(),
227 User::OAUTH2_TOKEN_STATUS_VALID);
228 }
229
230 void OAuth2LoginManager::OnSessionMergeFailure() {
231 LOG(ERROR) << "OAuth2 refresh and GAIA token verification failed!";
232 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
233 UserManager::Get()->SaveUserOAuthStatus(
234 UserManager::Get()->GetLoggedInUser()->email(),
235 User::OAUTH2_TOKEN_STATUS_INVALID);
236 }
237
238 void OAuth2LoginManager::StartTokenService(
239 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) {
240 TokenService* token_service = SetupTokenService();
241 token_service->UpdateCredentials(gaia_credentials);
242 CompleteAuthentication();
243 }
244
245 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698