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