| OLD | NEW |
| (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 |
| OLD | NEW |