Index: chrome/browser/signin/dice_response_handler.cc |
diff --git a/chrome/browser/signin/dice_response_handler.cc b/chrome/browser/signin/dice_response_handler.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..89835ba845cc7bee112857fa858fd9036aa1e3b8 |
--- /dev/null |
+++ b/chrome/browser/signin/dice_response_handler.cc |
@@ -0,0 +1,133 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/signin/dice_response_handler.h" |
+ |
+#include "base/memory/singleton.h" |
+#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/signin/chrome_signin_client_factory.h" |
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
+#include "components/keyed_service/content/browser_context_dependency_manager.h" |
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h" |
+#include "components/signin/core/browser/profile_oauth2_token_service.h" |
+#include "components/signin/core/browser/signin_client.h" |
+#include "components/signin/core/browser/signin_header_helper.h" |
+#include "components/signin/core/common/profile_management_switches.h" |
+#include "google_apis/gaia/gaia_auth_fetcher.h" |
+#include "google_apis/gaia/gaia_constants.h" |
+#include "google_apis/gaia/google_service_auth_error.h" |
+#include "google_apis/gaia/oauth2_token_service_delegate.h" |
+ |
+namespace { |
+ |
+class DiceResponseHandlerFactory : public BrowserContextKeyedServiceFactory { |
+ public: |
+ // Returns an instance of the factory singleton. |
+ static DiceResponseHandlerFactory* GetInstance() { |
+ return base::Singleton<DiceResponseHandlerFactory>::get(); |
+ } |
+ |
+ static DiceResponseHandler* GetForProfile(Profile* profile) { |
+ return static_cast<DiceResponseHandler*>( |
+ GetInstance()->GetServiceForBrowserContext(profile, true)); |
+ } |
+ |
+ private: |
+ friend struct base::DefaultSingletonTraits<DiceResponseHandlerFactory>; |
+ |
+ DiceResponseHandlerFactory() |
+ : BrowserContextKeyedServiceFactory( |
+ "DiceResponseHandler", |
+ BrowserContextDependencyManager::GetInstance()) { |
+ DependsOn(ChromeSigninClientFactory::GetInstance()); |
+ DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); |
+ } |
+ |
+ ~DiceResponseHandlerFactory() override {} |
+ |
+ // BrowserContextKeyedServiceFactory: |
+ KeyedService* BuildServiceInstanceFor( |
+ content::BrowserContext* context) const override { |
+ if (context->IsOffTheRecord()) |
+ return nullptr; |
+ |
+ Profile* profile = static_cast<Profile*>(context); |
+ return new DiceResponseHandler( |
+ ChromeSigninClientFactory::GetForProfile(profile), |
+ ProfileOAuth2TokenServiceFactory::GetForProfile(profile) |
+ ->GetDelegate()); |
+ } |
+}; |
+ |
+} // namespace |
+ |
+// static |
+DiceResponseHandler* DiceResponseHandler::GetForProfile(Profile* profile) { |
+ return DiceResponseHandlerFactory::GetForProfile(profile); |
+} |
+ |
+DiceResponseHandler::DiceResponseHandler( |
+ SigninClient* signin_client, |
+ OAuth2TokenServiceDelegate* oauth2_token_service_delegate) |
+ : signin_client_(signin_client), |
+ oauth2_token_service_delegate_(oauth2_token_service_delegate) { |
+ DCHECK(signin_client_); |
+ DCHECK(oauth2_token_service_delegate_); |
+} |
+ |
+DiceResponseHandler::~DiceResponseHandler() {} |
+ |
+void DiceResponseHandler::ProcessDiceHeader( |
+ const signin::DiceResponseParams& dice_params) { |
+ DCHECK_EQ(switches::AccountConsistencyMethod::kDice, |
+ switches::GetAccountConsistencyMethod()); |
+ |
+ switch (dice_params.user_intention) { |
+ case signin::DiceAction::SIGNIN: |
msarda
2017/06/20 08:45:22
In Chrome there are multiple notions of account id
droger
2017/06/20 11:01:27
As discussed offline, I did not use PickAccountIdF
|
+ ProcessDiceSigninHeader(dice_params.email, |
+ dice_params.authorization_code); |
+ return; |
+ case signin::DiceAction::SIGNOUT: |
+ case signin::DiceAction::SINGLE_SESSION_SIGNOUT: |
+ NOTIMPLEMENTED() << "Signout through Dice is not implemented."; |
msarda
2017/06/20 08:45:22
I think this should not be NOTIMPLEMENTED as the s
droger
2017/06/20 11:01:27
Done.
|
+ return; |
+ case signin::DiceAction::NONE: |
+ NOTREACHED() << "Invalid Dice response parameters."; |
+ return; |
+ } |
+ |
+ NOTREACHED(); |
+ return; |
+} |
+ |
+void DiceResponseHandler::ProcessDiceSigninHeader( |
+ const std::string& account_id, |
+ const std::string& authorization_code) { |
+ DCHECK(!gaia_auth_fetcher_); |
+ DCHECK(account_id_for_signin_.empty()); |
+ account_id_for_signin_ = account_id; |
+ gaia_auth_fetcher_ = signin_client_->CreateGaiaAuthFetcher( |
+ this, GaiaConstants::kChromeSource, |
+ signin_client_->GetURLRequestContext()); |
+ gaia_auth_fetcher_->StartAuthCodeForOAuth2TokenExchange(authorization_code); |
+ |
+ // TODO(droger): The token exchange must complete quicly or be cancelled. Add |
msarda
2017/06/20 08:45:23
s/quicly/quickly
droger
2017/06/20 11:01:27
Done.
|
+ // a timeout logic. |
+} |
+ |
+void DiceResponseHandler::OnClientOAuthSuccess( |
+ const ClientOAuthResult& result) { |
+ oauth2_token_service_delegate_->UpdateCredentials(account_id_for_signin_, |
msarda
2017/06/20 08:45:22
Use the token service (not its delegate) to update
msarda
2017/06/20 08:45:22
Before calling UpdateCredentials, please also seed
droger
2017/06/20 11:01:28
Done.
|
+ result.refresh_token); |
+ account_id_for_signin_.clear(); |
+ gaia_auth_fetcher_.reset(); |
+} |
+ |
+void DiceResponseHandler::OnClientOAuthFailure( |
+ const GoogleServiceAuthError& error) { |
+ // TODO(droger): Handle authentication errors. |
+ DLOG(ERROR) << "Dice OAuth failed: " << error.error_message(); |
+ account_id_for_signin_.clear(); |
+ gaia_auth_fetcher_.reset(); |
+} |