| 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 |
| 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/strings/string_number_conversions.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chrome/browser/app_mode/app_mode_utils.h" | 15 #include "chrome/browser/app_mode/app_mode_utils.h" |
| 16 #include "chrome/browser/extensions/extension_function_dispatcher.h" | 16 #include "chrome/browser/extensions/extension_function_dispatcher.h" |
| 17 #include "chrome/browser/extensions/extension_install_prompt.h" | |
| 18 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
| 19 #include "chrome/browser/extensions/permissions_updater.h" | |
| 20 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 21 #include "chrome/browser/signin/signin_manager.h" | 19 #include "chrome/browser/signin/signin_manager.h" |
| 22 #include "chrome/browser/signin/signin_manager_factory.h" | 20 #include "chrome/browser/signin/signin_manager_factory.h" |
| 23 #include "chrome/browser/signin/token_service.h" | 21 #include "chrome/browser/signin/token_service.h" |
| 24 #include "chrome/browser/signin/token_service_factory.h" | 22 #include "chrome/browser/signin/token_service_factory.h" |
| 25 #include "chrome/browser/ui/browser.h" | |
| 26 #include "chrome/common/extensions/api/identity.h" | 23 #include "chrome/common/extensions/api/identity.h" |
| 27 #include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h" | 24 #include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h" |
| 28 #include "chrome/common/extensions/extension.h" | 25 #include "chrome/common/extensions/extension.h" |
| 29 #include "chrome/common/extensions/extension_manifest_constants.h" | 26 #include "chrome/common/extensions/extension_manifest_constants.h" |
| 30 #include "chrome/common/url_constants.h" | 27 #include "chrome/common/url_constants.h" |
| 31 #include "content/public/common/page_transition_types.h" | |
| 32 #include "google_apis/gaia/gaia_constants.h" | 28 #include "google_apis/gaia/gaia_constants.h" |
| 33 #include "googleurl/src/gurl.h" | 29 #include "googleurl/src/gurl.h" |
| 34 #include "ui/base/window_open_disposition.h" | |
| 35 | 30 |
| 36 #if defined(OS_CHROMEOS) | 31 #if defined(OS_CHROMEOS) |
| 37 #include "chrome/browser/chromeos/login/user_manager.h" | 32 #include "chrome/browser/chromeos/login/user_manager.h" |
| 38 #endif | 33 #endif |
| 39 | 34 |
| 40 namespace extensions { | 35 namespace extensions { |
| 41 | 36 |
| 42 namespace identity_constants { | 37 namespace identity_constants { |
| 43 const char kInvalidClientId[] = "Invalid OAuth2 Client ID."; | 38 const char kInvalidClientId[] = "Invalid OAuth2 Client ID."; |
| 44 const char kInvalidScopes[] = "Invalid OAuth2 scopes."; | 39 const char kInvalidScopes[] = "Invalid OAuth2 scopes."; |
| 45 const char kAuthFailure[] = "OAuth2 request failed: "; | 40 const char kAuthFailure[] = "OAuth2 request failed: "; |
| 46 const char kNoGrant[] = "OAuth2 not granted or revoked."; | 41 const char kNoGrant[] = "OAuth2 not granted or revoked."; |
| 47 const char kUserRejected[] = "The user did not approve access."; | 42 const char kUserRejected[] = "The user did not approve access."; |
| 48 const char kUserNotSignedIn[] = "The user is not signed in."; | 43 const char kUserNotSignedIn[] = "The user is not signed in."; |
| 49 const char kInteractionRequired[] = "User interaction required."; | 44 const char kInteractionRequired[] = "User interaction required."; |
| 50 const char kInvalidRedirect[] = "Did not redirect to the right URL."; | 45 const char kInvalidRedirect[] = "Did not redirect to the right URL."; |
| 51 const char kOffTheRecord[] = "Identity API is disabled in incognito windows."; | 46 const char kOffTheRecord[] = "Identity API is disabled in incognito windows."; |
| 47 const char kPageLoadFailure[] = "Authorization page could not be loaded."; |
| 52 | 48 |
| 53 const int kCachedIssueAdviceTTLSeconds = 1; | 49 const int kCachedIssueAdviceTTLSeconds = 1; |
| 54 } // namespace identity_constants | 50 } // namespace identity_constants |
| 55 | 51 |
| 56 namespace { | 52 namespace { |
| 57 | 53 |
| 58 static const char kChromiumDomainRedirectUrlPattern[] = | 54 static const char kChromiumDomainRedirectUrlPattern[] = |
| 59 "https://%s.chromiumapp.org/"; | 55 "https://%s.chromiumapp.org/"; |
| 60 | 56 |
| 61 } // namespace | 57 } // namespace |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 | 305 |
| 310 case GaiaWebAuthFlow::SERVICE_AUTH_ERROR: | 306 case GaiaWebAuthFlow::SERVICE_AUTH_ERROR: |
| 311 error = std::string(identity_constants::kAuthFailure) + | 307 error = std::string(identity_constants::kAuthFailure) + |
| 312 service_error.ToString(); | 308 service_error.ToString(); |
| 313 break; | 309 break; |
| 314 | 310 |
| 315 case GaiaWebAuthFlow::OAUTH_ERROR: | 311 case GaiaWebAuthFlow::OAUTH_ERROR: |
| 316 error = MapOAuth2ErrorToDescription(oauth_error); | 312 error = MapOAuth2ErrorToDescription(oauth_error); |
| 317 break; | 313 break; |
| 318 | 314 |
| 315 // TODO(courage): load failure tests |
| 316 |
| 317 case GaiaWebAuthFlow::LOAD_FAILED: |
| 318 error = identity_constants::kPageLoadFailure; |
| 319 break; |
| 320 |
| 319 default: | 321 default: |
| 320 NOTREACHED() << "Unexpected error from gaia web auth flow: " << failure; | 322 NOTREACHED() << "Unexpected error from gaia web auth flow: " << failure; |
| 321 error = identity_constants::kInvalidRedirect; | 323 error = identity_constants::kInvalidRedirect; |
| 322 break; | 324 break; |
| 323 } | 325 } |
| 324 | 326 |
| 325 CompleteFunctionWithError(error); | 327 CompleteFunctionWithError(error); |
| 326 } | 328 } |
| 327 | 329 |
| 328 void IdentityGetAuthTokenFunction::OnGaiaFlowCompleted( | 330 void IdentityGetAuthTokenFunction::OnGaiaFlowCompleted( |
| (...skipping 19 matching lines...) Expand all Loading... |
| 348 mint_token_flow_->Start(); | 350 mint_token_flow_->Start(); |
| 349 } | 351 } |
| 350 | 352 |
| 351 void IdentityGetAuthTokenFunction::ShowLoginPopup() { | 353 void IdentityGetAuthTokenFunction::ShowLoginPopup() { |
| 352 signin_flow_.reset(new IdentitySigninFlow(this, profile())); | 354 signin_flow_.reset(new IdentitySigninFlow(this, profile())); |
| 353 signin_flow_->Start(); | 355 signin_flow_->Start(); |
| 354 } | 356 } |
| 355 | 357 |
| 356 void IdentityGetAuthTokenFunction::ShowOAuthApprovalDialog( | 358 void IdentityGetAuthTokenFunction::ShowOAuthApprovalDialog( |
| 357 const IssueAdviceInfo& issue_advice) { | 359 const IssueAdviceInfo& issue_advice) { |
| 358 Browser* current_browser = this->GetCurrentBrowser(); | |
| 359 chrome::HostDesktopType host_desktop_type = | |
| 360 current_browser ? current_browser->host_desktop_type() | |
| 361 : chrome::GetActiveDesktop(); | |
| 362 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); | 360 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); |
| 363 | 361 |
| 364 gaia_web_auth_flow_.reset(new GaiaWebAuthFlow( | 362 gaia_web_auth_flow_.reset(new GaiaWebAuthFlow( |
| 365 this, profile(), host_desktop_type, GetExtension()->id(), oauth2_info)); | 363 this, profile(), GetExtension()->id(), oauth2_info)); |
| 366 gaia_web_auth_flow_->Start(); | 364 gaia_web_auth_flow_->Start(); |
| 367 } | 365 } |
| 368 | 366 |
| 369 OAuth2MintTokenFlow* IdentityGetAuthTokenFunction::CreateMintTokenFlow( | 367 OAuth2MintTokenFlow* IdentityGetAuthTokenFunction::CreateMintTokenFlow( |
| 370 OAuth2MintTokenFlow::Mode mode) { | 368 OAuth2MintTokenFlow::Mode mode) { |
| 371 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); | 369 const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); |
| 372 OAuth2MintTokenFlow* mint_token_flow = | 370 OAuth2MintTokenFlow* mint_token_flow = |
| 373 new OAuth2MintTokenFlow( | 371 new OAuth2MintTokenFlow( |
| 374 profile()->GetRequestContext(), | 372 profile()->GetRequestContext(), |
| 375 this, | 373 this, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 | 449 |
| 452 GURL auth_url(params->details.url); | 450 GURL auth_url(params->details.url); |
| 453 WebAuthFlow::Mode mode = | 451 WebAuthFlow::Mode mode = |
| 454 params->details.interactive && *params->details.interactive ? | 452 params->details.interactive && *params->details.interactive ? |
| 455 WebAuthFlow::INTERACTIVE : WebAuthFlow::SILENT; | 453 WebAuthFlow::INTERACTIVE : WebAuthFlow::SILENT; |
| 456 | 454 |
| 457 // Set up acceptable target URLs. (Does not include chrome-extension | 455 // Set up acceptable target URLs. (Does not include chrome-extension |
| 458 // scheme for this version of the API.) | 456 // scheme for this version of the API.) |
| 459 InitFinalRedirectURLPrefix(GetExtension()->id()); | 457 InitFinalRedirectURLPrefix(GetExtension()->id()); |
| 460 | 458 |
| 461 gfx::Rect initial_bounds; | |
| 462 | |
| 463 AddRef(); // Balanced in OnAuthFlowSuccess/Failure. | 459 AddRef(); // Balanced in OnAuthFlowSuccess/Failure. |
| 464 | 460 |
| 465 Browser* current_browser = this->GetCurrentBrowser(); | 461 auth_flow_.reset(new WebAuthFlow(this, profile(), auth_url, mode)); |
| 466 chrome::HostDesktopType host_desktop_type = current_browser ? | |
| 467 current_browser->host_desktop_type() : chrome::GetActiveDesktop(); | |
| 468 auth_flow_.reset(new WebAuthFlow( | |
| 469 this, profile(), auth_url, mode, initial_bounds, | |
| 470 host_desktop_type)); | |
| 471 auth_flow_->Start(); | 462 auth_flow_->Start(); |
| 472 return true; | 463 return true; |
| 473 } | 464 } |
| 474 | 465 |
| 475 void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefixForTest( | 466 void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefixForTest( |
| 476 const std::string& extension_id) { | 467 const std::string& extension_id) { |
| 477 InitFinalRedirectURLPrefix(extension_id); | 468 InitFinalRedirectURLPrefix(extension_id); |
| 478 } | 469 } |
| 479 | 470 |
| 480 void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefix( | 471 void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefix( |
| 481 const std::string& extension_id) { | 472 const std::string& extension_id) { |
| 482 if (final_url_prefix_.is_empty()) { | 473 if (final_url_prefix_.is_empty()) { |
| 483 final_url_prefix_ = GURL(base::StringPrintf( | 474 final_url_prefix_ = GURL(base::StringPrintf( |
| 484 kChromiumDomainRedirectUrlPattern, extension_id.c_str())); | 475 kChromiumDomainRedirectUrlPattern, extension_id.c_str())); |
| 485 } | 476 } |
| 486 } | 477 } |
| 487 | 478 |
| 488 void IdentityLaunchWebAuthFlowFunction::OnAuthFlowFailure( | 479 void IdentityLaunchWebAuthFlowFunction::OnAuthFlowFailure( |
| 489 WebAuthFlow::Failure failure) { | 480 WebAuthFlow::Failure failure) { |
| 490 switch (failure) { | 481 switch (failure) { |
| 491 case WebAuthFlow::WINDOW_CLOSED: | 482 case WebAuthFlow::WINDOW_CLOSED: |
| 492 error_ = identity_constants::kUserRejected; | 483 error_ = identity_constants::kUserRejected; |
| 493 break; | 484 break; |
| 494 case WebAuthFlow::INTERACTION_REQUIRED: | 485 case WebAuthFlow::INTERACTION_REQUIRED: |
| 495 error_ = identity_constants::kInteractionRequired; | 486 error_ = identity_constants::kInteractionRequired; |
| 496 break; | 487 break; |
| 488 case WebAuthFlow::LOAD_FAILED: |
| 489 error_ = identity_constants::kPageLoadFailure; |
| 490 break; |
| 497 default: | 491 default: |
| 498 NOTREACHED() << "Unexpected error from web auth flow: " << failure; | 492 NOTREACHED() << "Unexpected error from web auth flow: " << failure; |
| 499 error_ = identity_constants::kInvalidRedirect; | 493 error_ = identity_constants::kInvalidRedirect; |
| 500 break; | 494 break; |
| 501 } | 495 } |
| 502 SendResponse(false); | 496 SendResponse(false); |
| 503 Release(); // Balanced in RunImpl. | 497 Release(); // Balanced in RunImpl. |
| 504 } | 498 } |
| 505 | 499 |
| 506 void IdentityLaunchWebAuthFlowFunction::OnAuthFlowURLChange( | 500 void IdentityLaunchWebAuthFlowFunction::OnAuthFlowURLChange( |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 const IdentityAPI::TokenCacheKey& rhs) const { | 671 const IdentityAPI::TokenCacheKey& rhs) const { |
| 678 if (extension_id < rhs.extension_id) | 672 if (extension_id < rhs.extension_id) |
| 679 return true; | 673 return true; |
| 680 else if (rhs.extension_id < extension_id) | 674 else if (rhs.extension_id < extension_id) |
| 681 return false; | 675 return false; |
| 682 | 676 |
| 683 return scopes < rhs.scopes; | 677 return scopes < rhs.scopes; |
| 684 } | 678 } |
| 685 | 679 |
| 686 } // namespace extensions | 680 } // namespace extensions |
| OLD | NEW |