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

Side by Side Diff: chrome/browser/extensions/api/identity/identity_api.cc

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

Powered by Google App Engine
This is Rietveld 408576698