Chromium Code Reviews| Index: chrome/browser/extensions/api/identity/identity_api.cc |
| diff --git a/chrome/browser/extensions/api/identity/identity_api.cc b/chrome/browser/extensions/api/identity/identity_api.cc |
| index 72658a33fcf26119ac4088fe958bfa6e838e4acc..b5a8a9ed8253829cd9102e61cbbd85f0e05e0623 100644 |
| --- a/chrome/browser/extensions/api/identity/identity_api.cc |
| +++ b/chrome/browser/extensions/api/identity/identity_api.cc |
| @@ -11,13 +11,11 @@ |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/extensions/permissions_updater.h" |
| #include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/signin/signin_manager.h" |
| +#include "chrome/browser/signin/signin_manager_factory.h" |
| #include "chrome/browser/signin/token_service.h" |
| #include "chrome/browser/signin/token_service_factory.h" |
| #include "chrome/browser/ui/browser.h" |
| -#include "chrome/browser/ui/browser_navigator.h" |
| -#include "chrome/browser/ui/webui/signin/login_ui_service.h" |
| -#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" |
| -#include "chrome/browser/ui/webui/sync_promo/sync_promo_ui.h" |
| #include "chrome/common/extensions/api/experimental_identity.h" |
| #include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h" |
| #include "chrome/common/extensions/extension.h" |
| @@ -25,6 +23,7 @@ |
| #include "chrome/common/extensions/manifest_handler.h" |
| #include "chrome/common/url_constants.h" |
| #include "content/public/common/page_transition_types.h" |
| +#include "google_apis/gaia/gaia_constants.h" |
| #include "googleurl/src/gurl.h" |
| #include "ui/base/window_open_disposition.h" |
| @@ -45,14 +44,19 @@ namespace LaunchWebAuthFlow = api::experimental_identity::LaunchWebAuthFlow; |
| namespace identity = api::experimental_identity; |
| IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction() |
| - : interactive_(false) {} |
| + : should_prompt_for_scopes_(false), |
| + should_prompt_for_signin_(false) {} |
| IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() {} |
| bool IdentityGetAuthTokenFunction::RunImpl() { |
| scoped_ptr<GetAuthToken::Params> params(GetAuthToken::Params::Create(*args_)); |
| EXTENSION_FUNCTION_VALIDATE(params.get()); |
| - if (params->details.get() && params->details->interactive.get()) |
| - interactive_ = *params->details->interactive; |
| + bool interactive = params->details.get() && |
| + params->details->interactive.get() && |
| + *params->details->interactive; |
| + |
| + should_prompt_for_scopes_ = interactive; |
| + should_prompt_for_signin_ = interactive; |
| const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); |
| @@ -68,24 +72,26 @@ bool IdentityGetAuthTokenFunction::RunImpl() { |
| } |
| // Balanced in OnIssueAdviceSuccess|OnMintTokenSuccess|OnMintTokenFailure| |
| - // InstallUIAbort|OnLoginUIClosed. |
| + // InstallUIAbort|SigninFailed. |
| AddRef(); |
| if (!HasLoginToken()) { |
| - if (StartLogin()) { |
| - return true; |
| - } else { |
| + if (!should_prompt_for_signin_) { |
| + error_ = identity_constants::kUserNotSignedIn; |
| Release(); |
| return false; |
| } |
| - } |
| - |
| - if (StartFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE)) { |
| - return true; |
| + // Display a login prompt. If the subsequent mint fails, don't display the |
| + // prompt again. |
| + should_prompt_for_signin_ = false; |
| + ShowLoginPopup(); |
| } else { |
| - Release(); |
| - return false; |
| + TokenService* token_service = TokenServiceFactory::GetForProfile(profile()); |
| + refresh_token_ = token_service->GetOAuth2LoginRefreshToken(); |
| + StartFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE); |
| } |
| + |
| + return true; |
| } |
| void IdentityGetAuthTokenFunction::OnMintTokenSuccess( |
| @@ -97,6 +103,24 @@ void IdentityGetAuthTokenFunction::OnMintTokenSuccess( |
| void IdentityGetAuthTokenFunction::OnMintTokenFailure( |
| const GoogleServiceAuthError& error) { |
| + switch (error.state()) { |
| + case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: |
| + case GoogleServiceAuthError::ACCOUNT_DELETED: |
| + case GoogleServiceAuthError::ACCOUNT_DISABLED: |
| + extensions::IdentityAPI::GetFactoryInstance()->GetForProfile( |
| + profile())->ReportAuthError(error); |
| + if (should_prompt_for_signin_) { |
| + // Display a login prompt and try again (once). |
| + should_prompt_for_signin_ = false; |
| + ShowLoginPopup(); |
| + return; |
| + } |
| + break; |
| + default: |
| + // Return error to caller. |
| + break; |
| + } |
| + |
| error_ = std::string(identity_constants::kAuthFailure) + error.ToString(); |
| SendResponse(false); |
| Release(); // Balanced in RunImpl. |
| @@ -104,9 +128,10 @@ void IdentityGetAuthTokenFunction::OnMintTokenFailure( |
| void IdentityGetAuthTokenFunction::OnIssueAdviceSuccess( |
| const IssueAdviceInfo& issue_advice) { |
| + should_prompt_for_signin_ = false; |
| // Existing grant was revoked and we used NO_FORCE, so we got info back |
| // instead. |
| - if (interactive_) { |
| + if (should_prompt_for_scopes_) { |
| install_ui_.reset(new ExtensionInstallPrompt(GetAssociatedWebContents())); |
| ShowOAuthApprovalDialog(issue_advice); |
| } else { |
| @@ -116,21 +141,22 @@ void IdentityGetAuthTokenFunction::OnIssueAdviceSuccess( |
| } |
| } |
| -void IdentityGetAuthTokenFunction::OnLoginUIClosed( |
| - LoginUIService::LoginUI* ui) { |
| - StopObservingLoginService(); |
| - if (!StartFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE)) { |
| - SendResponse(false); |
| - Release(); |
| - } |
| +void IdentityGetAuthTokenFunction::SigninSuccess(const std::string& token) { |
| + refresh_token_ = token; |
| + StartFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE); |
| +} |
| + |
| +void IdentityGetAuthTokenFunction::SigninFailed() { |
| + error_ = identity_constants::kUserNotSignedIn; |
|
Roger Tawa OOO till Jul 10th
2013/04/02 14:41:07
clear |refresh_token_| ?
Michael Courage
2013/04/02 17:17:49
Once we trigger the response, the whole object is
|
| + SendResponse(false); |
| + Release(); |
| } |
| void IdentityGetAuthTokenFunction::InstallUIProceed() { |
| DCHECK(install_ui_->record_oauth2_grant()); |
| // The user has accepted the scopes, so we may now force (recording a grant |
| // and receiving a token). |
| - bool success = StartFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE); |
| - DCHECK(success); |
| + StartFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE); |
| } |
| void IdentityGetAuthTokenFunction::InstallUIAbort(bool user_initiated) { |
| @@ -139,45 +165,15 @@ void IdentityGetAuthTokenFunction::InstallUIAbort(bool user_initiated) { |
| Release(); // Balanced in RunImpl. |
| } |
| -bool IdentityGetAuthTokenFunction::StartFlow(OAuth2MintTokenFlow::Mode mode) { |
| - if (!HasLoginToken()) { |
| - error_ = identity_constants::kUserNotSignedIn; |
| - return false; |
| - } |
| - |
| - flow_.reset(CreateMintTokenFlow(mode)); |
| - flow_->Start(); |
| - return true; |
| -} |
| - |
| -bool IdentityGetAuthTokenFunction::StartLogin() { |
| - if (!interactive_) { |
| - error_ = identity_constants::kUserNotSignedIn; |
| - return false; |
| - } |
| - |
| - ShowLoginPopup(); |
| - return true; |
| -} |
| - |
| -void IdentityGetAuthTokenFunction::StartObservingLoginService() { |
| - LoginUIService* login_ui_service = |
| - LoginUIServiceFactory::GetForProfile(profile()); |
| - login_ui_service->AddObserver(this); |
| -} |
| - |
| -void IdentityGetAuthTokenFunction::StopObservingLoginService() { |
| - LoginUIService* login_ui_service = |
| - LoginUIServiceFactory::GetForProfile(profile()); |
| - login_ui_service->RemoveObserver(this); |
| +void IdentityGetAuthTokenFunction::StartFlow(OAuth2MintTokenFlow::Mode mode) { |
| + signin_flow_.reset(NULL); |
| + mint_token_flow_.reset(CreateMintTokenFlow(mode)); |
| + mint_token_flow_->Start(); |
| } |
| void IdentityGetAuthTokenFunction::ShowLoginPopup() { |
| - StartObservingLoginService(); |
| - |
| - LoginUIService* login_ui_service = |
| - LoginUIServiceFactory::GetForProfile(profile()); |
| - login_ui_service->ShowLoginPopup(); |
| + signin_flow_.reset(new IdentitySigninFlow(this, profile())); |
| + signin_flow_->Start(); |
| } |
| void IdentityGetAuthTokenFunction::ShowOAuthApprovalDialog( |
| @@ -188,12 +184,11 @@ void IdentityGetAuthTokenFunction::ShowOAuthApprovalDialog( |
| OAuth2MintTokenFlow* IdentityGetAuthTokenFunction::CreateMintTokenFlow( |
| OAuth2MintTokenFlow::Mode mode) { |
| const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); |
| - TokenService* token_service = TokenServiceFactory::GetForProfile(profile()); |
| return new OAuth2MintTokenFlow( |
| profile()->GetRequestContext(), |
| this, |
| OAuth2MintTokenFlow::Parameters( |
| - token_service->GetOAuth2LoginRefreshToken(), |
| + refresh_token_, |
| GetExtension()->id(), |
| oauth2_info.client_id, |
| oauth2_info.scopes, |
| @@ -256,13 +251,39 @@ void IdentityLaunchWebAuthFlowFunction::OnAuthFlowFailure() { |
| Release(); // Balanced in RunImpl. |
| } |
| -IdentityAPI::IdentityAPI(Profile* profile) { |
| +IdentityAPI::IdentityAPI(Profile* profile) |
| + : profile_(profile), |
| + signin_manager_(NULL), |
| + error_(GoogleServiceAuthError::NONE) { |
| (new OAuth2ManifestHandler)->Register(); |
| } |
| IdentityAPI::~IdentityAPI() { |
| } |
| +void IdentityAPI::Initialize() { |
| + signin_manager_ = SigninManagerFactory::GetForProfile(profile_); |
| + signin_manager_->signin_global_error()->AddProvider(this); |
| + |
| + TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
| + registrar_.Add(this, |
| + chrome::NOTIFICATION_TOKEN_AVAILABLE, |
| + content::Source<TokenService>(token_service)); |
| +} |
| + |
| +void IdentityAPI::ReportAuthError(const GoogleServiceAuthError& error) { |
| + if (!signin_manager_) |
| + Initialize(); |
| + |
| + error_ = error; |
| + signin_manager_->signin_global_error()->AuthStatusChanged(); |
| +} |
| + |
| +void IdentityAPI::Shutdown() { |
| + if (signin_manager_) |
| + signin_manager_->signin_global_error()->RemoveProvider(this); |
| +} |
| + |
| static base::LazyInstance<ProfileKeyedAPIFactory<IdentityAPI> > |
| g_factory = LAZY_INSTANCE_INITIALIZER; |
| @@ -271,4 +292,28 @@ ProfileKeyedAPIFactory<IdentityAPI>* IdentityAPI::GetFactoryInstance() { |
| return &g_factory.Get(); |
| } |
| +GoogleServiceAuthError IdentityAPI::GetAuthStatus() const { |
| + return error_; |
| +} |
| + |
| +void IdentityAPI::Observe(int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) { |
| + CHECK(type == chrome::NOTIFICATION_TOKEN_AVAILABLE); |
| + TokenService::TokenAvailableDetails* token_details = |
| + content::Details<TokenService::TokenAvailableDetails>(details).ptr(); |
| + if (token_details->service() == |
| + GaiaConstants::kGaiaOAuth2LoginRefreshToken) { |
| + error_ = GoogleServiceAuthError::AuthErrorNone(); |
| + signin_manager_->signin_global_error()->AuthStatusChanged(); |
| + } |
| +} |
| + |
| +template <> |
| +void ProfileKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies() { |
| + DependsOn(ExtensionSystemFactory::GetInstance()); |
| + DependsOn(TokenServiceFactory::GetInstance()); |
| + DependsOn(SigninManagerFactory::GetInstance()); |
| +} |
| + |
| } // namespace extensions |