OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/extensions/api/identity/identity_api.h" | 5 #include "chrome/browser/extensions/api/identity/identity_api.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 30 matching lines...) Expand all Loading... |
41 | 41 |
42 namespace identity_constants { | 42 namespace identity_constants { |
43 const char kInvalidClientId[] = "Invalid OAuth2 Client ID."; | 43 const char kInvalidClientId[] = "Invalid OAuth2 Client ID."; |
44 const char kInvalidScopes[] = "Invalid OAuth2 scopes."; | 44 const char kInvalidScopes[] = "Invalid OAuth2 scopes."; |
45 const char kAuthFailure[] = "OAuth2 request failed: "; | 45 const char kAuthFailure[] = "OAuth2 request failed: "; |
46 const char kNoGrant[] = "OAuth2 not granted or revoked."; | 46 const char kNoGrant[] = "OAuth2 not granted or revoked."; |
47 const char kUserRejected[] = "The user did not approve access."; | 47 const char kUserRejected[] = "The user did not approve access."; |
48 const char kUserNotSignedIn[] = "The user is not signed in."; | 48 const char kUserNotSignedIn[] = "The user is not signed in."; |
49 const char kInteractionRequired[] = "User interaction required."; | 49 const char kInteractionRequired[] = "User interaction required."; |
50 const char kInvalidRedirect[] = "Did not redirect to the right URL."; | 50 const char kInvalidRedirect[] = "Did not redirect to the right URL."; |
| 51 |
| 52 const int kCachedIssueAdviceTTLSeconds = 1; |
51 } // namespace identity_constants | 53 } // namespace identity_constants |
52 | 54 |
53 namespace { | 55 namespace { |
54 | 56 |
55 static const char kChromiumDomainRedirectUrlPattern[] = | 57 static const char kChromiumDomainRedirectUrlPattern[] = |
56 "https://%s.chromiumapp.org/"; | 58 "https://%s.chromiumapp.org/"; |
57 | 59 |
58 } // namespace | 60 } // namespace |
59 | 61 |
60 namespace GetAuthToken = api::experimental_identity::GetAuthToken; | 62 namespace GetAuthToken = api::experimental_identity::GetAuthToken; |
| 63 namespace InvalidateAuthToken = api::experimental_identity::InvalidateAuthToken; |
61 namespace LaunchWebAuthFlow = api::experimental_identity::LaunchWebAuthFlow; | 64 namespace LaunchWebAuthFlow = api::experimental_identity::LaunchWebAuthFlow; |
62 namespace identity = api::experimental_identity; | 65 namespace identity = api::experimental_identity; |
63 | 66 |
64 IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction() | 67 IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction() |
65 : should_prompt_for_scopes_(false), | 68 : should_prompt_for_scopes_(false), |
66 should_prompt_for_signin_(false) {} | 69 should_prompt_for_signin_(false) {} |
67 | 70 |
68 IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() {} | 71 IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() {} |
69 | 72 |
70 bool IdentityGetAuthTokenFunction::RunImpl() { | 73 bool IdentityGetAuthTokenFunction::RunImpl() { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } | 121 } |
119 | 122 |
120 void IdentityGetAuthTokenFunction::CompleteFunctionWithError( | 123 void IdentityGetAuthTokenFunction::CompleteFunctionWithError( |
121 const std::string& error) { | 124 const std::string& error) { |
122 error_ = error; | 125 error_ = error; |
123 SendResponse(false); | 126 SendResponse(false); |
124 Release(); // Balanced in RunImpl. | 127 Release(); // Balanced in RunImpl. |
125 } | 128 } |
126 | 129 |
127 void IdentityGetAuthTokenFunction::StartSigninFlow() { | 130 void IdentityGetAuthTokenFunction::StartSigninFlow() { |
| 131 // All cached tokens are invalid because the user is not signed in. |
| 132 IdentityAPI* id_api = |
| 133 extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(profile_); |
| 134 id_api->EraseAllCachedTokens(); |
128 // Display a login prompt. If the subsequent mint fails, don't display the | 135 // Display a login prompt. If the subsequent mint fails, don't display the |
129 // login prompt again. | 136 // login prompt again. |
130 should_prompt_for_signin_ = false; | 137 should_prompt_for_signin_ = false; |
131 ShowLoginPopup(); | 138 ShowLoginPopup(); |
132 } | 139 } |
133 | 140 |
134 void IdentityGetAuthTokenFunction::StartMintTokenFlow( | 141 void IdentityGetAuthTokenFunction::StartMintTokenFlow( |
135 IdentityMintRequestQueue::MintType type) { | 142 IdentityMintRequestQueue::MintType type) { |
136 mint_token_flow_type_ = type; | 143 mint_token_flow_type_ = type; |
137 | 144 |
138 // Flows are serialized to prevent excessive traffic to GAIA, and | 145 // Flows are serialized to prevent excessive traffic to GAIA, and |
139 // to consolidate UI pop-ups. | 146 // to consolidate UI pop-ups. |
140 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); | 147 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); |
141 std::set<std::string> scopes(oauth2_info.scopes.begin(), | 148 std::set<std::string> scopes(oauth2_info.scopes.begin(), |
142 oauth2_info.scopes.end()); | 149 oauth2_info.scopes.end()); |
143 IdentityAPI* id_api = | 150 IdentityAPI* id_api = |
144 extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(profile_); | 151 extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(profile_); |
145 | 152 |
146 // If there is an interactive flow in progress, non-interactive | 153 if (!should_prompt_for_scopes_) { |
147 // requests should complete immediately since a consent UI is | 154 // Caller requested no interaction. |
148 // known to be required. | 155 |
149 if (!should_prompt_for_scopes_ && !id_api->mint_queue()->empty( | 156 if (type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE) { |
150 IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE, | 157 // GAIA told us to do a consent UI. |
151 GetExtension()->id(), scopes)) { | 158 CompleteFunctionWithError(identity_constants::kNoGrant); |
152 CompleteFunctionWithError(identity_constants::kNoGrant); | 159 return; |
153 return; | 160 } |
| 161 if (!id_api->mint_queue()->empty( |
| 162 IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE, |
| 163 GetExtension()->id(), scopes)) { |
| 164 // Another call is going through a consent UI. |
| 165 CompleteFunctionWithError(identity_constants::kNoGrant); |
| 166 return; |
| 167 } |
154 } | 168 } |
155 id_api->mint_queue()->RequestStart(type, | 169 id_api->mint_queue()->RequestStart(type, |
156 GetExtension()->id(), | 170 GetExtension()->id(), |
157 scopes, | 171 scopes, |
158 this); | 172 this); |
159 } | 173 } |
160 | 174 |
161 void IdentityGetAuthTokenFunction::CompleteMintTokenFlow() { | 175 void IdentityGetAuthTokenFunction::CompleteMintTokenFlow() { |
162 IdentityMintRequestQueue::MintType type = mint_token_flow_type_; | 176 IdentityMintRequestQueue::MintType type = mint_token_flow_type_; |
163 | 177 |
164 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); | 178 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); |
165 std::set<std::string> scopes(oauth2_info.scopes.begin(), | 179 std::set<std::string> scopes(oauth2_info.scopes.begin(), |
166 oauth2_info.scopes.end()); | 180 oauth2_info.scopes.end()); |
167 | 181 |
168 extensions::IdentityAPI::GetFactoryInstance()->GetForProfile( | 182 extensions::IdentityAPI::GetFactoryInstance()->GetForProfile( |
169 profile_)->mint_queue()->RequestComplete(type, | 183 profile_)->mint_queue()->RequestComplete(type, |
170 GetExtension()->id(), | 184 GetExtension()->id(), |
171 scopes, | 185 scopes, |
172 this); | 186 this); |
173 } | 187 } |
174 | 188 |
175 void IdentityGetAuthTokenFunction::StartMintToken( | 189 void IdentityGetAuthTokenFunction::StartMintToken( |
176 IdentityMintRequestQueue::MintType type) { | 190 IdentityMintRequestQueue::MintType type) { |
177 switch (type) { | 191 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); |
178 case IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE: | 192 IdentityAPI* id_api = IdentityAPI::GetFactoryInstance()->GetForProfile( |
179 StartGaiaRequest(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE); | 193 profile()); |
180 break; | 194 IdentityTokenCacheValue cache_entry = id_api->GetCachedToken( |
| 195 GetExtension()->id(), oauth2_info.scopes); |
| 196 IdentityTokenCacheValue::CacheValueStatus cache_status = |
| 197 cache_entry.status(); |
181 | 198 |
182 case IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE: | 199 if (type == IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE) { |
| 200 switch (cache_status) { |
| 201 case IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND: |
| 202 StartGaiaRequest(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE); |
| 203 break; |
| 204 |
| 205 case IdentityTokenCacheValue::CACHE_STATUS_TOKEN: |
| 206 CompleteMintTokenFlow(); |
| 207 CompleteFunctionWithResult(cache_entry.token()); |
| 208 break; |
| 209 |
| 210 case IdentityTokenCacheValue::CACHE_STATUS_ADVICE: |
| 211 CompleteMintTokenFlow(); |
| 212 should_prompt_for_signin_ = false; |
| 213 issue_advice_ = cache_entry.issue_advice(); |
| 214 StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE); |
| 215 break; |
| 216 } |
| 217 } else { |
| 218 DCHECK(type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE); |
| 219 |
| 220 if (cache_status == IdentityTokenCacheValue::CACHE_STATUS_TOKEN) { |
| 221 CompleteMintTokenFlow(); |
| 222 CompleteFunctionWithResult(cache_entry.token()); |
| 223 } else { |
183 install_ui_.reset(new ExtensionInstallPrompt(GetAssociatedWebContents())); | 224 install_ui_.reset(new ExtensionInstallPrompt(GetAssociatedWebContents())); |
184 ShowOAuthApprovalDialog(issue_advice_); | 225 ShowOAuthApprovalDialog(issue_advice_); |
185 break; | 226 } |
186 | 227 } |
187 default: | |
188 NOTREACHED() << "Unexepected mint type in StartMintToken: " << type; | |
189 break; | |
190 }; | |
191 } | 228 } |
192 | 229 |
193 void IdentityGetAuthTokenFunction::OnMintTokenSuccess( | 230 void IdentityGetAuthTokenFunction::OnMintTokenSuccess( |
194 const std::string& access_token) { | 231 const std::string& access_token, int time_to_live) { |
| 232 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); |
| 233 IdentityTokenCacheValue token(access_token, |
| 234 base::TimeDelta::FromSeconds(time_to_live)); |
| 235 IdentityAPI::GetFactoryInstance()->GetForProfile(profile())->SetCachedToken( |
| 236 GetExtension()->id(), oauth2_info.scopes, token); |
| 237 |
195 CompleteMintTokenFlow(); | 238 CompleteMintTokenFlow(); |
196 CompleteFunctionWithResult(access_token); | 239 CompleteFunctionWithResult(access_token); |
197 } | 240 } |
198 | 241 |
199 void IdentityGetAuthTokenFunction::OnMintTokenFailure( | 242 void IdentityGetAuthTokenFunction::OnMintTokenFailure( |
200 const GoogleServiceAuthError& error) { | 243 const GoogleServiceAuthError& error) { |
201 CompleteMintTokenFlow(); | 244 CompleteMintTokenFlow(); |
202 | 245 |
203 switch (error.state()) { | 246 switch (error.state()) { |
204 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: | 247 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: |
(...skipping 11 matching lines...) Expand all Loading... |
216 // Return error to caller. | 259 // Return error to caller. |
217 break; | 260 break; |
218 } | 261 } |
219 | 262 |
220 CompleteFunctionWithError( | 263 CompleteFunctionWithError( |
221 std::string(identity_constants::kAuthFailure) + error.ToString()); | 264 std::string(identity_constants::kAuthFailure) + error.ToString()); |
222 } | 265 } |
223 | 266 |
224 void IdentityGetAuthTokenFunction::OnIssueAdviceSuccess( | 267 void IdentityGetAuthTokenFunction::OnIssueAdviceSuccess( |
225 const IssueAdviceInfo& issue_advice) { | 268 const IssueAdviceInfo& issue_advice) { |
| 269 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); |
| 270 IdentityAPI::GetFactoryInstance()->GetForProfile(profile())->SetCachedToken( |
| 271 GetExtension()->id(), oauth2_info.scopes, |
| 272 IdentityTokenCacheValue(issue_advice)); |
226 CompleteMintTokenFlow(); | 273 CompleteMintTokenFlow(); |
227 | 274 |
228 should_prompt_for_signin_ = false; | 275 should_prompt_for_signin_ = false; |
229 // Existing grant was revoked and we used NO_FORCE, so we got info back | 276 // Existing grant was revoked and we used NO_FORCE, so we got info back |
230 // instead. | 277 // instead. Start a consent UI if we can. |
231 if (should_prompt_for_scopes_) { | 278 issue_advice_ = issue_advice; |
232 issue_advice_ = issue_advice; | 279 StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE); |
233 StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE); | |
234 } else { | |
235 CompleteFunctionWithError(identity_constants::kNoGrant); | |
236 } | |
237 } | 280 } |
238 | 281 |
239 void IdentityGetAuthTokenFunction::SigninSuccess(const std::string& token) { | 282 void IdentityGetAuthTokenFunction::SigninSuccess(const std::string& token) { |
240 refresh_token_ = token; | 283 refresh_token_ = token; |
241 StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE); | 284 StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE); |
242 } | 285 } |
243 | 286 |
244 void IdentityGetAuthTokenFunction::SigninFailed() { | 287 void IdentityGetAuthTokenFunction::SigninFailed() { |
245 CompleteFunctionWithError(identity_constants::kUserNotSignedIn); | 288 CompleteFunctionWithError(identity_constants::kUserNotSignedIn); |
246 } | 289 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 } | 341 } |
299 #endif | 342 #endif |
300 return mint_token_flow; | 343 return mint_token_flow; |
301 } | 344 } |
302 | 345 |
303 bool IdentityGetAuthTokenFunction::HasLoginToken() const { | 346 bool IdentityGetAuthTokenFunction::HasLoginToken() const { |
304 TokenService* token_service = TokenServiceFactory::GetForProfile(profile()); | 347 TokenService* token_service = TokenServiceFactory::GetForProfile(profile()); |
305 return token_service->HasOAuthLoginToken(); | 348 return token_service->HasOAuthLoginToken(); |
306 } | 349 } |
307 | 350 |
| 351 IdentityInvalidateAuthTokenFunction::IdentityInvalidateAuthTokenFunction() {} |
| 352 IdentityInvalidateAuthTokenFunction::~IdentityInvalidateAuthTokenFunction() {} |
| 353 |
| 354 bool IdentityInvalidateAuthTokenFunction::RunImpl() { |
| 355 scoped_ptr<InvalidateAuthToken::Params> params( |
| 356 InvalidateAuthToken::Params::Create(*args_)); |
| 357 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 358 const identity::InvalidTokenDetails& details = params->details; |
| 359 IdentityAPI::GetFactoryInstance()->GetForProfile(profile())->EraseCachedToken( |
| 360 GetExtension()->id(), details.token); |
| 361 return true; |
| 362 } |
| 363 |
308 IdentityLaunchWebAuthFlowFunction::IdentityLaunchWebAuthFlowFunction() {} | 364 IdentityLaunchWebAuthFlowFunction::IdentityLaunchWebAuthFlowFunction() {} |
309 IdentityLaunchWebAuthFlowFunction::~IdentityLaunchWebAuthFlowFunction() {} | 365 IdentityLaunchWebAuthFlowFunction::~IdentityLaunchWebAuthFlowFunction() {} |
310 | 366 |
311 bool IdentityLaunchWebAuthFlowFunction::RunImpl() { | 367 bool IdentityLaunchWebAuthFlowFunction::RunImpl() { |
312 scoped_ptr<LaunchWebAuthFlow::Params> params( | 368 scoped_ptr<LaunchWebAuthFlow::Params> params( |
313 LaunchWebAuthFlow::Params::Create(*args_)); | 369 LaunchWebAuthFlow::Params::Create(*args_)); |
314 EXTENSION_FUNCTION_VALIDATE(params.get()); | 370 EXTENSION_FUNCTION_VALIDATE(params.get()); |
315 const identity::WebAuthFlowDetails& details = params->details; | 371 const identity::WebAuthFlowDetails& details = params->details; |
316 | 372 |
317 GURL auth_url(details.url); | 373 GURL auth_url(details.url); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 | 446 |
391 void IdentityLaunchWebAuthFlowFunction::OnAuthFlowURLChange( | 447 void IdentityLaunchWebAuthFlowFunction::OnAuthFlowURLChange( |
392 const GURL& redirect_url) { | 448 const GURL& redirect_url) { |
393 if (IsFinalRedirectURL(redirect_url)) { | 449 if (IsFinalRedirectURL(redirect_url)) { |
394 SetResult(Value::CreateStringValue(redirect_url.spec())); | 450 SetResult(Value::CreateStringValue(redirect_url.spec())); |
395 SendResponse(true); | 451 SendResponse(true); |
396 Release(); // Balanced in RunImpl. | 452 Release(); // Balanced in RunImpl. |
397 } | 453 } |
398 } | 454 } |
399 | 455 |
| 456 IdentityTokenCacheValue::IdentityTokenCacheValue() |
| 457 : status_(CACHE_STATUS_NOTFOUND) { |
| 458 } |
| 459 |
| 460 IdentityTokenCacheValue::IdentityTokenCacheValue( |
| 461 const IssueAdviceInfo& issue_advice) : status_(CACHE_STATUS_ADVICE), |
| 462 issue_advice_(issue_advice) { |
| 463 expiration_time_ = base::Time::Now() + base::TimeDelta::FromSeconds( |
| 464 identity_constants::kCachedIssueAdviceTTLSeconds); |
| 465 } |
| 466 |
| 467 IdentityTokenCacheValue::IdentityTokenCacheValue( |
| 468 const std::string& token, base::TimeDelta time_to_live) |
| 469 : status_(CACHE_STATUS_TOKEN), |
| 470 token_(token) { |
| 471 base::TimeDelta zero_delta; |
| 472 if (time_to_live < zero_delta) |
| 473 time_to_live = zero_delta; |
| 474 |
| 475 expiration_time_ = base::Time::Now() + time_to_live; |
| 476 } |
| 477 |
| 478 IdentityTokenCacheValue::~IdentityTokenCacheValue() { |
| 479 } |
| 480 |
| 481 IdentityTokenCacheValue::CacheValueStatus |
| 482 IdentityTokenCacheValue::status() const { |
| 483 if (is_expired()) |
| 484 return IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND; |
| 485 else |
| 486 return status_; |
| 487 } |
| 488 |
| 489 const IssueAdviceInfo& IdentityTokenCacheValue::issue_advice() const { |
| 490 return issue_advice_; |
| 491 } |
| 492 |
| 493 const std::string& IdentityTokenCacheValue::token() const { |
| 494 return token_; |
| 495 } |
| 496 |
| 497 bool IdentityTokenCacheValue::is_expired() const { |
| 498 return status_ == CACHE_STATUS_NOTFOUND || |
| 499 expiration_time_ < base::Time::Now(); |
| 500 } |
| 501 |
400 IdentityAPI::IdentityAPI(Profile* profile) | 502 IdentityAPI::IdentityAPI(Profile* profile) |
401 : profile_(profile), | 503 : profile_(profile), |
402 signin_manager_(NULL), | 504 signin_manager_(NULL), |
403 error_(GoogleServiceAuthError::NONE) { | 505 error_(GoogleServiceAuthError::NONE) { |
404 (new OAuth2ManifestHandler)->Register(); | 506 (new OAuth2ManifestHandler)->Register(); |
405 } | 507 } |
406 | 508 |
407 IdentityAPI::~IdentityAPI() { | 509 IdentityAPI::~IdentityAPI() { |
408 } | 510 } |
409 | 511 |
410 void IdentityAPI::Initialize() { | 512 void IdentityAPI::Initialize() { |
411 signin_manager_ = SigninManagerFactory::GetForProfile(profile_); | 513 signin_manager_ = SigninManagerFactory::GetForProfile(profile_); |
412 signin_manager_->signin_global_error()->AddProvider(this); | 514 signin_manager_->signin_global_error()->AddProvider(this); |
413 | 515 |
414 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | 516 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
415 registrar_.Add(this, | 517 registrar_.Add(this, |
416 chrome::NOTIFICATION_TOKEN_AVAILABLE, | 518 chrome::NOTIFICATION_TOKEN_AVAILABLE, |
417 content::Source<TokenService>(token_service)); | 519 content::Source<TokenService>(token_service)); |
418 } | 520 } |
419 | 521 |
420 IdentityMintRequestQueue* IdentityAPI::mint_queue() { | 522 IdentityMintRequestQueue* IdentityAPI::mint_queue() { |
421 return &mint_queue_; | 523 return &mint_queue_; |
422 } | 524 } |
423 | 525 |
| 526 void IdentityAPI::SetCachedToken(const std::string& extension_id, |
| 527 const std::vector<std::string> scopes, |
| 528 const IdentityTokenCacheValue& token_data) { |
| 529 std::set<std::string> scopeset(scopes.begin(), scopes.end()); |
| 530 TokenCacheKey key(extension_id, scopeset); |
| 531 |
| 532 std::map<TokenCacheKey, IdentityTokenCacheValue>::iterator it = |
| 533 token_cache_.find(key); |
| 534 if (it != token_cache_.end() && it->second.status() <= token_data.status()) |
| 535 token_cache_.erase(it); |
| 536 |
| 537 token_cache_.insert(std::make_pair(key, token_data)); |
| 538 } |
| 539 |
| 540 void IdentityAPI::EraseCachedToken(const std::string& extension_id, |
| 541 const std::string& token) { |
| 542 std::map<TokenCacheKey, IdentityTokenCacheValue>::iterator it; |
| 543 for (it = token_cache_.begin(); it != token_cache_.end(); ++it) { |
| 544 if (it->first.extension_id == extension_id && |
| 545 it->second.status() == IdentityTokenCacheValue::CACHE_STATUS_TOKEN && |
| 546 it->second.token() == token) { |
| 547 token_cache_.erase(it); |
| 548 break; |
| 549 } |
| 550 } |
| 551 } |
| 552 |
| 553 void IdentityAPI::EraseAllCachedTokens() { |
| 554 token_cache_.clear(); |
| 555 } |
| 556 |
| 557 const IdentityTokenCacheValue& IdentityAPI::GetCachedToken( |
| 558 const std::string& extension_id, const std::vector<std::string> scopes) { |
| 559 std::set<std::string> scopeset(scopes.begin(), scopes.end()); |
| 560 TokenCacheKey key(extension_id, scopeset); |
| 561 return token_cache_[key]; |
| 562 } |
| 563 |
424 void IdentityAPI::ReportAuthError(const GoogleServiceAuthError& error) { | 564 void IdentityAPI::ReportAuthError(const GoogleServiceAuthError& error) { |
425 if (!signin_manager_) | 565 if (!signin_manager_) |
426 Initialize(); | 566 Initialize(); |
427 | 567 |
428 error_ = error; | 568 error_ = error; |
429 signin_manager_->signin_global_error()->AuthStatusChanged(); | 569 signin_manager_->signin_global_error()->AuthStatusChanged(); |
430 } | 570 } |
431 | 571 |
432 void IdentityAPI::Shutdown() { | 572 void IdentityAPI::Shutdown() { |
433 if (signin_manager_) | 573 if (signin_manager_) |
(...skipping 25 matching lines...) Expand all Loading... |
459 } | 599 } |
460 } | 600 } |
461 | 601 |
462 template <> | 602 template <> |
463 void ProfileKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies() { | 603 void ProfileKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies() { |
464 DependsOn(ExtensionSystemFactory::GetInstance()); | 604 DependsOn(ExtensionSystemFactory::GetInstance()); |
465 DependsOn(TokenServiceFactory::GetInstance()); | 605 DependsOn(TokenServiceFactory::GetInstance()); |
466 DependsOn(SigninManagerFactory::GetInstance()); | 606 DependsOn(SigninManagerFactory::GetInstance()); |
467 } | 607 } |
468 | 608 |
| 609 IdentityAPI::TokenCacheKey::TokenCacheKey(const std::string& extension_id, |
| 610 const std::set<std::string> scopes) |
| 611 : extension_id(extension_id), |
| 612 scopes(scopes) { |
| 613 } |
| 614 |
| 615 IdentityAPI::TokenCacheKey::~TokenCacheKey() { |
| 616 } |
| 617 |
| 618 bool IdentityAPI::TokenCacheKey::operator<( |
| 619 const IdentityAPI::TokenCacheKey& rhs) const { |
| 620 if (extension_id < rhs.extension_id) |
| 621 return true; |
| 622 else if (rhs.extension_id < extension_id) |
| 623 return false; |
| 624 |
| 625 return scopes < rhs.scopes; |
| 626 } |
| 627 |
469 } // namespace extensions | 628 } // namespace extensions |
OLD | NEW |