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

Side by Side Diff: chrome/browser/chromeos/login/oauth1_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/oauth1_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/chrome_switches.h"
17 #include "chrome/common/pref_names.h"
18 #include "content/public/browser/notification_service.h"
19 #include "google_apis/gaia/gaia_auth_fetcher.h"
20 #include "google_apis/gaia/gaia_constants.h"
21 #include "net/url_request/url_request_context_getter.h"
22
23 namespace chromeos {
24
25 OAuth1LoginManager::OAuth1LoginManager(
26 OAuthLoginManager::Delegate* delegate)
27 : OAuthLoginManager(delegate) {
28 }
29
30 OAuth1LoginManager::~OAuth1LoginManager() {
31 }
32
33 void OAuth1LoginManager::RestoreSession(
34 Profile* user_profile,
35 net::URLRequestContextGetter* auth_request_context,
36 bool restore_from_auth_cookies) {
37 user_profile_ = user_profile;
38 auth_request_context_ = auth_request_context;
39 state_ = OAuthLoginManager::SESSION_RESTORE_IN_PROGRESS;
40
41 // Reuse the access token fetched by the PolicyOAuthFetcher, if it was
42 // used to fetch policies before Profile creation.
43 if (policy_oauth_fetcher_.get() &&
44 !policy_oauth_fetcher_->oauth1_token().empty()) {
45 VLOG(1) << "Resuming profile creation after fetching policy token";
46 oauth1_token_ = policy_oauth_fetcher_->oauth1_token();
47 oauth1_secret_ = policy_oauth_fetcher_->oauth1_secret();
48 StoreOAuth1Tokens();
49 restore_from_auth_cookies = false;
50 }
51 restore_from_auth_cookies_ = restore_from_auth_cookies;
52 ContinueSessionRestore();
53 }
54
55 void OAuth1LoginManager::ContinueSessionRestore() {
56 // Have we even started session restore?
57 if (!user_profile_)
58 return;
59
60 if (restore_from_auth_cookies_) {
61 DCHECK(auth_request_context_.get());
62 // If we don't have it, fetch OAuth1 access token.
63 // Once we get that, we will kick off individual requests for OAuth2
64 // tokens for all our services.
65 // Use off-the-record profile that was used for this step. It should
66 // already contain all needed cookies that will let us skip GAIA's user
67 // authentication UI.
68 oauth1_token_fetcher_.reset(
69 new OAuth1TokenFetcher(this, auth_request_context_));
70 oauth1_token_fetcher_->Start();
71 } else if (ReadOAuth1Tokens()) {
72 // Verify OAuth access token when we find it in the profile and always if
73 // if we don't have cookies.
74 // TODO(xiyuan): Change back to use authenticator to verify token when
75 // we support Gaia in lock screen.
76 VerifyOAuth1AccessToken();
77 } else {
78 UserManager::Get()->SaveUserOAuthStatus(
79 UserManager::Get()->GetLoggedInUser()->email(),
80 User::OAUTH1_TOKEN_STATUS_INVALID);
81 }
82 }
83
84 void OAuth1LoginManager::RestorePolicyTokens(
85 net::URLRequestContextGetter* auth_request_context) {
86 DCHECK(!policy_oauth_fetcher_.get());
87 policy_oauth_fetcher_.reset(
88 new PolicyOAuthFetcher(auth_request_context));
89 policy_oauth_fetcher_->Start();
90 }
91
92 void OAuth1LoginManager::Stop() {
93 oauth1_token_fetcher_.reset();
94 oauth1_login_verifier_.reset();
95 state_ = OAuthLoginManager::SESSION_RESTORE_NOT_STARTED;
96 }
97
98 void OAuth1LoginManager::VerifyOAuth1AccessToken() {
99 // Kick off verification of OAuth1 access token (via OAuthLogin), this should
100 // let us fetch credentials that will be used to initialize sync engine.
101 FetchCredentialsWithOAuth1();
102 delegate_->OnFoundStoredTokens();
103 FetchPolicyTokens();
104 }
105
106 void OAuth1LoginManager::FetchPolicyTokens() {
107 if (!policy_oauth_fetcher_.get() || policy_oauth_fetcher_->failed()) {
108 // Trigger oauth token fetch for user policy.
109 policy_oauth_fetcher_.reset(
110 new PolicyOAuthFetcher(g_browser_process->system_request_context(),
111 oauth1_token_,
112 oauth1_secret_));
113 policy_oauth_fetcher_->Start();
114 }
115 }
116
117 void OAuth1LoginManager::FetchCredentialsWithOAuth1() {
118 oauth1_login_verifier_.reset(
119 new OAuth1LoginVerifier(this,
120 user_profile_->GetRequestContext(),
121 oauth1_token_,
122 oauth1_secret_,
123 UserManager::Get()->GetLoggedInUser()->email()));
124 oauth1_login_verifier_->StartOAuthVerification();
125 }
126
127 void OAuth1LoginManager::OnOAuth1AccessTokenAvailable(
128 const std::string& token,
129 const std::string& secret) {
130 LOG(INFO) << "OAuth1 access token fetch succeeded.";
131 oauth1_token_ = token;
132 oauth1_secret_ = secret;
133 StoreOAuth1Tokens();
134 // Verify OAuth1 token by doing OAuthLogin and fetching credentials. If we
135 // have just transfered auth cookies out of authenticated cookie jar, there
136 // is no need to try to mint them from OAuth token again.
137 VerifyOAuth1AccessToken();
138 }
139
140 void OAuth1LoginManager::OnOAuth1AccessTokenFetchFailed() {
141 LOG(ERROR) << "OAuth1 access token fetch failed!";
142 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
143 g_browser_process->browser_policy_connector()->RegisterForUserPolicy(
144 EmptyString());
145 }
146
147 void OAuth1LoginManager::OnOAuth1VerificationSucceeded(
148 const std::string& user_name, const std::string& sid,
149 const std::string& lsid, const std::string& auth) {
150 LOG(INFO) << "OAuth1 token verification succeeded";
151 // Kick off sync engine.
152 GaiaAuthConsumer::ClientLoginResult credentials(sid, lsid, auth,
153 std::string());
154 TokenService* token_service =
155 TokenServiceFactory::GetForProfile(user_profile_);
156 token_service->UpdateCredentials(credentials);
157 CompleteAuthentication();
158 }
159
160 void OAuth1LoginManager::OnOAuth1VerificationFailed(
161 const std::string& user_name) {
162 LOG(ERROR) << "OAuth1 token verification failed!";
163 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
164 UserManager::Get()->SaveUserOAuthStatus(user_name,
165 User::OAUTH1_TOKEN_STATUS_INVALID);
166 }
167
168 bool OAuth1LoginManager::ReadOAuth1Tokens() {
169 // Skip reading oauth token if user does not have a valid status.
170 if (UserManager::Get()->IsUserLoggedIn() &&
171 UserManager::Get()->GetLoggedInUser()->oauth_token_status() !=
172 User::OAUTH1_TOKEN_STATUS_VALID) {
173 return false;
174 }
175
176 PrefService* pref_service = user_profile_->GetPrefs();
177 std::string encoded_token = pref_service->GetString(prefs::kOAuth1Token);
178 std::string encoded_secret = pref_service->GetString(prefs::kOAuth1Secret);
179 if (!encoded_token.length() || !encoded_secret.length())
180 return false;
181
182 std::string decoded_token =
183 CrosLibrary::Get()->GetCertLibrary()->DecryptToken(encoded_token);
184 std::string decoded_secret =
185 CrosLibrary::Get()->GetCertLibrary()->DecryptToken(encoded_secret);
186
187 if (!decoded_token.length() || !decoded_secret.length())
188 return false;
189
190 oauth1_token_ = decoded_token;
191 oauth1_secret_ = decoded_secret;
192 return true;
193 }
194
195 void OAuth1LoginManager::StoreOAuth1Tokens() {
196 DCHECK(!oauth1_token_.empty());
197 DCHECK(!oauth1_secret_.empty());
198 // First store OAuth1 token + service for the current user profile...
199 std::string encrypted_token =
200 CrosLibrary::Get()->GetCertLibrary()->EncryptToken(oauth1_token_);
201 std::string encrypted_secret =
202 CrosLibrary::Get()->GetCertLibrary()->EncryptToken(oauth1_secret_);
203
204 PrefService* pref_service = user_profile_->GetPrefs();
205 User* user = UserManager::Get()->GetLoggedInUser();
206 if (!encrypted_token.empty() && !encrypted_secret.empty()) {
207 pref_service->SetString(prefs::kOAuth1Token, encrypted_token);
208 pref_service->SetString(prefs::kOAuth1Secret, encrypted_secret);
209
210 // ...then record the presence of valid OAuth token for this account in
211 // local state as well.
212 UserManager::Get()->SaveUserOAuthStatus(
213 user->email(), User::OAUTH1_TOKEN_STATUS_VALID);
214 } else {
215 LOG(INFO) << "Failed to get OAuth1 token/secret encrypted.";
216 // Set the OAuth status invalid so that the user will go through full
217 // GAIA login next time.
218 UserManager::Get()->SaveUserOAuthStatus(
219 user->email(), User::OAUTH1_TOKEN_STATUS_INVALID);
220 }
221 }
222
223 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698