Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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.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" |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 client_id(client_id), | 36 client_id(client_id), |
| 37 client_secret(client_secret), | 37 client_secret(client_secret), |
| 38 scopes(scopes) {} | 38 scopes(scopes) {} |
| 39 | 39 |
| 40 const base::WeakPtr<RequestImpl> request; | 40 const base::WeakPtr<RequestImpl> request; |
| 41 const std::string client_id; | 41 const std::string client_id; |
| 42 const std::string client_secret; | 42 const std::string client_secret; |
| 43 const ScopeSet scopes; | 43 const ScopeSet scopes; |
| 44 }; | 44 }; |
| 45 | 45 |
| 46 DeviceOAuth2TokenService::DeviceOAuth2TokenServiceDelegate:: | |
|
Mattias Nissler (ping if slow)
2015/06/29 08:20:06
It's pretty odd that the CL introduces a delegate
| |
| 47 DeviceOAuth2TokenServiceDelegate( | |
| 48 DeviceOAuth2TokenService* device_token_service) | |
| 49 : device_token_service_(device_token_service) { | |
| 50 } | |
| 51 | |
| 52 DeviceOAuth2TokenService::DeviceOAuth2TokenServiceDelegate:: | |
| 53 ~DeviceOAuth2TokenServiceDelegate() { | |
| 54 } | |
| 55 | |
| 56 OAuth2AccessTokenFetcher* DeviceOAuth2TokenService:: | |
| 57 DeviceOAuth2TokenServiceDelegate::CreateAccessTokenFetcher( | |
| 58 const std::string& account_id, | |
| 59 net::URLRequestContextGetter* getter, | |
| 60 OAuth2AccessTokenConsumer* consumer) { | |
| 61 return device_token_service_->CreateAccessTokenFetcherImpl(account_id, getter, | |
| 62 consumer); | |
| 63 } | |
| 64 | |
| 65 bool DeviceOAuth2TokenService::DeviceOAuth2TokenServiceDelegate:: | |
| 66 RefreshTokenIsAvailable(const std::string& account_id) const { | |
| 67 return device_token_service_->RefreshTokenIsAvailableImpl(account_id); | |
| 68 } | |
| 69 | |
| 70 net::URLRequestContextGetter* | |
| 71 DeviceOAuth2TokenService::DeviceOAuth2TokenServiceDelegate::GetRequestContext() | |
| 72 const { | |
| 73 return device_token_service_->GetRequestContextImpl(); | |
| 74 } | |
| 75 | |
| 76 void DeviceOAuth2TokenService::DeviceOAuth2TokenServiceDelegate:: | |
| 77 UpdateAuthError(const std::string& account_id, | |
| 78 const GoogleServiceAuthError& error) { | |
|
Mattias Nissler (ping if slow)
2015/06/29 08:20:06
Should have a comment explaining why it's OK that
| |
| 79 } | |
| 80 | |
| 81 std::vector<std::string> | |
| 82 DeviceOAuth2TokenService::DeviceOAuth2TokenServiceDelegate::GetAccounts() { | |
| 83 std::vector<std::string> accounts; | |
| 84 std::string account = device_token_service_->GetRobotAccountId(); | |
| 85 if (!account.empty()) | |
| 86 accounts.push_back(account); | |
| 87 return accounts; | |
| 88 } | |
| 89 | |
| 90 void DeviceOAuth2TokenService::DeviceOAuth2TokenServiceDelegate:: | |
| 91 RevokeAllCredentials() { | |
|
Mattias Nissler (ping if slow)
2015/06/29 08:20:06
Again, please explain why it's OK that this is emp
| |
| 92 } | |
| 93 | |
| 46 void DeviceOAuth2TokenService::OnServiceAccountIdentityChanged() { | 94 void DeviceOAuth2TokenService::OnServiceAccountIdentityChanged() { |
| 47 if (!GetRobotAccountId().empty() && !refresh_token_.empty()) | 95 if (!GetRobotAccountId().empty() && !refresh_token_.empty()) |
| 48 FireRefreshTokenAvailable(GetRobotAccountId()); | 96 device_oauth2_token_service_delegate_->FireRefreshTokenAvailable( |
| 97 GetRobotAccountId()); | |
| 49 } | 98 } |
| 50 | 99 |
| 51 DeviceOAuth2TokenService::DeviceOAuth2TokenService( | 100 DeviceOAuth2TokenService::DeviceOAuth2TokenService( |
| 52 net::URLRequestContextGetter* getter, | 101 net::URLRequestContextGetter* getter, |
| 53 PrefService* local_state) | 102 PrefService* local_state) |
| 54 : url_request_context_getter_(getter), | 103 : OAuth2TokenService(new DeviceOAuth2TokenServiceDelegate(this)), |
| 104 url_request_context_getter_(getter), | |
| 55 local_state_(local_state), | 105 local_state_(local_state), |
| 56 state_(STATE_LOADING), | 106 state_(STATE_LOADING), |
| 57 max_refresh_token_validation_retries_(3), | 107 max_refresh_token_validation_retries_(3), |
| 58 service_account_identity_subscription_( | 108 service_account_identity_subscription_( |
| 59 CrosSettings::Get()->AddSettingsObserver( | 109 CrosSettings::Get() |
| 60 kServiceAccountIdentity, | 110 ->AddSettingsObserver( |
| 61 base::Bind( | 111 kServiceAccountIdentity, |
| 62 &DeviceOAuth2TokenService::OnServiceAccountIdentityChanged, | 112 base::Bind(&DeviceOAuth2TokenService:: |
| 63 base::Unretained(this))).Pass()), | 113 OnServiceAccountIdentityChanged, |
| 114 base::Unretained(this))) | |
| 115 .Pass()), | |
| 64 weak_ptr_factory_(this) { | 116 weak_ptr_factory_(this) { |
| 117 device_oauth2_token_service_delegate_ = | |
| 118 (DeviceOAuth2TokenServiceDelegate*)GetDelegate(); | |
|
xiyuan
2015/06/26 18:15:52
nit: static_cast<DeviceOAuth2TokenServiceDelegate*
Mattias Nissler (ping if slow)
2015/06/29 08:20:06
Actually, it looks like none of the uses of |devic
| |
| 65 // Pull in the system salt. | 119 // Pull in the system salt. |
| 66 SystemSaltGetter::Get()->GetSystemSalt( | 120 SystemSaltGetter::Get()->GetSystemSalt( |
| 67 base::Bind(&DeviceOAuth2TokenService::DidGetSystemSalt, | 121 base::Bind(&DeviceOAuth2TokenService::DidGetSystemSalt, |
| 68 weak_ptr_factory_.GetWeakPtr())); | 122 weak_ptr_factory_.GetWeakPtr())); |
| 69 } | 123 } |
| 70 | 124 |
| 71 DeviceOAuth2TokenService::~DeviceOAuth2TokenService() { | 125 DeviceOAuth2TokenService::~DeviceOAuth2TokenService() { |
| 72 FlushPendingRequests(false, GoogleServiceAuthError::REQUEST_CANCELED); | 126 FlushPendingRequests(false, GoogleServiceAuthError::REQUEST_CANCELED); |
| 73 FlushTokenSaveCallbacks(false); | 127 FlushTokenSaveCallbacks(false); |
| 74 } | 128 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 85 FlushPendingRequests(false, GoogleServiceAuthError::REQUEST_CANCELED); | 139 FlushPendingRequests(false, GoogleServiceAuthError::REQUEST_CANCELED); |
| 86 | 140 |
| 87 bool waiting_for_salt = state_ == STATE_LOADING; | 141 bool waiting_for_salt = state_ == STATE_LOADING; |
| 88 refresh_token_ = refresh_token; | 142 refresh_token_ = refresh_token; |
| 89 state_ = STATE_VALIDATION_PENDING; | 143 state_ = STATE_VALIDATION_PENDING; |
| 90 | 144 |
| 91 // If the robot account ID is not available yet, do not announce the token. It | 145 // 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 | 146 // will be done from OnServiceAccountIdentityChanged() once the robot account |
| 93 // ID becomes available as well. | 147 // ID becomes available as well. |
| 94 if (!GetRobotAccountId().empty()) | 148 if (!GetRobotAccountId().empty()) |
| 95 FireRefreshTokenAvailable(GetRobotAccountId()); | 149 device_oauth2_token_service_delegate_->FireRefreshTokenAvailable( |
| 150 GetRobotAccountId()); | |
| 96 | 151 |
| 97 token_save_callbacks_.push_back(result_callback); | 152 token_save_callbacks_.push_back(result_callback); |
| 98 if (!waiting_for_salt) { | 153 if (!waiting_for_salt) { |
| 99 if (system_salt_.empty()) | 154 if (system_salt_.empty()) |
| 100 FlushTokenSaveCallbacks(false); | 155 FlushTokenSaveCallbacks(false); |
| 101 else | 156 else |
| 102 EncryptAndSaveToken(); | 157 EncryptAndSaveToken(); |
| 103 } | 158 } |
| 104 } | 159 } |
| 105 | 160 |
| 106 bool DeviceOAuth2TokenService::RefreshTokenIsAvailable( | 161 bool DeviceOAuth2TokenService::RefreshTokenIsAvailableImpl( |
| 107 const std::string& account_id) const { | 162 const std::string& account_id) const { |
| 108 switch (state_) { | 163 switch (state_) { |
| 109 case STATE_NO_TOKEN: | 164 case STATE_NO_TOKEN: |
| 110 case STATE_TOKEN_INVALID: | 165 case STATE_TOKEN_INVALID: |
| 111 return false; | 166 return false; |
| 112 case STATE_LOADING: | 167 case STATE_LOADING: |
| 113 case STATE_VALIDATION_PENDING: | 168 case STATE_VALIDATION_PENDING: |
| 114 case STATE_VALIDATION_STARTED: | 169 case STATE_VALIDATION_STARTED: |
| 115 case STATE_TOKEN_VALID: | 170 case STATE_TOKEN_VALID: |
| 116 return account_id == GetRobotAccountId(); | 171 return account_id == GetRobotAccountId(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 case STATE_VALIDATION_PENDING: | 229 case STATE_VALIDATION_PENDING: |
| 175 case STATE_VALIDATION_STARTED: | 230 case STATE_VALIDATION_STARTED: |
| 176 case STATE_TOKEN_VALID: | 231 case STATE_TOKEN_VALID: |
| 177 return refresh_token_; | 232 return refresh_token_; |
| 178 } | 233 } |
| 179 | 234 |
| 180 NOTREACHED() << "Unhandled state " << state_; | 235 NOTREACHED() << "Unhandled state " << state_; |
| 181 return std::string(); | 236 return std::string(); |
| 182 } | 237 } |
| 183 | 238 |
| 184 net::URLRequestContextGetter* DeviceOAuth2TokenService::GetRequestContext() { | 239 net::URLRequestContextGetter* |
| 240 DeviceOAuth2TokenService::GetRequestContextImpl() { | |
| 185 return url_request_context_getter_.get(); | 241 return url_request_context_getter_.get(); |
| 186 } | 242 } |
| 187 | 243 |
| 188 void DeviceOAuth2TokenService::FetchOAuth2Token( | 244 void DeviceOAuth2TokenService::FetchOAuth2Token( |
| 189 RequestImpl* request, | 245 RequestImpl* request, |
| 190 const std::string& account_id, | 246 const std::string& account_id, |
| 191 net::URLRequestContextGetter* getter, | 247 net::URLRequestContextGetter* getter, |
| 192 const std::string& client_id, | 248 const std::string& client_id, |
| 193 const std::string& client_secret, | 249 const std::string& client_secret, |
| 194 const ScopeSet& scopes) { | 250 const ScopeSet& scopes) { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 212 case STATE_TOKEN_VALID: | 268 case STATE_TOKEN_VALID: |
| 213 // Pass through to OAuth2TokenService to satisfy the request. | 269 // Pass through to OAuth2TokenService to satisfy the request. |
| 214 OAuth2TokenService::FetchOAuth2Token( | 270 OAuth2TokenService::FetchOAuth2Token( |
| 215 request, account_id, getter, client_id, client_secret, scopes); | 271 request, account_id, getter, client_id, client_secret, scopes); |
| 216 return; | 272 return; |
| 217 } | 273 } |
| 218 | 274 |
| 219 NOTREACHED() << "Unexpected state " << state_; | 275 NOTREACHED() << "Unexpected state " << state_; |
| 220 } | 276 } |
| 221 | 277 |
| 222 OAuth2AccessTokenFetcher* DeviceOAuth2TokenService::CreateAccessTokenFetcher( | 278 OAuth2AccessTokenFetcher* |
| 279 DeviceOAuth2TokenService::CreateAccessTokenFetcherImpl( | |
| 223 const std::string& account_id, | 280 const std::string& account_id, |
| 224 net::URLRequestContextGetter* getter, | 281 net::URLRequestContextGetter* getter, |
| 225 OAuth2AccessTokenConsumer* consumer) { | 282 OAuth2AccessTokenConsumer* consumer) { |
| 226 std::string refresh_token = GetRefreshToken(account_id); | 283 std::string refresh_token = GetRefreshToken(account_id); |
| 227 DCHECK(!refresh_token.empty()); | 284 DCHECK(!refresh_token.empty()); |
| 228 return new OAuth2AccessTokenFetcherImpl(consumer, getter, refresh_token); | 285 return new OAuth2AccessTokenFetcherImpl(consumer, getter, refresh_token); |
| 229 } | 286 } |
| 230 | 287 |
| 231 | 288 |
| 232 void DeviceOAuth2TokenService::DidGetSystemSalt( | 289 void DeviceOAuth2TokenService::DidGetSystemSalt( |
| 233 const std::string& system_salt) { | 290 const std::string& system_salt) { |
| 234 system_salt_ = system_salt; | 291 system_salt_ = system_salt; |
| 235 | 292 |
| 236 // Bail out if system salt is not available. | 293 // Bail out if system salt is not available. |
| 237 if (system_salt_.empty()) { | 294 if (system_salt_.empty()) { |
| 238 LOG(ERROR) << "Failed to get system salt."; | 295 LOG(ERROR) << "Failed to get system salt."; |
| 239 FlushTokenSaveCallbacks(false); | 296 FlushTokenSaveCallbacks(false); |
| 240 state_ = STATE_NO_TOKEN; | 297 state_ = STATE_NO_TOKEN; |
| 241 FireRefreshTokensLoaded(); | 298 device_oauth2_token_service_delegate_->FireRefreshTokensLoaded(); |
| 242 return; | 299 return; |
| 243 } | 300 } |
| 244 | 301 |
| 245 // If the token has been set meanwhile, write it to |local_state_|. | 302 // If the token has been set meanwhile, write it to |local_state_|. |
| 246 if (!refresh_token_.empty()) { | 303 if (!refresh_token_.empty()) { |
| 247 EncryptAndSaveToken(); | 304 EncryptAndSaveToken(); |
| 248 FireRefreshTokensLoaded(); | 305 device_oauth2_token_service_delegate_->FireRefreshTokensLoaded(); |
| 249 return; | 306 return; |
| 250 } | 307 } |
| 251 | 308 |
| 252 // Otherwise, load the refresh token from |local_state_|. | 309 // Otherwise, load the refresh token from |local_state_|. |
| 253 std::string encrypted_refresh_token = | 310 std::string encrypted_refresh_token = |
| 254 local_state_->GetString(prefs::kDeviceRobotAnyApiRefreshToken); | 311 local_state_->GetString(prefs::kDeviceRobotAnyApiRefreshToken); |
| 255 if (!encrypted_refresh_token.empty()) { | 312 if (!encrypted_refresh_token.empty()) { |
| 256 CryptohomeTokenEncryptor encryptor(system_salt_); | 313 CryptohomeTokenEncryptor encryptor(system_salt_); |
| 257 refresh_token_ = encryptor.DecryptWithSystemSalt(encrypted_refresh_token); | 314 refresh_token_ = encryptor.DecryptWithSystemSalt(encrypted_refresh_token); |
| 258 if (refresh_token_.empty()) { | 315 if (refresh_token_.empty()) { |
| 259 LOG(ERROR) << "Failed to decrypt refresh token."; | 316 LOG(ERROR) << "Failed to decrypt refresh token."; |
| 260 state_ = STATE_NO_TOKEN; | 317 state_ = STATE_NO_TOKEN; |
| 261 FireRefreshTokensLoaded(); | 318 device_oauth2_token_service_delegate_->FireRefreshTokensLoaded(); |
| 262 return; | 319 return; |
| 263 } | 320 } |
| 264 } | 321 } |
| 265 | 322 |
| 266 state_ = STATE_VALIDATION_PENDING; | 323 state_ = STATE_VALIDATION_PENDING; |
| 267 | 324 |
| 268 // If there are pending requests, start a validation. | 325 // If there are pending requests, start a validation. |
| 269 if (!pending_requests_.empty()) | 326 if (!pending_requests_.empty()) |
| 270 StartValidation(); | 327 StartValidation(); |
| 271 | 328 |
| 272 // Announce the token. | 329 // Announce the token. |
| 273 FireRefreshTokenAvailable(GetRobotAccountId()); | 330 device_oauth2_token_service_delegate_->FireRefreshTokenAvailable( |
| 274 FireRefreshTokensLoaded(); | 331 GetRobotAccountId()); |
| 332 device_oauth2_token_service_delegate_->FireRefreshTokensLoaded(); | |
| 275 } | 333 } |
| 276 | 334 |
| 277 void DeviceOAuth2TokenService::CheckRobotAccountId( | 335 void DeviceOAuth2TokenService::CheckRobotAccountId( |
| 278 const std::string& gaia_robot_id) { | 336 const std::string& gaia_robot_id) { |
| 279 // Make sure the value returned by GetRobotAccountId has been validated | 337 // Make sure the value returned by GetRobotAccountId has been validated |
| 280 // against current device settings. | 338 // against current device settings. |
| 281 switch (CrosSettings::Get()->PrepareTrustedValues(base::Bind( | 339 switch (CrosSettings::Get()->PrepareTrustedValues(base::Bind( |
| 282 &DeviceOAuth2TokenService::CheckRobotAccountId, | 340 &DeviceOAuth2TokenService::CheckRobotAccountId, |
| 283 weak_ptr_factory_.GetWeakPtr(), | 341 weak_ptr_factory_.GetWeakPtr(), |
| 284 gaia_robot_id))) { | 342 gaia_robot_id))) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 for (std::vector<PendingRequest*>::iterator request(requests.begin()); | 420 for (std::vector<PendingRequest*>::iterator request(requests.begin()); |
| 363 request != requests.end(); | 421 request != requests.end(); |
| 364 ++request) { | 422 ++request) { |
| 365 scoped_ptr<PendingRequest> scoped_request(*request); | 423 scoped_ptr<PendingRequest> scoped_request(*request); |
| 366 if (!scoped_request->request) | 424 if (!scoped_request->request) |
| 367 continue; | 425 continue; |
| 368 | 426 |
| 369 if (token_is_valid) { | 427 if (token_is_valid) { |
| 370 OAuth2TokenService::FetchOAuth2Token( | 428 OAuth2TokenService::FetchOAuth2Token( |
| 371 scoped_request->request.get(), | 429 scoped_request->request.get(), |
| 372 scoped_request->request->GetAccountId(), | 430 scoped_request->request->GetAccountId(), GetRequestContextImpl(), |
| 373 GetRequestContext(), | 431 scoped_request->client_id, scoped_request->client_secret, |
| 374 scoped_request->client_id, | |
| 375 scoped_request->client_secret, | |
| 376 scoped_request->scopes); | 432 scoped_request->scopes); |
| 377 } else { | 433 } else { |
| 378 FailRequest(scoped_request->request.get(), error); | 434 FailRequest(scoped_request->request.get(), error); |
| 379 } | 435 } |
| 380 } | 436 } |
| 381 } | 437 } |
| 382 | 438 |
| 383 void DeviceOAuth2TokenService::FlushTokenSaveCallbacks(bool result) { | 439 void DeviceOAuth2TokenService::FlushTokenSaveCallbacks(bool result) { |
| 384 std::vector<StatusCallback> callbacks; | 440 std::vector<StatusCallback> callbacks; |
| 385 callbacks.swap(token_save_callbacks_); | 441 callbacks.swap(token_save_callbacks_); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 397 GoogleServiceAuthError auth_error(error); | 453 GoogleServiceAuthError auth_error(error); |
| 398 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 454 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| 399 &RequestImpl::InformConsumer, | 455 &RequestImpl::InformConsumer, |
| 400 request->AsWeakPtr(), | 456 request->AsWeakPtr(), |
| 401 auth_error, | 457 auth_error, |
| 402 std::string(), | 458 std::string(), |
| 403 base::Time())); | 459 base::Time())); |
| 404 } | 460 } |
| 405 | 461 |
| 406 } // namespace chromeos | 462 } // namespace chromeos |
| OLD | NEW |