| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/chromeos/settings/device_oauth2_token_service.h" | 5 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_delegate.
h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/memory/weak_ptr.h" | 12 #include "base/memory/weak_ptr.h" |
| 13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
| 14 #include "base/prefs/pref_registry_simple.h" | 14 #include "base/prefs/pref_registry_simple.h" |
| 15 #include "base/prefs/pref_service.h" | 15 #include "base/prefs/pref_service.h" |
| 16 #include "base/values.h" | 16 #include "base/values.h" |
| 17 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
| 18 #include "chrome/browser/chromeos/settings/token_encryptor.h" | 18 #include "chrome/browser/chromeos/settings/token_encryptor.h" |
| 19 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
| 20 #include "chromeos/cryptohome/system_salt_getter.h" | 20 #include "chromeos/cryptohome/system_salt_getter.h" |
| 21 #include "chromeos/settings/cros_settings_names.h" | 21 #include "chromeos/settings/cros_settings_names.h" |
| 22 #include "google_apis/gaia/gaia_constants.h" | 22 #include "google_apis/gaia/gaia_constants.h" |
| 23 #include "google_apis/gaia/gaia_urls.h" | 23 #include "google_apis/gaia/gaia_urls.h" |
| 24 #include "google_apis/gaia/google_service_auth_error.h" | 24 #include "google_apis/gaia/google_service_auth_error.h" |
| 25 #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h" | 25 #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h" |
| 26 #include "policy/proto/device_management_backend.pb.h" | 26 #include "policy/proto/device_management_backend.pb.h" |
| 27 | 27 |
| 28 namespace chromeos { | 28 namespace chromeos { |
| 29 | 29 |
| 30 struct DeviceOAuth2TokenService::PendingRequest { | 30 void DeviceOAuth2TokenServiceDelegate::OnServiceAccountIdentityChanged() { |
| 31 PendingRequest(const base::WeakPtr<RequestImpl>& request, | |
| 32 const std::string& client_id, | |
| 33 const std::string& client_secret, | |
| 34 const ScopeSet& scopes) | |
| 35 : request(request), | |
| 36 client_id(client_id), | |
| 37 client_secret(client_secret), | |
| 38 scopes(scopes) {} | |
| 39 | |
| 40 const base::WeakPtr<RequestImpl> request; | |
| 41 const std::string client_id; | |
| 42 const std::string client_secret; | |
| 43 const ScopeSet scopes; | |
| 44 }; | |
| 45 | |
| 46 void DeviceOAuth2TokenService::OnServiceAccountIdentityChanged() { | |
| 47 if (!GetRobotAccountId().empty() && !refresh_token_.empty()) | 31 if (!GetRobotAccountId().empty() && !refresh_token_.empty()) |
| 48 FireRefreshTokenAvailable(GetRobotAccountId()); | 32 FireRefreshTokenAvailable(GetRobotAccountId()); |
| 49 } | 33 } |
| 50 | 34 |
| 51 DeviceOAuth2TokenService::DeviceOAuth2TokenService( | 35 DeviceOAuth2TokenServiceDelegate::DeviceOAuth2TokenServiceDelegate( |
| 52 net::URLRequestContextGetter* getter, | 36 net::URLRequestContextGetter* getter, |
| 53 PrefService* local_state) | 37 PrefService* local_state) |
| 54 : url_request_context_getter_(getter), | 38 : url_request_context_getter_(getter), |
| 55 local_state_(local_state), | 39 local_state_(local_state), |
| 56 state_(STATE_LOADING), | 40 state_(STATE_LOADING), |
| 57 max_refresh_token_validation_retries_(3), | 41 max_refresh_token_validation_retries_(3), |
| 42 validation_requested_(false), |
| 43 validation_status_delegate_(nullptr), |
| 58 service_account_identity_subscription_( | 44 service_account_identity_subscription_( |
| 59 CrosSettings::Get()->AddSettingsObserver( | 45 CrosSettings::Get() |
| 60 kServiceAccountIdentity, | 46 ->AddSettingsObserver( |
| 61 base::Bind( | 47 kServiceAccountIdentity, |
| 62 &DeviceOAuth2TokenService::OnServiceAccountIdentityChanged, | 48 base::Bind(&DeviceOAuth2TokenServiceDelegate:: |
| 63 base::Unretained(this))).Pass()), | 49 OnServiceAccountIdentityChanged, |
| 50 base::Unretained(this))) |
| 51 .Pass()), |
| 64 weak_ptr_factory_(this) { | 52 weak_ptr_factory_(this) { |
| 65 // Pull in the system salt. | 53 // Pull in the system salt. |
| 66 SystemSaltGetter::Get()->GetSystemSalt( | 54 SystemSaltGetter::Get()->GetSystemSalt( |
| 67 base::Bind(&DeviceOAuth2TokenService::DidGetSystemSalt, | 55 base::Bind(&DeviceOAuth2TokenServiceDelegate::DidGetSystemSalt, |
| 68 weak_ptr_factory_.GetWeakPtr())); | 56 weak_ptr_factory_.GetWeakPtr())); |
| 69 } | 57 } |
| 70 | 58 |
| 71 DeviceOAuth2TokenService::~DeviceOAuth2TokenService() { | 59 DeviceOAuth2TokenServiceDelegate::~DeviceOAuth2TokenServiceDelegate() { |
| 72 FlushPendingRequests(false, GoogleServiceAuthError::REQUEST_CANCELED); | |
| 73 FlushTokenSaveCallbacks(false); | 60 FlushTokenSaveCallbacks(false); |
| 74 } | 61 } |
| 75 | 62 |
| 76 // static | 63 void DeviceOAuth2TokenServiceDelegate::SetAndSaveRefreshToken( |
| 77 void DeviceOAuth2TokenService::RegisterPrefs(PrefRegistrySimple* registry) { | |
| 78 registry->RegisterStringPref(prefs::kDeviceRobotAnyApiRefreshToken, | |
| 79 std::string()); | |
| 80 } | |
| 81 | |
| 82 void DeviceOAuth2TokenService::SetAndSaveRefreshToken( | |
| 83 const std::string& refresh_token, | 64 const std::string& refresh_token, |
| 84 const StatusCallback& result_callback) { | 65 const StatusCallback& result_callback) { |
| 85 FlushPendingRequests(false, GoogleServiceAuthError::REQUEST_CANCELED); | 66 if (validation_status_delegate_) { |
| 67 validation_status_delegate_->OnValidationCompleted( |
| 68 GoogleServiceAuthError::REQUEST_CANCELED); |
| 69 } |
| 86 | 70 |
| 87 bool waiting_for_salt = state_ == STATE_LOADING; | 71 bool waiting_for_salt = state_ == STATE_LOADING; |
| 88 refresh_token_ = refresh_token; | 72 refresh_token_ = refresh_token; |
| 89 state_ = STATE_VALIDATION_PENDING; | 73 state_ = STATE_VALIDATION_PENDING; |
| 90 | 74 |
| 91 // If the robot account ID is not available yet, do not announce the token. It | 75 // If the robot account ID is not available yet, do not announce the token. It |
| 92 // will be done from OnServiceAccountIdentityChanged() once the robot account | 76 // will be done from OnServiceAccountIdentityChanged() once the robot account |
| 93 // ID becomes available as well. | 77 // ID becomes available as well. |
| 94 if (!GetRobotAccountId().empty()) | 78 if (!GetRobotAccountId().empty()) |
| 95 FireRefreshTokenAvailable(GetRobotAccountId()); | 79 FireRefreshTokenAvailable(GetRobotAccountId()); |
| 96 | 80 |
| 97 token_save_callbacks_.push_back(result_callback); | 81 token_save_callbacks_.push_back(result_callback); |
| 98 if (!waiting_for_salt) { | 82 if (!waiting_for_salt) { |
| 99 if (system_salt_.empty()) | 83 if (system_salt_.empty()) |
| 100 FlushTokenSaveCallbacks(false); | 84 FlushTokenSaveCallbacks(false); |
| 101 else | 85 else |
| 102 EncryptAndSaveToken(); | 86 EncryptAndSaveToken(); |
| 103 } | 87 } |
| 104 } | 88 } |
| 105 | 89 |
| 106 bool DeviceOAuth2TokenService::RefreshTokenIsAvailable( | 90 bool DeviceOAuth2TokenServiceDelegate::RefreshTokenIsAvailable( |
| 107 const std::string& account_id) const { | 91 const std::string& account_id) const { |
| 108 switch (state_) { | 92 switch (state_) { |
| 109 case STATE_NO_TOKEN: | 93 case STATE_NO_TOKEN: |
| 110 case STATE_TOKEN_INVALID: | 94 case STATE_TOKEN_INVALID: |
| 111 return false; | 95 return false; |
| 112 case STATE_LOADING: | 96 case STATE_LOADING: |
| 113 case STATE_VALIDATION_PENDING: | 97 case STATE_VALIDATION_PENDING: |
| 114 case STATE_VALIDATION_STARTED: | 98 case STATE_VALIDATION_STARTED: |
| 115 case STATE_TOKEN_VALID: | 99 case STATE_TOKEN_VALID: |
| 116 return account_id == GetRobotAccountId(); | 100 return account_id == GetRobotAccountId(); |
| 117 } | 101 } |
| 118 | 102 |
| 119 NOTREACHED() << "Unhandled state " << state_; | 103 NOTREACHED() << "Unhandled state " << state_; |
| 120 return false; | 104 return false; |
| 121 } | 105 } |
| 122 | 106 |
| 123 std::string DeviceOAuth2TokenService::GetRobotAccountId() const { | 107 std::string DeviceOAuth2TokenServiceDelegate::GetRobotAccountId() const { |
| 124 std::string result; | 108 std::string result; |
| 125 CrosSettings::Get()->GetString(kServiceAccountIdentity, &result); | 109 CrosSettings::Get()->GetString(kServiceAccountIdentity, &result); |
| 126 return result; | 110 return result; |
| 127 } | 111 } |
| 128 | 112 |
| 129 void DeviceOAuth2TokenService::OnRefreshTokenResponse( | 113 void DeviceOAuth2TokenServiceDelegate::OnRefreshTokenResponse( |
| 130 const std::string& access_token, | 114 const std::string& access_token, |
| 131 int expires_in_seconds) { | 115 int expires_in_seconds) { |
| 132 gaia_oauth_client_->GetTokenInfo( | 116 gaia_oauth_client_->GetTokenInfo(access_token, |
| 133 access_token, | 117 max_refresh_token_validation_retries_, this); |
| 134 max_refresh_token_validation_retries_, | |
| 135 this); | |
| 136 } | 118 } |
| 137 | 119 |
| 138 void DeviceOAuth2TokenService::OnGetTokenInfoResponse( | 120 void DeviceOAuth2TokenServiceDelegate::OnGetTokenInfoResponse( |
| 139 scoped_ptr<base::DictionaryValue> token_info) { | 121 scoped_ptr<base::DictionaryValue> token_info) { |
| 140 std::string gaia_robot_id; | 122 std::string gaia_robot_id; |
| 141 token_info->GetString("email", &gaia_robot_id); | 123 token_info->GetString("email", &gaia_robot_id); |
| 142 gaia_oauth_client_.reset(); | 124 gaia_oauth_client_.reset(); |
| 143 | 125 |
| 144 CheckRobotAccountId(gaia_robot_id); | 126 CheckRobotAccountId(gaia_robot_id); |
| 145 } | 127 } |
| 146 | 128 |
| 147 void DeviceOAuth2TokenService::OnOAuthError() { | 129 void DeviceOAuth2TokenServiceDelegate::OnOAuthError() { |
| 148 gaia_oauth_client_.reset(); | 130 gaia_oauth_client_.reset(); |
| 149 state_ = STATE_TOKEN_INVALID; | 131 state_ = STATE_TOKEN_INVALID; |
| 150 FlushPendingRequests(false, GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); | 132 if (validation_status_delegate_) { |
| 133 validation_status_delegate_->OnValidationCompleted( |
| 134 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); |
| 135 } |
| 151 } | 136 } |
| 152 | 137 |
| 153 void DeviceOAuth2TokenService::OnNetworkError(int response_code) { | 138 void DeviceOAuth2TokenServiceDelegate::OnNetworkError(int response_code) { |
| 154 gaia_oauth_client_.reset(); | 139 gaia_oauth_client_.reset(); |
| 155 | 140 |
| 156 // Go back to pending validation state. That'll allow a retry on subsequent | 141 // Go back to pending validation state. That'll allow a retry on subsequent |
| 157 // token minting requests. | 142 // token minting requests. |
| 158 state_ = STATE_VALIDATION_PENDING; | 143 state_ = STATE_VALIDATION_PENDING; |
| 159 FlushPendingRequests(false, GoogleServiceAuthError::CONNECTION_FAILED); | 144 if (validation_status_delegate_) { |
| 145 validation_status_delegate_->OnValidationCompleted( |
| 146 GoogleServiceAuthError::CONNECTION_FAILED); |
| 147 } |
| 160 } | 148 } |
| 161 | 149 |
| 162 std::string DeviceOAuth2TokenService::GetRefreshToken( | 150 std::string DeviceOAuth2TokenServiceDelegate::GetRefreshToken( |
| 163 const std::string& account_id) const { | 151 const std::string& account_id) const { |
| 164 switch (state_) { | 152 switch (state_) { |
| 165 case STATE_LOADING: | 153 case STATE_LOADING: |
| 166 case STATE_NO_TOKEN: | 154 case STATE_NO_TOKEN: |
| 167 case STATE_TOKEN_INVALID: | 155 case STATE_TOKEN_INVALID: |
| 168 // This shouldn't happen: GetRefreshToken() is only called for actual | 156 // This shouldn't happen: GetRefreshToken() is only called for actual |
| 169 // token minting operations. In above states, requests are either queued | 157 // token minting operations. In above states, requests are either queued |
| 170 // or short-circuited to signal error immediately, so no actual token | 158 // or short-circuited to signal error immediately, so no actual token |
| 171 // minting via OAuth2TokenService::FetchOAuth2Token should be triggered. | 159 // minting via OAuth2TokenService::FetchOAuth2Token should be triggered. |
| 172 NOTREACHED(); | 160 NOTREACHED(); |
| 173 return std::string(); | 161 return std::string(); |
| 174 case STATE_VALIDATION_PENDING: | 162 case STATE_VALIDATION_PENDING: |
| 175 case STATE_VALIDATION_STARTED: | 163 case STATE_VALIDATION_STARTED: |
| 176 case STATE_TOKEN_VALID: | 164 case STATE_TOKEN_VALID: |
| 177 return refresh_token_; | 165 return refresh_token_; |
| 178 } | 166 } |
| 179 | 167 |
| 180 NOTREACHED() << "Unhandled state " << state_; | 168 NOTREACHED() << "Unhandled state " << state_; |
| 181 return std::string(); | 169 return std::string(); |
| 182 } | 170 } |
| 183 | 171 |
| 184 net::URLRequestContextGetter* DeviceOAuth2TokenService::GetRequestContext() { | 172 net::URLRequestContextGetter* |
| 173 DeviceOAuth2TokenServiceDelegate::GetRequestContext() const { |
| 185 return url_request_context_getter_.get(); | 174 return url_request_context_getter_.get(); |
| 186 } | 175 } |
| 187 | 176 |
| 188 void DeviceOAuth2TokenService::FetchOAuth2Token( | 177 OAuth2AccessTokenFetcher* |
| 189 RequestImpl* request, | 178 DeviceOAuth2TokenServiceDelegate::CreateAccessTokenFetcher( |
| 190 const std::string& account_id, | |
| 191 net::URLRequestContextGetter* getter, | |
| 192 const std::string& client_id, | |
| 193 const std::string& client_secret, | |
| 194 const ScopeSet& scopes) { | |
| 195 switch (state_) { | |
| 196 case STATE_VALIDATION_PENDING: | |
| 197 // If this is the first request for a token, start validation. | |
| 198 StartValidation(); | |
| 199 // fall through. | |
| 200 case STATE_LOADING: | |
| 201 case STATE_VALIDATION_STARTED: | |
| 202 // Add a pending request that will be satisfied once validation completes. | |
| 203 pending_requests_.push_back(new PendingRequest( | |
| 204 request->AsWeakPtr(), client_id, client_secret, scopes)); | |
| 205 return; | |
| 206 case STATE_NO_TOKEN: | |
| 207 FailRequest(request, GoogleServiceAuthError::USER_NOT_SIGNED_UP); | |
| 208 return; | |
| 209 case STATE_TOKEN_INVALID: | |
| 210 FailRequest(request, GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); | |
| 211 return; | |
| 212 case STATE_TOKEN_VALID: | |
| 213 // Pass through to OAuth2TokenService to satisfy the request. | |
| 214 OAuth2TokenService::FetchOAuth2Token( | |
| 215 request, account_id, getter, client_id, client_secret, scopes); | |
| 216 return; | |
| 217 } | |
| 218 | |
| 219 NOTREACHED() << "Unexpected state " << state_; | |
| 220 } | |
| 221 | |
| 222 OAuth2AccessTokenFetcher* DeviceOAuth2TokenService::CreateAccessTokenFetcher( | |
| 223 const std::string& account_id, | 179 const std::string& account_id, |
| 224 net::URLRequestContextGetter* getter, | 180 net::URLRequestContextGetter* getter, |
| 225 OAuth2AccessTokenConsumer* consumer) { | 181 OAuth2AccessTokenConsumer* consumer) { |
| 226 std::string refresh_token = GetRefreshToken(account_id); | 182 std::string refresh_token = GetRefreshToken(account_id); |
| 227 DCHECK(!refresh_token.empty()); | 183 DCHECK(!refresh_token.empty()); |
| 228 return new OAuth2AccessTokenFetcherImpl(consumer, getter, refresh_token); | 184 return new OAuth2AccessTokenFetcherImpl(consumer, getter, refresh_token); |
| 229 } | 185 } |
| 230 | 186 |
| 231 | 187 void DeviceOAuth2TokenServiceDelegate::DidGetSystemSalt( |
| 232 void DeviceOAuth2TokenService::DidGetSystemSalt( | |
| 233 const std::string& system_salt) { | 188 const std::string& system_salt) { |
| 234 system_salt_ = system_salt; | 189 system_salt_ = system_salt; |
| 235 | 190 |
| 236 // Bail out if system salt is not available. | 191 // Bail out if system salt is not available. |
| 237 if (system_salt_.empty()) { | 192 if (system_salt_.empty()) { |
| 238 LOG(ERROR) << "Failed to get system salt."; | 193 LOG(ERROR) << "Failed to get system salt."; |
| 239 FlushTokenSaveCallbacks(false); | 194 FlushTokenSaveCallbacks(false); |
| 240 state_ = STATE_NO_TOKEN; | 195 state_ = STATE_NO_TOKEN; |
| 241 FireRefreshTokensLoaded(); | 196 FireRefreshTokensLoaded(); |
| 242 return; | 197 return; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 259 LOG(ERROR) << "Failed to decrypt refresh token."; | 214 LOG(ERROR) << "Failed to decrypt refresh token."; |
| 260 state_ = STATE_NO_TOKEN; | 215 state_ = STATE_NO_TOKEN; |
| 261 FireRefreshTokensLoaded(); | 216 FireRefreshTokensLoaded(); |
| 262 return; | 217 return; |
| 263 } | 218 } |
| 264 } | 219 } |
| 265 | 220 |
| 266 state_ = STATE_VALIDATION_PENDING; | 221 state_ = STATE_VALIDATION_PENDING; |
| 267 | 222 |
| 268 // If there are pending requests, start a validation. | 223 // If there are pending requests, start a validation. |
| 269 if (!pending_requests_.empty()) | 224 if (validation_requested_) |
| 270 StartValidation(); | 225 StartValidation(); |
| 271 | 226 |
| 272 // Announce the token. | 227 // Announce the token. |
| 273 FireRefreshTokenAvailable(GetRobotAccountId()); | 228 FireRefreshTokenAvailable(GetRobotAccountId()); |
| 274 FireRefreshTokensLoaded(); | 229 FireRefreshTokensLoaded(); |
| 275 } | 230 } |
| 276 | 231 |
| 277 void DeviceOAuth2TokenService::CheckRobotAccountId( | 232 void DeviceOAuth2TokenServiceDelegate::CheckRobotAccountId( |
| 278 const std::string& gaia_robot_id) { | 233 const std::string& gaia_robot_id) { |
| 279 // Make sure the value returned by GetRobotAccountId has been validated | 234 // Make sure the value returned by GetRobotAccountId has been validated |
| 280 // against current device settings. | 235 // against current device settings. |
| 281 switch (CrosSettings::Get()->PrepareTrustedValues(base::Bind( | 236 switch (CrosSettings::Get()->PrepareTrustedValues( |
| 282 &DeviceOAuth2TokenService::CheckRobotAccountId, | 237 base::Bind(&DeviceOAuth2TokenServiceDelegate::CheckRobotAccountId, |
| 283 weak_ptr_factory_.GetWeakPtr(), | 238 weak_ptr_factory_.GetWeakPtr(), gaia_robot_id))) { |
| 284 gaia_robot_id))) { | |
| 285 case CrosSettingsProvider::TRUSTED: | 239 case CrosSettingsProvider::TRUSTED: |
| 286 // All good, compare account ids below. | 240 // All good, compare account ids below. |
| 287 break; | 241 break; |
| 288 case CrosSettingsProvider::TEMPORARILY_UNTRUSTED: | 242 case CrosSettingsProvider::TEMPORARILY_UNTRUSTED: |
| 289 // The callback passed to PrepareTrustedValues above will trigger a | 243 // The callback passed to PrepareTrustedValues above will trigger a |
| 290 // re-check eventually. | 244 // re-check eventually. |
| 291 return; | 245 return; |
| 292 case CrosSettingsProvider::PERMANENTLY_UNTRUSTED: | 246 case CrosSettingsProvider::PERMANENTLY_UNTRUSTED: |
| 293 // There's no trusted account id, which is equivalent to no token present. | 247 // There's no trusted account id, which is equivalent to no token present. |
| 294 LOG(WARNING) << "Device settings permanently untrusted."; | 248 LOG(WARNING) << "Device settings permanently untrusted."; |
| 295 state_ = STATE_NO_TOKEN; | 249 state_ = STATE_NO_TOKEN; |
| 296 FlushPendingRequests(false, GoogleServiceAuthError::USER_NOT_SIGNED_UP); | 250 if (validation_status_delegate_) { |
| 251 validation_status_delegate_->OnValidationCompleted( |
| 252 GoogleServiceAuthError::USER_NOT_SIGNED_UP); |
| 253 } |
| 297 return; | 254 return; |
| 298 } | 255 } |
| 299 | 256 |
| 300 std::string policy_robot_id = GetRobotAccountId(); | 257 std::string policy_robot_id = GetRobotAccountId(); |
| 301 if (policy_robot_id == gaia_robot_id) { | 258 if (policy_robot_id == gaia_robot_id) { |
| 302 state_ = STATE_TOKEN_VALID; | 259 state_ = STATE_TOKEN_VALID; |
| 303 FlushPendingRequests(true, GoogleServiceAuthError::NONE); | 260 if (validation_status_delegate_) { |
| 261 validation_status_delegate_->OnValidationCompleted( |
| 262 GoogleServiceAuthError::NONE); |
| 263 } |
| 304 } else { | 264 } else { |
| 305 if (gaia_robot_id.empty()) { | 265 if (gaia_robot_id.empty()) { |
| 306 LOG(WARNING) << "Device service account owner in policy is empty."; | 266 LOG(WARNING) << "Device service account owner in policy is empty."; |
| 307 } else { | 267 } else { |
| 308 LOG(WARNING) << "Device service account owner in policy does not match " | 268 LOG(WARNING) << "Device service account owner in policy does not match " |
| 309 << "refresh token owner \"" << gaia_robot_id << "\"."; | 269 << "refresh token owner \"" << gaia_robot_id << "\"."; |
| 310 } | 270 } |
| 311 state_ = STATE_TOKEN_INVALID; | 271 state_ = STATE_TOKEN_INVALID; |
| 312 FlushPendingRequests(false, | 272 if (validation_status_delegate_) { |
| 313 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); | 273 validation_status_delegate_->OnValidationCompleted( |
| 274 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); |
| 275 } |
| 314 } | 276 } |
| 315 } | 277 } |
| 316 | 278 |
| 317 void DeviceOAuth2TokenService::EncryptAndSaveToken() { | 279 void DeviceOAuth2TokenServiceDelegate::EncryptAndSaveToken() { |
| 318 DCHECK_NE(state_, STATE_LOADING); | 280 DCHECK_NE(state_, STATE_LOADING); |
| 319 | 281 |
| 320 CryptohomeTokenEncryptor encryptor(system_salt_); | 282 CryptohomeTokenEncryptor encryptor(system_salt_); |
| 321 std::string encrypted_refresh_token = | 283 std::string encrypted_refresh_token = |
| 322 encryptor.EncryptWithSystemSalt(refresh_token_); | 284 encryptor.EncryptWithSystemSalt(refresh_token_); |
| 323 bool result = true; | 285 bool result = true; |
| 324 if (encrypted_refresh_token.empty()) { | 286 if (encrypted_refresh_token.empty()) { |
| 325 LOG(ERROR) << "Failed to encrypt refresh token; save aborted."; | 287 LOG(ERROR) << "Failed to encrypt refresh token; save aborted."; |
| 326 result = false; | 288 result = false; |
| 327 } else { | 289 } else { |
| 328 local_state_->SetString(prefs::kDeviceRobotAnyApiRefreshToken, | 290 local_state_->SetString(prefs::kDeviceRobotAnyApiRefreshToken, |
| 329 encrypted_refresh_token); | 291 encrypted_refresh_token); |
| 330 } | 292 } |
| 331 | 293 |
| 332 FlushTokenSaveCallbacks(result); | 294 FlushTokenSaveCallbacks(result); |
| 333 } | 295 } |
| 334 | 296 |
| 335 void DeviceOAuth2TokenService::StartValidation() { | 297 void DeviceOAuth2TokenServiceDelegate::StartValidation() { |
| 336 DCHECK_EQ(state_, STATE_VALIDATION_PENDING); | 298 DCHECK_EQ(state_, STATE_VALIDATION_PENDING); |
| 337 DCHECK(!gaia_oauth_client_); | 299 DCHECK(!gaia_oauth_client_); |
| 338 | 300 |
| 339 state_ = STATE_VALIDATION_STARTED; | 301 state_ = STATE_VALIDATION_STARTED; |
| 340 | 302 |
| 341 gaia_oauth_client_.reset(new gaia::GaiaOAuthClient( | 303 gaia_oauth_client_.reset( |
| 342 g_browser_process->system_request_context())); | 304 new gaia::GaiaOAuthClient(g_browser_process->system_request_context())); |
| 343 | 305 |
| 344 GaiaUrls* gaia_urls = GaiaUrls::GetInstance(); | 306 GaiaUrls* gaia_urls = GaiaUrls::GetInstance(); |
| 345 gaia::OAuthClientInfo client_info; | 307 gaia::OAuthClientInfo client_info; |
| 346 client_info.client_id = gaia_urls->oauth2_chrome_client_id(); | 308 client_info.client_id = gaia_urls->oauth2_chrome_client_id(); |
| 347 client_info.client_secret = gaia_urls->oauth2_chrome_client_secret(); | 309 client_info.client_secret = gaia_urls->oauth2_chrome_client_secret(); |
| 348 | 310 |
| 349 gaia_oauth_client_->RefreshToken( | 311 gaia_oauth_client_->RefreshToken( |
| 350 client_info, | 312 client_info, refresh_token_, |
| 351 refresh_token_, | |
| 352 std::vector<std::string>(1, GaiaConstants::kOAuthWrapBridgeUserInfoScope), | 313 std::vector<std::string>(1, GaiaConstants::kOAuthWrapBridgeUserInfoScope), |
| 353 max_refresh_token_validation_retries_, | 314 max_refresh_token_validation_retries_, this); |
| 354 this); | |
| 355 } | 315 } |
| 356 | 316 |
| 357 void DeviceOAuth2TokenService::FlushPendingRequests( | 317 void DeviceOAuth2TokenServiceDelegate::FlushTokenSaveCallbacks(bool result) { |
| 358 bool token_is_valid, | |
| 359 GoogleServiceAuthError::State error) { | |
| 360 std::vector<PendingRequest*> requests; | |
| 361 requests.swap(pending_requests_); | |
| 362 for (std::vector<PendingRequest*>::iterator request(requests.begin()); | |
| 363 request != requests.end(); | |
| 364 ++request) { | |
| 365 scoped_ptr<PendingRequest> scoped_request(*request); | |
| 366 if (!scoped_request->request) | |
| 367 continue; | |
| 368 | |
| 369 if (token_is_valid) { | |
| 370 OAuth2TokenService::FetchOAuth2Token( | |
| 371 scoped_request->request.get(), | |
| 372 scoped_request->request->GetAccountId(), | |
| 373 GetRequestContext(), | |
| 374 scoped_request->client_id, | |
| 375 scoped_request->client_secret, | |
| 376 scoped_request->scopes); | |
| 377 } else { | |
| 378 FailRequest(scoped_request->request.get(), error); | |
| 379 } | |
| 380 } | |
| 381 } | |
| 382 | |
| 383 void DeviceOAuth2TokenService::FlushTokenSaveCallbacks(bool result) { | |
| 384 std::vector<StatusCallback> callbacks; | 318 std::vector<StatusCallback> callbacks; |
| 385 callbacks.swap(token_save_callbacks_); | 319 callbacks.swap(token_save_callbacks_); |
| 386 for (std::vector<StatusCallback>::iterator callback(callbacks.begin()); | 320 for (std::vector<StatusCallback>::iterator callback(callbacks.begin()); |
| 387 callback != callbacks.end(); | 321 callback != callbacks.end(); ++callback) { |
| 388 ++callback) { | |
| 389 if (!callback->is_null()) | 322 if (!callback->is_null()) |
| 390 callback->Run(result); | 323 callback->Run(result); |
| 391 } | 324 } |
| 392 } | 325 } |
| 393 | 326 |
| 394 void DeviceOAuth2TokenService::FailRequest( | 327 void DeviceOAuth2TokenServiceDelegate::RequestValidation() { |
| 395 RequestImpl* request, | 328 validation_requested_ = true; |
| 396 GoogleServiceAuthError::State error) { | 329 } |
| 397 GoogleServiceAuthError auth_error(error); | 330 |
| 398 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 331 void DeviceOAuth2TokenServiceDelegate::SetValidationStatusDelegate( |
| 399 &RequestImpl::InformConsumer, | 332 ValidationStatusDelegate* delegate) { |
| 400 request->AsWeakPtr(), | 333 validation_status_delegate_ = delegate; |
| 401 auth_error, | |
| 402 std::string(), | |
| 403 base::Time())); | |
| 404 } | 334 } |
| 405 | 335 |
| 406 } // namespace chromeos | 336 } // namespace chromeos |
| OLD | NEW |