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

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

Issue 15148007: Identity API: web-based scope approval dialogs for getAuthToken (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: windows build fix Created 7 years, 7 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
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
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/stringprintf.h" 12 #include "base/stringprintf.h"
13 #include "base/strings/string_number_conversions.h"
13 #include "base/values.h" 14 #include "base/values.h"
14 #include "chrome/browser/app_mode/app_mode_utils.h" 15 #include "chrome/browser/app_mode/app_mode_utils.h"
15 #include "chrome/browser/extensions/extension_function_dispatcher.h" 16 #include "chrome/browser/extensions/extension_function_dispatcher.h"
16 #include "chrome/browser/extensions/extension_install_prompt.h" 17 #include "chrome/browser/extensions/extension_install_prompt.h"
17 #include "chrome/browser/extensions/extension_service.h" 18 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/extensions/permissions_updater.h" 19 #include "chrome/browser/extensions/permissions_updater.h"
19 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/signin/signin_manager.h" 21 #include "chrome/browser/signin/signin_manager.h"
21 #include "chrome/browser/signin/signin_manager_factory.h" 22 #include "chrome/browser/signin/signin_manager_factory.h"
22 #include "chrome/browser/signin/token_service.h" 23 #include "chrome/browser/signin/token_service.h"
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE); 218 StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
218 break; 219 break;
219 } 220 }
220 } else { 221 } else {
221 DCHECK(type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE); 222 DCHECK(type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
222 223
223 if (cache_status == IdentityTokenCacheValue::CACHE_STATUS_TOKEN) { 224 if (cache_status == IdentityTokenCacheValue::CACHE_STATUS_TOKEN) {
224 CompleteMintTokenFlow(); 225 CompleteMintTokenFlow();
225 CompleteFunctionWithResult(cache_entry.token()); 226 CompleteFunctionWithResult(cache_entry.token());
226 } else { 227 } else {
227 install_ui_.reset(new ExtensionInstallPrompt(GetAssociatedWebContents()));
228 ShowOAuthApprovalDialog(issue_advice_); 228 ShowOAuthApprovalDialog(issue_advice_);
229 } 229 }
230 } 230 }
231 } 231 }
232 232
233 void IdentityGetAuthTokenFunction::OnMintTokenSuccess( 233 void IdentityGetAuthTokenFunction::OnMintTokenSuccess(
234 const std::string& access_token, int time_to_live) { 234 const std::string& access_token, int time_to_live) {
235 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); 235 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
236 IdentityTokenCacheValue token(access_token, 236 IdentityTokenCacheValue token(access_token,
237 base::TimeDelta::FromSeconds(time_to_live)); 237 base::TimeDelta::FromSeconds(time_to_live));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 284
285 void IdentityGetAuthTokenFunction::SigninSuccess(const std::string& token) { 285 void IdentityGetAuthTokenFunction::SigninSuccess(const std::string& token) {
286 refresh_token_ = token; 286 refresh_token_ = token;
287 StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE); 287 StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE);
288 } 288 }
289 289
290 void IdentityGetAuthTokenFunction::SigninFailed() { 290 void IdentityGetAuthTokenFunction::SigninFailed() {
291 CompleteFunctionWithError(identity_constants::kUserNotSignedIn); 291 CompleteFunctionWithError(identity_constants::kUserNotSignedIn);
292 } 292 }
293 293
294 void IdentityGetAuthTokenFunction::InstallUIProceed() { 294 void IdentityGetAuthTokenFunction::OnGaiaFlowFailure(
295 // The user has accepted the scopes, so we may now force (recording a grant 295 GaiaWebAuthFlow::Failure failure,
296 // and receiving a token). 296 GoogleServiceAuthError service_error) {
297 StartGaiaRequest(OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE); 297 CompleteMintTokenFlow();
298 std::string error;
299
300 switch (failure) {
301 case GaiaWebAuthFlow::WINDOW_CLOSED:
302 error = identity_constants::kUserRejected;
303 break;
304
305 case GaiaWebAuthFlow::INVALID_REDIRECT:
306 error = identity_constants::kInvalidRedirect;
307 break;
308
309 case GaiaWebAuthFlow::SERVICE_AUTH_ERROR:
310 error = std::string(identity_constants::kAuthFailure) +
311 service_error.ToString();
312 break;
313
314 default:
315 NOTREACHED() << "Unexpected error from gaia web auth flow: " << failure;
316 error = identity_constants::kInvalidRedirect;
317 break;
318 }
319
320 CompleteFunctionWithError(error);
298 } 321 }
299 322
300 void IdentityGetAuthTokenFunction::InstallUIAbort(bool user_initiated) { 323 void IdentityGetAuthTokenFunction::OnGaiaFlowCompleted(
324 const std::string& access_token,
325 const std::string& expiration,
326 const std::string& error) {
327 if (!error.empty()) {
328 CompleteMintTokenFlow();
329 CompleteFunctionWithError(MapOAuth2ErrorToDescription(error));
330 return;
331 }
332
333 int time_to_live;
334 if (!expiration.empty() && base::StringToInt(expiration, &time_to_live)) {
335 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
336 IdentityTokenCacheValue token_value(
337 access_token, base::TimeDelta::FromSeconds(time_to_live));
338 IdentityAPI::GetFactoryInstance()->GetForProfile(profile())
339 ->SetCachedToken(GetExtension()->id(), oauth2_info.scopes, token_value);
340 }
341
301 CompleteMintTokenFlow(); 342 CompleteMintTokenFlow();
302 CompleteFunctionWithError(identity_constants::kUserRejected); 343 CompleteFunctionWithResult(access_token);
303 } 344 }
304 345
305 void IdentityGetAuthTokenFunction::StartGaiaRequest( 346 void IdentityGetAuthTokenFunction::StartGaiaRequest(
306 OAuth2MintTokenFlow::Mode mode) { 347 OAuth2MintTokenFlow::Mode mode) {
307 mint_token_flow_.reset(CreateMintTokenFlow(mode)); 348 mint_token_flow_.reset(CreateMintTokenFlow(mode));
308 mint_token_flow_->Start(); 349 mint_token_flow_->Start();
309 } 350 }
310 351
311 void IdentityGetAuthTokenFunction::ShowLoginPopup() { 352 void IdentityGetAuthTokenFunction::ShowLoginPopup() {
312 signin_flow_.reset(new IdentitySigninFlow(this, profile())); 353 signin_flow_.reset(new IdentitySigninFlow(this, profile()));
313 signin_flow_->Start(); 354 signin_flow_->Start();
314 } 355 }
315 356
316 void IdentityGetAuthTokenFunction::ShowOAuthApprovalDialog( 357 void IdentityGetAuthTokenFunction::ShowOAuthApprovalDialog(
317 const IssueAdviceInfo& issue_advice) { 358 const IssueAdviceInfo& issue_advice) {
318 install_ui_->ConfirmIssueAdvice(this, GetExtension(), issue_advice); 359 Browser* current_browser = this->GetCurrentBrowser();
360 chrome::HostDesktopType host_desktop_type =
361 current_browser ? current_browser->host_desktop_type()
362 : chrome::GetActiveDesktop();
363 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
364
365 gaia_web_auth_flow_.reset(new GaiaWebAuthFlow(
366 this, profile(), host_desktop_type, GetExtension()->id(), oauth2_info));
367 gaia_web_auth_flow_->Start();
319 } 368 }
320 369
321 OAuth2MintTokenFlow* IdentityGetAuthTokenFunction::CreateMintTokenFlow( 370 OAuth2MintTokenFlow* IdentityGetAuthTokenFunction::CreateMintTokenFlow(
322 OAuth2MintTokenFlow::Mode mode) { 371 OAuth2MintTokenFlow::Mode mode) {
323 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); 372 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
324 OAuth2MintTokenFlow* mint_token_flow = 373 OAuth2MintTokenFlow* mint_token_flow =
325 new OAuth2MintTokenFlow( 374 new OAuth2MintTokenFlow(
326 profile()->GetRequestContext(), 375 profile()->GetRequestContext(),
327 this, 376 this,
328 OAuth2MintTokenFlow::Parameters( 377 OAuth2MintTokenFlow::Parameters(
(...skipping 14 matching lines...) Expand all
343 } 392 }
344 #endif 393 #endif
345 return mint_token_flow; 394 return mint_token_flow;
346 } 395 }
347 396
348 bool IdentityGetAuthTokenFunction::HasLoginToken() const { 397 bool IdentityGetAuthTokenFunction::HasLoginToken() const {
349 TokenService* token_service = TokenServiceFactory::GetForProfile(profile()); 398 TokenService* token_service = TokenServiceFactory::GetForProfile(profile());
350 return token_service->HasOAuthLoginToken(); 399 return token_service->HasOAuthLoginToken();
351 } 400 }
352 401
402 std::string IdentityGetAuthTokenFunction::MapOAuth2ErrorToDescription(
403 const std::string& error) {
404 const char kOAuth2ErrorAccessDenied[] = "access_denied";
405 const char kOAuth2ErrorInvalidScope[] = "invalid_scope";
406
407 if (error == kOAuth2ErrorAccessDenied)
408 return std::string(identity_constants::kUserRejected);
409 else if (error == kOAuth2ErrorInvalidScope)
410 return std::string(identity_constants::kInvalidScopes);
411 else
412 return std::string(identity_constants::kAuthFailure) + error;
413 }
414
353 IdentityRemoveCachedAuthTokenFunction::IdentityRemoveCachedAuthTokenFunction() { 415 IdentityRemoveCachedAuthTokenFunction::IdentityRemoveCachedAuthTokenFunction() {
354 } 416 }
355 417
356 IdentityRemoveCachedAuthTokenFunction:: 418 IdentityRemoveCachedAuthTokenFunction::
357 ~IdentityRemoveCachedAuthTokenFunction() { 419 ~IdentityRemoveCachedAuthTokenFunction() {
358 } 420 }
359 421
360 bool IdentityRemoveCachedAuthTokenFunction::RunImpl() { 422 bool IdentityRemoveCachedAuthTokenFunction::RunImpl() {
361 if (profile()->IsOffTheRecord()) { 423 if (profile()->IsOffTheRecord()) {
362 error_ = identity_constants::kOffTheRecord; 424 error_ = identity_constants::kOffTheRecord;
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 const IdentityAPI::TokenCacheKey& rhs) const { 674 const IdentityAPI::TokenCacheKey& rhs) const {
613 if (extension_id < rhs.extension_id) 675 if (extension_id < rhs.extension_id)
614 return true; 676 return true;
615 else if (rhs.extension_id < extension_id) 677 else if (rhs.extension_id < extension_id)
616 return false; 678 return false;
617 679
618 return scopes < rhs.scopes; 680 return scopes < rhs.scopes;
619 } 681 }
620 682
621 } // namespace extensions 683 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698