OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/signin/dice_response_handler.h" | 5 #include "chrome/browser/signin/dice_response_handler.h" |
6 | 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" |
| 9 #include "base/location.h" |
7 #include "base/logging.h" | 10 #include "base/logging.h" |
8 #include "base/memory/singleton.h" | 11 #include "base/memory/singleton.h" |
| 12 #include "base/threading/thread_task_runner_handle.h" |
| 13 #include "base/time/time.h" |
9 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
10 #include "chrome/browser/signin/account_tracker_service_factory.h" | 15 #include "chrome/browser/signin/account_tracker_service_factory.h" |
11 #include "chrome/browser/signin/chrome_signin_client_factory.h" | 16 #include "chrome/browser/signin/chrome_signin_client_factory.h" |
12 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" | 17 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
13 #include "components/keyed_service/content/browser_context_dependency_manager.h" | 18 #include "components/keyed_service/content/browser_context_dependency_manager.h" |
14 #include "components/keyed_service/content/browser_context_keyed_service_factory
.h" | 19 #include "components/keyed_service/content/browser_context_keyed_service_factory
.h" |
15 #include "components/signin/core/browser/account_tracker_service.h" | 20 #include "components/signin/core/browser/account_tracker_service.h" |
16 #include "components/signin/core/browser/profile_oauth2_token_service.h" | 21 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
17 #include "components/signin/core/browser/signin_client.h" | 22 #include "components/signin/core/browser/signin_client.h" |
18 #include "components/signin/core/browser/signin_header_helper.h" | 23 #include "components/signin/core/browser/signin_header_helper.h" |
19 #include "components/signin/core/common/profile_management_switches.h" | 24 #include "components/signin/core/common/profile_management_switches.h" |
20 #include "google_apis/gaia/gaia_auth_fetcher.h" | 25 #include "google_apis/gaia/gaia_auth_fetcher.h" |
21 #include "google_apis/gaia/gaia_constants.h" | 26 #include "google_apis/gaia/gaia_constants.h" |
22 #include "google_apis/gaia/google_service_auth_error.h" | 27 #include "google_apis/gaia/google_service_auth_error.h" |
23 | 28 |
| 29 const int kDiceTokenFetchTimeoutSeconds = 10; |
| 30 |
24 namespace { | 31 namespace { |
25 | 32 |
26 class DiceResponseHandlerFactory : public BrowserContextKeyedServiceFactory { | 33 class DiceResponseHandlerFactory : public BrowserContextKeyedServiceFactory { |
27 public: | 34 public: |
28 // Returns an instance of the factory singleton. | 35 // Returns an instance of the factory singleton. |
29 static DiceResponseHandlerFactory* GetInstance() { | 36 static DiceResponseHandlerFactory* GetInstance() { |
30 return base::Singleton<DiceResponseHandlerFactory>::get(); | 37 return base::Singleton<DiceResponseHandlerFactory>::get(); |
31 } | 38 } |
32 | 39 |
33 static DiceResponseHandler* GetForProfile(Profile* profile) { | 40 static DiceResponseHandler* GetForProfile(Profile* profile) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 | 78 |
72 DiceResponseHandler::DiceTokenFetcher::DiceTokenFetcher( | 79 DiceResponseHandler::DiceTokenFetcher::DiceTokenFetcher( |
73 const std::string& gaia_id, | 80 const std::string& gaia_id, |
74 const std::string& email, | 81 const std::string& email, |
75 const std::string& authorization_code, | 82 const std::string& authorization_code, |
76 SigninClient* signin_client, | 83 SigninClient* signin_client, |
77 DiceResponseHandler* dice_response_handler) | 84 DiceResponseHandler* dice_response_handler) |
78 : gaia_id_(gaia_id), | 85 : gaia_id_(gaia_id), |
79 email_(email), | 86 email_(email), |
80 authorization_code_(authorization_code), | 87 authorization_code_(authorization_code), |
81 dice_response_handler_(dice_response_handler) { | 88 dice_response_handler_(dice_response_handler), |
| 89 timeout_closure_( |
| 90 base::Bind(&DiceResponseHandler::DiceTokenFetcher::OnTimeout, |
| 91 base::Unretained(this))) { |
| 92 DCHECK(dice_response_handler_); |
82 gaia_auth_fetcher_ = signin_client->CreateGaiaAuthFetcher( | 93 gaia_auth_fetcher_ = signin_client->CreateGaiaAuthFetcher( |
83 this, GaiaConstants::kChromeSource, | 94 this, GaiaConstants::kChromeSource, |
84 signin_client->GetURLRequestContext()); | 95 signin_client->GetURLRequestContext()); |
85 gaia_auth_fetcher_->StartAuthCodeForOAuth2TokenExchange(authorization_code_); | 96 gaia_auth_fetcher_->StartAuthCodeForOAuth2TokenExchange(authorization_code_); |
86 | 97 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
87 // TODO(droger): The token exchange must complete quickly or be cancelled. Add | 98 FROM_HERE, timeout_closure_.callback(), |
88 // a timeout logic. | 99 base::TimeDelta::FromSeconds(kDiceTokenFetchTimeoutSeconds)); |
89 } | 100 } |
90 | 101 |
91 DiceResponseHandler::DiceTokenFetcher::~DiceTokenFetcher() {} | 102 DiceResponseHandler::DiceTokenFetcher::~DiceTokenFetcher() {} |
92 | 103 |
| 104 void DiceResponseHandler::DiceTokenFetcher::OnTimeout() { |
| 105 gaia_auth_fetcher_.reset(); |
| 106 timeout_closure_.Cancel(); |
| 107 dice_response_handler_->OnTokenExchangeFailure( |
| 108 this, GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED)); |
| 109 // |this| may be deleted at this point. |
| 110 } |
| 111 |
93 void DiceResponseHandler::DiceTokenFetcher::OnClientOAuthSuccess( | 112 void DiceResponseHandler::DiceTokenFetcher::OnClientOAuthSuccess( |
94 const GaiaAuthConsumer::ClientOAuthResult& result) { | 113 const GaiaAuthConsumer::ClientOAuthResult& result) { |
| 114 gaia_auth_fetcher_.reset(); |
| 115 timeout_closure_.Cancel(); |
95 dice_response_handler_->OnTokenExchangeSuccess(this, gaia_id_, email_, | 116 dice_response_handler_->OnTokenExchangeSuccess(this, gaia_id_, email_, |
96 result); | 117 result); |
| 118 // |this| may be deleted at this point. |
97 } | 119 } |
98 | 120 |
99 void DiceResponseHandler::DiceTokenFetcher::OnClientOAuthFailure( | 121 void DiceResponseHandler::DiceTokenFetcher::OnClientOAuthFailure( |
100 const GoogleServiceAuthError& error) { | 122 const GoogleServiceAuthError& error) { |
| 123 gaia_auth_fetcher_.reset(); |
| 124 timeout_closure_.Cancel(); |
101 dice_response_handler_->OnTokenExchangeFailure(this, error); | 125 dice_response_handler_->OnTokenExchangeFailure(this, error); |
| 126 // |this| may be deleted at this point. |
102 } | 127 } |
103 | 128 |
104 //////////////////////////////////////////////////////////////////////////////// | 129 //////////////////////////////////////////////////////////////////////////////// |
105 // DiceResponseHandler | 130 // DiceResponseHandler |
106 //////////////////////////////////////////////////////////////////////////////// | 131 //////////////////////////////////////////////////////////////////////////////// |
107 | 132 |
108 // static | 133 // static |
109 DiceResponseHandler* DiceResponseHandler::GetForProfile(Profile* profile) { | 134 DiceResponseHandler* DiceResponseHandler::GetForProfile(Profile* profile) { |
110 return DiceResponseHandlerFactory::GetForProfile(profile); | 135 return DiceResponseHandlerFactory::GetForProfile(profile); |
111 } | 136 } |
(...skipping 28 matching lines...) Expand all Loading... |
140 return; | 165 return; |
141 case signin::DiceAction::NONE: | 166 case signin::DiceAction::NONE: |
142 NOTREACHED() << "Invalid Dice response parameters."; | 167 NOTREACHED() << "Invalid Dice response parameters."; |
143 return; | 168 return; |
144 } | 169 } |
145 | 170 |
146 NOTREACHED(); | 171 NOTREACHED(); |
147 return; | 172 return; |
148 } | 173 } |
149 | 174 |
| 175 size_t DiceResponseHandler::GetPendingDiceTokenFetchersCountForTesting() const { |
| 176 return token_fetchers_.size(); |
| 177 } |
| 178 |
150 void DiceResponseHandler::ProcessDiceSigninHeader( | 179 void DiceResponseHandler::ProcessDiceSigninHeader( |
151 const std::string& gaia_id, | 180 const std::string& gaia_id, |
152 const std::string& email, | 181 const std::string& email, |
153 const std::string& authorization_code) { | 182 const std::string& authorization_code) { |
154 DCHECK(!gaia_id.empty()); | 183 DCHECK(!gaia_id.empty()); |
155 DCHECK(!email.empty()); | 184 DCHECK(!email.empty()); |
156 DCHECK(!authorization_code.empty()); | 185 DCHECK(!authorization_code.empty()); |
157 | 186 |
158 for (auto it = token_fetchers_.begin(); it != token_fetchers_.end(); ++it) { | 187 for (auto it = token_fetchers_.begin(); it != token_fetchers_.end(); ++it) { |
159 if ((it->get()->gaia_id() == gaia_id) && (it->get()->email() == email) && | 188 if ((it->get()->gaia_id() == gaia_id) && (it->get()->email() == email) && |
(...skipping 28 matching lines...) Expand all Loading... |
188 DeleteTokenFetcher(token_fetcher); | 217 DeleteTokenFetcher(token_fetcher); |
189 } | 218 } |
190 | 219 |
191 void DiceResponseHandler::OnTokenExchangeFailure( | 220 void DiceResponseHandler::OnTokenExchangeFailure( |
192 DiceTokenFetcher* token_fetcher, | 221 DiceTokenFetcher* token_fetcher, |
193 const GoogleServiceAuthError& error) { | 222 const GoogleServiceAuthError& error) { |
194 // TODO(droger): Handle authentication errors. | 223 // TODO(droger): Handle authentication errors. |
195 VLOG(1) << "Dice OAuth failed with error: " << error.ToString(); | 224 VLOG(1) << "Dice OAuth failed with error: " << error.ToString(); |
196 DeleteTokenFetcher(token_fetcher); | 225 DeleteTokenFetcher(token_fetcher); |
197 } | 226 } |
OLD | NEW |