Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: components/signin/core/browser/gaia_cookie_manager_service.cc

Issue 1044933002: GaiaCookieServiceManager handles general request types (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More unit tests; Reviewed LogOutInternal; other rogerta comments. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/signin/core/browser/gaia_cookie_manager_service.h" 5 #include "components/signin/core/browser/gaia_cookie_manager_service.h"
6 6
7 #include <queue>
7 #include <vector> 8 #include <vector>
8 9
9 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
10 #include "base/stl_util.h" 11 #include "base/stl_util.h"
11 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
13 #include "base/time/time.h" 14 #include "base/time/time.h"
14 #include "base/values.h" 15 #include "base/values.h"
15 #include "components/signin/core/browser/signin_metrics.h" 16 #include "components/signin/core/browser/signin_metrics.h"
16 #include "google_apis/gaia/gaia_auth_fetcher.h" 17 #include "google_apis/gaia/gaia_auth_fetcher.h"
17 #include "google_apis/gaia/gaia_constants.h" 18 #include "google_apis/gaia/gaia_constants.h"
18 #include "google_apis/gaia/gaia_urls.h" 19 #include "google_apis/gaia/gaia_urls.h"
19 #include "google_apis/gaia/oauth2_token_service.h" 20 #include "google_apis/gaia/oauth2_token_service.h"
20 #include "net/base/load_flags.h" 21 #include "net/base/load_flags.h"
21 #include "net/http/http_status_code.h" 22 #include "net/http/http_status_code.h"
22 #include "net/url_request/url_fetcher.h" 23 #include "net/url_request/url_fetcher.h"
23 #include "net/url_request/url_fetcher_delegate.h" 24 #include "net/url_request/url_fetcher_delegate.h"
24 25
26 GaiaCookieManagerService::GaiaCookieRequest::GaiaCookieRequest(
27 GaiaCookieRequestType request_type,
28 const std::string& account_id,
29 const GaiaCookieManagerService::ListAccountsCallback&
30 list_accounts_callback)
31 : request_type_(request_type),
32 account_id_(account_id),
33 list_accounts_callback_(list_accounts_callback) {}
34
35 GaiaCookieManagerService::GaiaCookieRequest::~GaiaCookieRequest() {
36 }
37
38 // static
39 GaiaCookieManagerService::GaiaCookieRequest
40 GaiaCookieManagerService::GaiaCookieRequest::CreateAddAccountRequest(
41 const std::string& account_id) {
42 return GaiaCookieManagerService::GaiaCookieRequest(
43 GaiaCookieManagerService::GaiaCookieRequestType::ADD_ACCOUNT,
44 account_id,
45 GaiaCookieManagerService::ListAccountsCallback());
46 }
47
48 // static
49 GaiaCookieManagerService::GaiaCookieRequest
50 GaiaCookieManagerService::GaiaCookieRequest::CreateLogOutRequest() {
51 return GaiaCookieManagerService::GaiaCookieRequest(
52 GaiaCookieManagerService::GaiaCookieRequestType::LOG_OUT,
53 std::string(),
54 GaiaCookieManagerService::ListAccountsCallback());
55 }
56
57 GaiaCookieManagerService::GaiaCookieRequest
58 GaiaCookieManagerService::GaiaCookieRequest::CreateListAccountsRequest(
59 const GaiaCookieManagerService::ListAccountsCallback&
60 list_accounts_callback) {
61 return GaiaCookieManagerService::GaiaCookieRequest(
62 GaiaCookieManagerService::GaiaCookieRequestType::LIST_ACCOUNTS,
63 std::string(),
64 list_accounts_callback);
65 }
66
25 GaiaCookieManagerService::ExternalCcResultFetcher::ExternalCcResultFetcher( 67 GaiaCookieManagerService::ExternalCcResultFetcher::ExternalCcResultFetcher(
26 GaiaCookieManagerService* helper) 68 GaiaCookieManagerService* helper)
27 : helper_(helper) { 69 : helper_(helper) {
28 DCHECK(helper_); 70 DCHECK(helper_);
29 } 71 }
30 72
31 GaiaCookieManagerService::ExternalCcResultFetcher::~ExternalCcResultFetcher() { 73 GaiaCookieManagerService::ExternalCcResultFetcher::~ExternalCcResultFetcher() {
32 CleanupTransientState(); 74 CleanupTransientState();
33 } 75 }
34 76
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 const std::string& source, 227 const std::string& source,
186 SigninClient* signin_client) 228 SigninClient* signin_client)
187 : token_service_(token_service), 229 : token_service_(token_service),
188 signin_client_(signin_client), 230 signin_client_(signin_client),
189 external_cc_result_fetcher_(this), 231 external_cc_result_fetcher_(this),
190 source_(source) { 232 source_(source) {
191 } 233 }
192 234
193 GaiaCookieManagerService::~GaiaCookieManagerService() { 235 GaiaCookieManagerService::~GaiaCookieManagerService() {
194 CancelAll(); 236 CancelAll();
195 DCHECK(accounts_.empty()); 237 DCHECK(requests_.empty());
196 } 238 }
197 239
198 void GaiaCookieManagerService::AddAccountToCookie( 240 void GaiaCookieManagerService::AddAccountToCookie(
199 const std::string& account_id) { 241 const std::string& account_id) {
200 DCHECK(!account_id.empty()); 242 DCHECK(!account_id.empty());
201 VLOG(1) << "GaiaCookieManagerService::AddAccountToCookie: " << account_id; 243 VLOG(1) << "GaiaCookieManagerService::AddAccountToCookie: " << account_id;
202 accounts_.push_back(account_id); 244 requests_.push_back(GaiaCookieRequest::CreateAddAccountRequest(account_id));
203 if (accounts_.size() == 1) 245 if (requests_.size() == 1)
204 StartFetching(); 246 StartFetchingUbertoken();
247 }
248
249 void GaiaCookieManagerService::ListAccounts(
250 const ListAccountsCallback& callback) {
251 // Not implemented yet.
252 NOTREACHED();
253
254 // TODO(mlerman): Once this service listens to all GAIA cookie changes, cache
255 // the results of ListAccounts, and return them here if the GAIA cookie
256 // hasn't changed since the last call.
257
258 // If there's a GAIA call being executed, wait for it to complete. If it was
259 // another /ListAccounts then we'll use the results it caches.
260 if (gaia_auth_fetcher_)
261 return;
262
263 VLOG(1) << "GaiaCookieManagerService::ListAccounts";
264 gaia_auth_fetcher_.reset(
265 new GaiaAuthFetcher(this, source_,
266 signin_client_->GetURLRequestContext()));
267 gaia_auth_fetcher_->StartListAccounts();
268 }
269
270 void GaiaCookieManagerService::LogOutAllAccounts() {
271 VLOG(1) << "GaiaCookieManagerService::LogOutAllAccounts";
272
273 bool log_out_queued = false;
274 if (!requests_.empty()) {
275 // Track requests to keep; all other unstarted requests will be removed.
276 std::vector<GaiaCookieRequest> requests_to_keep;
277
278 // Check all pending, non-executing requests.
279 for (auto it = requests_.begin() + 1; it != requests_.end(); ++it) {
280 if (it->request_type() == GaiaCookieRequestType::ADD_ACCOUNT) {
281 // We have a pending log in request for an account followed by
282 // a signout.
283 GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED);
284 SignalComplete(it->account_id(), error);
285 }
286
287 // Keep all requests except for ADD_ACCOUNTS.
288 if (it->request_type() != GaiaCookieRequestType::ADD_ACCOUNT)
289 requests_to_keep.push_back(*it);
290
291 // Verify a LOG_OUT isn't already queued.
292 if (it->request_type() == GaiaCookieRequestType::LOG_OUT)
293 log_out_queued = true;
294 }
295
296 // Verify a LOG_OUT isn't currently being processed.
297 if (requests_.front().request_type() == GaiaCookieRequestType::LOG_OUT)
298 log_out_queued = true;
299
300 // Remove all put the executing request. Re-add all requests being kept.
Roger Tawa OOO till Jul 10th 2015/04/01 16:50:38 put --> but
Mike Lerman 2015/04/02 12:43:14 Done.
301 if (requests_.size() > 1) {
302 requests_.erase(requests_.begin() + 1, requests_.end());
303 requests_.insert(
304 requests_.end(), requests_to_keep.begin(), requests_to_keep.end());
305 }
306 }
307
308 if (!log_out_queued) {
309 requests_.push_back(GaiaCookieRequest::CreateLogOutRequest());
310 if (requests_.size() == 1)
311 StartLogOutUrlFetch();
312 }
205 } 313 }
206 314
207 void GaiaCookieManagerService::AddObserver(Observer* observer) { 315 void GaiaCookieManagerService::AddObserver(Observer* observer) {
208 observer_list_.AddObserver(observer); 316 observer_list_.AddObserver(observer);
209 } 317 }
210 318
211 void GaiaCookieManagerService::RemoveObserver(Observer* observer) { 319 void GaiaCookieManagerService::RemoveObserver(Observer* observer) {
212 observer_list_.RemoveObserver(observer); 320 observer_list_.RemoveObserver(observer);
213 } 321 }
214 322
215 void GaiaCookieManagerService::CancelAll() { 323 void GaiaCookieManagerService::CancelAll() {
216 VLOG(1) << "GaiaCookieManagerService::CancelAll"; 324 VLOG(1) << "GaiaCookieManagerService::CancelAll";
217 gaia_auth_fetcher_.reset(); 325 gaia_auth_fetcher_.reset();
218 uber_token_fetcher_.reset(); 326 uber_token_fetcher_.reset();
219 accounts_.clear(); 327 requests_.clear();
220 }
221
222 void GaiaCookieManagerService::LogOut(
223 const std::string& account_id,
224 const std::vector<std::string>& accounts) {
225 DCHECK(!account_id.empty());
226 VLOG(1) << "GaiaCookieManagerService::LogOut: " << account_id
227 << " accounts=" << accounts.size();
228 LogOutInternal(account_id, accounts);
229 }
230
231 void GaiaCookieManagerService::LogOutInternal(
232 const std::string& account_id,
233 const std::vector<std::string>& accounts) {
234 bool pending = !accounts_.empty();
235
236 if (pending) {
237 for (std::deque<std::string>::const_iterator it = accounts_.begin() + 1;
238 it != accounts_.end(); it++) {
239 if (!it->empty() &&
240 (std::find(accounts.begin(), accounts.end(), *it) == accounts.end() ||
241 *it == account_id)) {
242 // We have a pending log in request for an account followed by
243 // a signout.
244 GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED);
245 SignalComplete(*it, error);
246 }
247 }
248
249 // Remove every thing in the work list besides the one that is running.
250 accounts_.resize(1);
251 }
252
253 // Signal a logout to be the next thing to do unless the pending
254 // action is already a logout.
255 if (!pending || !accounts_.front().empty())
256 accounts_.push_back("");
257
258 for (std::vector<std::string>::const_iterator it = accounts.begin();
259 it != accounts.end(); it++) {
260 if (*it != account_id) {
261 DCHECK(!it->empty());
262 accounts_.push_back(*it);
263 }
264 }
265
266 if (!pending)
267 StartLogOutUrlFetch();
268 }
269
270 void GaiaCookieManagerService::LogOutAllAccounts() {
271 VLOG(1) << "GaiaCookieManagerService::LogOutAllAccounts";
272 LogOutInternal("", std::vector<std::string>());
273 } 328 }
274 329
275 void GaiaCookieManagerService::SignalComplete( 330 void GaiaCookieManagerService::SignalComplete(
276 const std::string& account_id, 331 const std::string& account_id,
277 const GoogleServiceAuthError& error) { 332 const GoogleServiceAuthError& error) {
278 // Its possible for the observer to delete |this| object. Don't access 333 // Its possible for the observer to delete |this| object. Don't access
279 // access any members after this calling the observer. This method should 334 // access any members after this calling the observer. This method should
280 // be the last call in any other method. 335 // be the last call in any other method.
281 FOR_EACH_OBSERVER(Observer, observer_list_, 336 FOR_EACH_OBSERVER(Observer, observer_list_,
282 OnAddAccountToCookieCompleted(account_id, error)); 337 OnAddAccountToCookieCompleted(account_id, error));
283 } 338 }
284 339
285 void GaiaCookieManagerService::StartFetchingExternalCcResult() { 340 void GaiaCookieManagerService::StartFetchingExternalCcResult() {
286 if (!external_cc_result_fetcher_.IsRunning()) 341 if (!external_cc_result_fetcher_.IsRunning())
287 external_cc_result_fetcher_.Start(); 342 external_cc_result_fetcher_.Start();
288 } 343 }
289 344
290 void GaiaCookieManagerService::StartLogOutUrlFetch() { 345 void GaiaCookieManagerService::StartLogOutUrlFetch() {
291 DCHECK(accounts_.front().empty()); 346 DCHECK(requests_.front().request_type() == GaiaCookieRequestType::LOG_OUT);
292 VLOG(1) << "GaiaCookieManagerService::StartLogOutUrlFetch"; 347 VLOG(1) << "GaiaCookieManagerService::StartLogOutUrlFetch";
293 GURL logout_url(GaiaUrls::GetInstance()->service_logout_url().Resolve( 348 GURL logout_url(GaiaUrls::GetInstance()->service_logout_url().Resolve(
294 base::StringPrintf("?source=%s", source_.c_str()))); 349 base::StringPrintf("?source=%s", source_.c_str())));
295 net::URLFetcher* fetcher = 350 net::URLFetcher* fetcher =
296 net::URLFetcher::Create(logout_url, net::URLFetcher::GET, this); 351 net::URLFetcher::Create(logout_url, net::URLFetcher::GET, this);
297 fetcher->SetRequestContext(signin_client_->GetURLRequestContext()); 352 fetcher->SetRequestContext(signin_client_->GetURLRequestContext());
298 fetcher->Start(); 353 fetcher->Start();
299 } 354 }
300 355
301 void GaiaCookieManagerService::OnUbertokenSuccess( 356 void GaiaCookieManagerService::OnUbertokenSuccess(
302 const std::string& uber_token) { 357 const std::string& uber_token) {
303 VLOG(1) << "GaiaCookieManagerService::OnUbertokenSuccess" 358 VLOG(1) << "GaiaCookieManagerService::OnUbertokenSuccess"
304 << " account=" << accounts_.front(); 359 << " account=" << requests_.front().account_id();
305 gaia_auth_fetcher_.reset( 360 gaia_auth_fetcher_.reset(
306 new GaiaAuthFetcher(this, source_, 361 new GaiaAuthFetcher(this, source_,
307 signin_client_->GetURLRequestContext())); 362 signin_client_->GetURLRequestContext()));
308 363
309 // It's possible that not all external checks have completed. 364 // It's possible that not all external checks have completed.
310 // GetExternalCcResult() returns results for those that have. 365 // GetExternalCcResult() returns results for those that have.
311 gaia_auth_fetcher_->StartMergeSession(uber_token, 366 gaia_auth_fetcher_->StartMergeSession(uber_token,
312 external_cc_result_fetcher_.GetExternalCcResult()); 367 external_cc_result_fetcher_.GetExternalCcResult());
313 } 368 }
314 369
315 void GaiaCookieManagerService::OnUbertokenFailure( 370 void GaiaCookieManagerService::OnUbertokenFailure(
316 const GoogleServiceAuthError& error) { 371 const GoogleServiceAuthError& error) {
317 VLOG(1) << "Failed to retrieve ubertoken" 372 VLOG(1) << "Failed to retrieve ubertoken"
318 << " account=" << accounts_.front() << " error=" << error.ToString(); 373 << " account=" << requests_.front().account_id()
319 const std::string account_id = accounts_.front(); 374 << " error=" << error.ToString();
320 HandleNextAccount(); 375 const std::string account_id = requests_.front().account_id();
376 HandleNextRequest();
321 SignalComplete(account_id, error); 377 SignalComplete(account_id, error);
322 } 378 }
323 379
324 void GaiaCookieManagerService::OnMergeSessionSuccess(const std::string& data) { 380 void GaiaCookieManagerService::OnMergeSessionSuccess(const std::string& data) {
325 VLOG(1) << "MergeSession successful account=" << accounts_.front(); 381 VLOG(1) << "MergeSession successful account="
326 const std::string account_id = accounts_.front(); 382 << requests_.front().account_id();
327 HandleNextAccount(); 383 const std::string account_id = requests_.front().account_id();
384 HandleNextRequest();
328 SignalComplete(account_id, GoogleServiceAuthError::AuthErrorNone()); 385 SignalComplete(account_id, GoogleServiceAuthError::AuthErrorNone());
329 } 386 }
330 387
331 void GaiaCookieManagerService::OnMergeSessionFailure( 388 void GaiaCookieManagerService::OnMergeSessionFailure(
332 const GoogleServiceAuthError& error) { 389 const GoogleServiceAuthError& error) {
333 VLOG(1) << "Failed MergeSession" 390 VLOG(1) << "Failed MergeSession"
334 << " account=" << accounts_.front() << " error=" << error.ToString(); 391 << " account=" << requests_.front().account_id()
335 const std::string account_id = accounts_.front(); 392 << " error=" << error.ToString();
336 HandleNextAccount(); 393 const std::string account_id = requests_.front().account_id();
394 HandleNextRequest();
337 SignalComplete(account_id, error); 395 SignalComplete(account_id, error);
338 } 396 }
339 397
340 void GaiaCookieManagerService::StartFetching() { 398 void GaiaCookieManagerService::StartFetchingUbertoken() {
341 VLOG(1) << "GaiaCookieManagerService::StartFetching account_id=" 399 VLOG(1) << "GaiaCookieManagerService::StartFetching account_id="
342 << accounts_.front(); 400 << requests_.front().account_id();
343 uber_token_fetcher_.reset( 401 uber_token_fetcher_.reset(
344 new UbertokenFetcher(token_service_, this, source_, 402 new UbertokenFetcher(token_service_, this, source_,
345 signin_client_->GetURLRequestContext())); 403 signin_client_->GetURLRequestContext()));
346 uber_token_fetcher_->StartFetchingToken(accounts_.front()); 404 uber_token_fetcher_->StartFetchingToken(requests_.front().account_id());
347 } 405 }
348 406
349 void GaiaCookieManagerService::OnURLFetchComplete( 407 void GaiaCookieManagerService::OnURLFetchComplete(
350 const net::URLFetcher* source) { 408 const net::URLFetcher* source) {
351 DCHECK(accounts_.front().empty()); 409 DCHECK(requests_.front().request_type() == GaiaCookieRequestType::LOG_OUT);
352 VLOG(1) << "GaiaCookieManagerService::OnURLFetchComplete"; 410 VLOG(1) << "GaiaCookieManagerService::OnURLFetchComplete";
353 HandleNextAccount(); 411 HandleNextRequest();
354 } 412 }
355 413
356 void GaiaCookieManagerService::HandleNextAccount() { 414 void GaiaCookieManagerService::HandleNextRequest() {
357 VLOG(1) << "GaiaCookieManagerService::HandleNextAccount"; 415 VLOG(1) << "GaiaCookieManagerService::HandleNextRequest";
358 accounts_.pop_front(); 416 requests_.pop_front();
359 gaia_auth_fetcher_.reset(); 417 gaia_auth_fetcher_.reset();
360 if (accounts_.empty()) { 418 if (requests_.empty()) {
361 VLOG(1) << "GaiaCookieManagerService::HandleNextAccount: no more"; 419 VLOG(1) << "GaiaCookieManagerService::HandleNextRequest: no more";
362 uber_token_fetcher_.reset(); 420 uber_token_fetcher_.reset();
363 } else { 421 } else {
364 if (accounts_.front().empty()) { 422 switch (requests_.front().request_type()) {
365 StartLogOutUrlFetch(); 423 case GaiaCookieRequestType::ADD_ACCOUNT:
366 } else { 424 StartFetchingUbertoken();
367 StartFetching(); 425 break;
368 } 426 case GaiaCookieRequestType::LOG_OUT:
427 StartLogOutUrlFetch();
428 break;
429 case GaiaCookieRequestType::LIST_ACCOUNTS:
430 break;
431 };
369 } 432 }
370 } 433 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698