profile_auth_data.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/login/profile_auth_data.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <string>
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/bind.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/bind_helpers.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/callback.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/location.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/logging.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/memory/ref_counted.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/message_loop/message_loop.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/browser_context.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/cookies/canonical_cookie.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/cookies/cookie_monster.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/cookies/cookie_store.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_auth_cache.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_network_session.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_transaction_factory.h"
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/ssl/channel_id_service.h"
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/ssl/channel_id_store.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_context.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "url/gurl.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Given a |cookie| set during login, returns true if the cookie may have been
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// set by GAIA. While GAIA can set cookies for many different domains, the
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// domain names it sets cookies for during Chrome OS login will always contain
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// the strings "google" or "youtube".
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool IsGAIACookie(const net::CanonicalCookie& cookie) {
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const std::string& domain = cookie.Domain();
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return domain.find("google") != std::string::npos ||
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         domain.find("youtube") != std::string::npos;
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ProfileAuthDataTransferer {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProfileAuthDataTransferer(
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      content::BrowserContext* from_context,
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      content::BrowserContext* to_context,
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      bool transfer_auth_cookies_and_channel_ids_on_first_login,
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      bool transfer_saml_auth_cookies_on_subsequent_login,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Closure& completion_callback);
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void BeginTransfer();
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void BeginTransferOnIOThread();
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Transfer the proxy auth cache from |from_context_| to |to_context_|. If
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the user was required to authenticate with a proxy during login, this
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // authentication information will be transferred into the user's session.
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void TransferProxyAuthCache();
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Callback that receives the content of |to_context_|'s cookie jar. Checks
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // whether this is the user's first login, based on the state of the cookie
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // jar, and starts retrieval of the data that should be transfered. Calls
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Finish() if there is no data to transfer.
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void OnTargetCookieJarContentsRetrieved(
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const net::CookieList& target_cookies);
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Retrieve the contents of |from_context_|'s cookie jar. When the retrieval
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // finishes, OnCookiesToTransferRetrieved will be called with the result.
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void RetrieveCookiesToTransfer();
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Callback that receives the contents of |from_context_|'s cookie jar. Calls
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // MaybeTransferCookiesAndChannelIDs() to try and perform the transfer.
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnCookiesToTransferRetrieved(const net::CookieList& cookies_to_transfer);
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Retrieve |from_context_|'s channel IDs. When the retrieval finishes,
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // OnChannelIDsToTransferRetrieved will be called with the result.
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void RetrieveChannelIDsToTransfer();
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Callback that receives |from_context_|'s channel IDs. Calls
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // MaybeTransferCookiesAndChannelIDs() to try and perform the transfer.
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void OnChannelIDsToTransferRetrieved(
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const net::ChannelIDStore::ChannelIDList& channel_ids_to_transfer);
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If all data to be transferred has been retrieved already, transfer it to
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // |to_context_| and call Finish().
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void MaybeTransferCookiesAndChannelIDs();
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Post the |completion_callback_| to the UI thread and schedule destruction
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // of |this|.
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void Finish();
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::URLRequestContextGetter> from_context_;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::URLRequestContextGetter> to_context_;
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool transfer_auth_cookies_and_channel_ids_on_first_login_;
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool transfer_saml_auth_cookies_on_subsequent_login_;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Closure completion_callback_;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::CookieList cookies_to_transfer_;
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  net::ChannelIDStore::ChannelIDList channel_ids_to_transfer_;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool first_login_;
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool waiting_for_auth_cookies_;
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool waiting_for_channel_ids_;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProfileAuthDataTransferer::ProfileAuthDataTransferer(
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    content::BrowserContext* from_context,
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    content::BrowserContext* to_context,
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool transfer_auth_cookies_and_channel_ids_on_first_login,
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool transfer_saml_auth_cookies_on_subsequent_login,
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& completion_callback)
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : from_context_(from_context->GetRequestContext()),
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      to_context_(to_context->GetRequestContext()),
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      transfer_auth_cookies_and_channel_ids_on_first_login_(
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          transfer_auth_cookies_and_channel_ids_on_first_login),
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      transfer_saml_auth_cookies_on_subsequent_login_(
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          transfer_saml_auth_cookies_on_subsequent_login),
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      completion_callback_(completion_callback),
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      first_login_(false),
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      waiting_for_auth_cookies_(false),
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      waiting_for_channel_ids_(false) {
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProfileAuthDataTransferer::BeginTransfer() {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If we aren't transferring auth cookies or channel IDs, post the completion
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // callback immediately. Otherwise, it will be called when the transfer
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // finishes.
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!transfer_auth_cookies_and_channel_ids_on_first_login_ &&
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      !transfer_saml_auth_cookies_on_subsequent_login_) {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, completion_callback_);
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Null the callback so that when Finish is called, the callback won't be
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // called again.
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion_callback_.Reset();
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::IO, FROM_HERE,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ProfileAuthDataTransferer::BeginTransferOnIOThread,
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this)));
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProfileAuthDataTransferer::BeginTransferOnIOThread() {
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TransferProxyAuthCache();
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (transfer_auth_cookies_and_channel_ids_on_first_login_ ||
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      transfer_saml_auth_cookies_on_subsequent_login_) {
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Retrieve the contents of |to_context_|'s cookie jar.
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    net::CookieStore* to_store =
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        to_context_->GetURLRequestContext()->cookie_store();
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    net::CookieMonster* to_monster = to_store->GetCookieMonster();
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    to_monster->GetAllCookiesAsync(
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            &ProfileAuthDataTransferer::OnTargetCookieJarContentsRetrieved,
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Unretained(this)));
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Finish();
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ProfileAuthDataTransferer::TransferProxyAuthCache() {
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  net::HttpAuthCache* new_cache = to_context_->GetURLRequestContext()->
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      http_transaction_factory()->GetSession()->http_auth_cache();
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  new_cache->UpdateAllFrom(*from_context_->GetURLRequestContext()->
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      http_transaction_factory()->GetSession()->http_auth_cache());
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ProfileAuthDataTransferer::OnTargetCookieJarContentsRetrieved(
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const net::CookieList& target_cookies) {
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  first_login_ = target_cookies.empty();
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (first_login_) {
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // On first login, transfer all auth cookies and channel IDs if
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // |transfer_auth_cookies_and_channel_ids_on_first_login_| is true.
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    waiting_for_auth_cookies_ =
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        transfer_auth_cookies_and_channel_ids_on_first_login_;
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    waiting_for_channel_ids_ =
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        transfer_auth_cookies_and_channel_ids_on_first_login_;
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // On subsequent login, transfer auth cookies set by the SAML IdP if
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // |transfer_saml_auth_cookies_on_subsequent_login_| is true.
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    waiting_for_auth_cookies_ = transfer_saml_auth_cookies_on_subsequent_login_;
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!waiting_for_auth_cookies_ && !waiting_for_channel_ids_) {
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Finish();
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (waiting_for_auth_cookies_)
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RetrieveCookiesToTransfer();
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (waiting_for_channel_ids_)
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RetrieveChannelIDsToTransfer();
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ProfileAuthDataTransferer::RetrieveCookiesToTransfer() {
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  net::CookieStore* from_store =
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      from_context_->GetURLRequestContext()->cookie_store();
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  net::CookieMonster* from_monster = from_store->GetCookieMonster();
206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  from_monster->SetKeepExpiredCookies();
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  from_monster->GetAllCookiesAsync(
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&ProfileAuthDataTransferer::OnCookiesToTransferRetrieved,
209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(this)));
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ProfileAuthDataTransferer::OnCookiesToTransferRetrieved(
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const net::CookieList& cookies_to_transfer) {
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  waiting_for_auth_cookies_ = false;
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  cookies_to_transfer_ = cookies_to_transfer;
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  MaybeTransferCookiesAndChannelIDs();
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ProfileAuthDataTransferer::RetrieveChannelIDsToTransfer() {
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  net::ChannelIDService* from_service =
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      from_context_->GetURLRequestContext()->channel_id_service();
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  from_service->GetChannelIDStore()->GetAllChannelIDs(
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          &ProfileAuthDataTransferer::OnChannelIDsToTransferRetrieved,
227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Unretained(this)));
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ProfileAuthDataTransferer::OnChannelIDsToTransferRetrieved(
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const net::ChannelIDStore::ChannelIDList& channel_ids_to_transfer) {
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  channel_ids_to_transfer_ = channel_ids_to_transfer;
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  waiting_for_channel_ids_ = false;
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  MaybeTransferCookiesAndChannelIDs();
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ProfileAuthDataTransferer::MaybeTransferCookiesAndChannelIDs() {
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (waiting_for_auth_cookies_ || waiting_for_channel_ids_)
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::CookieStore* to_store =
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      to_context_->GetURLRequestContext()->cookie_store();
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::CookieMonster* to_monster = to_store->GetCookieMonster();
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (first_login_) {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    to_monster->InitializeFrom(cookies_to_transfer_);
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    net::ChannelIDService* to_cert_service =
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        to_context_->GetURLRequestContext()->channel_id_service();
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    to_cert_service->GetChannelIDStore()->InitializeFrom(
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        channel_ids_to_transfer_);
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for (net::CookieList::const_iterator it = cookies_to_transfer_.begin();
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         it != cookies_to_transfer_.end(); ++it) {
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      if (IsGAIACookie(*it))
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        continue;
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // Although this method can be asynchronous, it will run synchronously in
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // this case as the target cookie jar is guaranteed to be loaded and
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // ready.
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      to_monster->SetCookieWithDetailsAsync(
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          GURL(it->Source()),
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          it->Name(),
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          it->Value(),
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          it->Domain(),
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          it->Path(),
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          it->ExpiryDate(),
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          it->IsSecure(),
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          it->IsHttpOnly(),
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          it->Priority(),
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          net::CookieStore::SetCookiesCallback());
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Finish();
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
277116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ProfileAuthDataTransferer::Finish() {
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!completion_callback_.is_null())
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, completion_callback_);
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProfileAuthData::Transfer(
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    content::BrowserContext* from_context,
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    content::BrowserContext* to_context,
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool transfer_auth_cookies_and_channel_ids_on_first_login,
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool transfer_saml_auth_cookies_on_subsequent_login,
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& completion_callback) {
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  (new ProfileAuthDataTransferer(
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       from_context,
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       to_context,
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       transfer_auth_cookies_and_channel_ids_on_first_login,
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       transfer_saml_auth_cookies_on_subsequent_login,
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       completion_callback))->BeginTransfer();
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace chromeos
302