OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/chromeos/login/profile_auth_data.h" | 5 #include "chrome/browser/chromeos/login/profile_auth_data.h" |
6 | 6 |
7 #include "chrome/browser/profiles/profile.h" | 7 #include "chrome/browser/profiles/profile.h" |
8 #include "content/public/browser/browser_thread.h" | 8 #include "content/public/browser/browser_thread.h" |
9 #include "net/base/server_bound_cert_service.h" | 9 #include "net/base/server_bound_cert_service.h" |
10 #include "net/base/server_bound_cert_store.h" | 10 #include "net/base/server_bound_cert_store.h" |
11 #include "net/cookies/cookie_monster.h" | 11 #include "net/cookies/cookie_monster.h" |
12 #include "net/cookies/cookie_store.h" | 12 #include "net/cookies/cookie_store.h" |
13 #include "net/http/http_auth_cache.h" | 13 #include "net/http/http_auth_cache.h" |
14 #include "net/http/http_network_session.h" | 14 #include "net/http/http_network_session.h" |
15 #include "net/http/http_transaction_factory.h" | 15 #include "net/http/http_transaction_factory.h" |
16 #include "net/url_request/url_request_context.h" | 16 #include "net/url_request/url_request_context.h" |
17 #include "net/url_request/url_request_context_getter.h" | 17 #include "net/url_request/url_request_context_getter.h" |
18 | 18 |
19 using content::BrowserThread; | 19 using content::BrowserThread; |
20 | 20 |
21 namespace chromeos { | 21 namespace chromeos { |
22 | 22 |
23 namespace { | 23 namespace { |
24 | 24 |
25 // Callback for transferring |cookies_to_transfer| into |cookie_monster| if | 25 class ProfileAuthDataTransferer { |
26 // its jar is completely empty. | 26 public: |
27 void OnTransferCookiesIfEmptyJar( | 27 ProfileAuthDataTransferer( |
28 net::CookieMonster* cookie_monster, | 28 Profile* from_profile, |
29 const net::CookieList& cookies_to_transfer, | 29 Profile* to_profile, |
30 const base::Callback<void()>& cookies_transfered_callback, | 30 bool transfer_cookies, |
| 31 const base::Closure& completion_callback); |
| 32 |
| 33 void BeginTransfer(); |
| 34 |
| 35 private: |
| 36 void BeginTransferOnIOThread(); |
| 37 void MaybeDoCookieAndCertTransfer(); |
| 38 void Finish(); |
| 39 |
| 40 void OnTransferCookiesIfEmptyJar(const net::CookieList& cookies_in_jar); |
| 41 void OnGetCookiesToTransfer(const net::CookieList& cookies_to_transfer); |
| 42 void RetrieveDefaultCookies(); |
| 43 void OnGetServerBoundCertsToTransfer( |
| 44 const net::ServerBoundCertStore::ServerBoundCertList& certs); |
| 45 void RetrieveDefaultServerBoundCerts(); |
| 46 void TransferDefaultAuthCache(); |
| 47 |
| 48 scoped_refptr<net::URLRequestContextGetter> from_context_; |
| 49 scoped_refptr<net::URLRequestContextGetter> to_context_; |
| 50 bool transfer_cookies_; |
| 51 base::Closure completion_callback_; |
| 52 |
| 53 net::CookieList cookies_to_transfer_; |
| 54 net::ServerBoundCertStore::ServerBoundCertList certs_to_transfer_; |
| 55 |
| 56 bool got_cookies_; |
| 57 bool got_server_bound_certs_; |
| 58 }; |
| 59 |
| 60 ProfileAuthDataTransferer::ProfileAuthDataTransferer( |
| 61 Profile* from_profile, |
| 62 Profile* to_profile, |
| 63 bool transfer_cookies, |
| 64 const base::Closure& completion_callback) |
| 65 : from_context_(from_profile->GetRequestContext()), |
| 66 to_context_(to_profile->GetRequestContext()), |
| 67 transfer_cookies_(transfer_cookies), |
| 68 completion_callback_(completion_callback), |
| 69 got_cookies_(false), |
| 70 got_server_bound_certs_(false) { |
| 71 } |
| 72 |
| 73 void ProfileAuthDataTransferer::BeginTransfer() { |
| 74 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 75 // If we aren't transferring cookies, post the completion callback |
| 76 // immediately. Otherwise, it will be called when both cookies and channel |
| 77 // ids are finished transferring. |
| 78 if (!transfer_cookies_) { |
| 79 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, completion_callback_); |
| 80 // Null the callback so that when Finish is called the callback won't be |
| 81 // called again. |
| 82 completion_callback_.Reset(); |
| 83 } |
| 84 BrowserThread::PostTask( |
| 85 BrowserThread::IO, FROM_HERE, |
| 86 base::Bind(&ProfileAuthDataTransferer::BeginTransferOnIOThread, |
| 87 base::Unretained(this))); |
| 88 } |
| 89 |
| 90 void ProfileAuthDataTransferer::BeginTransferOnIOThread() { |
| 91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 92 TransferDefaultAuthCache(); |
| 93 |
| 94 if (transfer_cookies_) { |
| 95 RetrieveDefaultCookies(); |
| 96 RetrieveDefaultServerBoundCerts(); |
| 97 } else { |
| 98 Finish(); |
| 99 } |
| 100 } |
| 101 |
| 102 // If both cookies and server bound certs have been retrieved, see if we need to |
| 103 // do the actual transfer. |
| 104 void ProfileAuthDataTransferer::MaybeDoCookieAndCertTransfer() { |
| 105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 106 if (!(got_cookies_ && got_server_bound_certs_)) |
| 107 return; |
| 108 |
| 109 // Nothing to transfer over? |
| 110 if (!cookies_to_transfer_.size()) { |
| 111 Finish(); |
| 112 return; |
| 113 } |
| 114 |
| 115 // Now let's see if the target cookie monster's jar is even empty. |
| 116 net::CookieStore* to_store = |
| 117 to_context_->GetURLRequestContext()->cookie_store(); |
| 118 net::CookieMonster* to_monster = to_store->GetCookieMonster(); |
| 119 to_monster->GetAllCookiesAsync( |
| 120 base::Bind(&ProfileAuthDataTransferer::OnTransferCookiesIfEmptyJar, |
| 121 base::Unretained(this))); |
| 122 } |
| 123 |
| 124 // Post the |completion_callback_| and delete ourself. |
| 125 void ProfileAuthDataTransferer::Finish() { |
| 126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 127 if (!completion_callback_.is_null()) |
| 128 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, completion_callback_); |
| 129 delete this; |
| 130 } |
| 131 |
| 132 // Callback for transferring |cookies_to_transfer_| into |to_context_|'s |
| 133 // CookieMonster if its jar is completely empty. If authentication was |
| 134 // performed by an extension, then the set of cookies that was acquired through |
| 135 // such that process will be automatically transfered into the profile. |
| 136 void ProfileAuthDataTransferer::OnTransferCookiesIfEmptyJar( |
31 const net::CookieList& cookies_in_jar) { | 137 const net::CookieList& cookies_in_jar) { |
32 std::string sid; | 138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
33 std::string lsid; | |
34 // Transfer only if the existing cookie jar is empty. | 139 // Transfer only if the existing cookie jar is empty. |
35 if (!cookies_in_jar.size()) | 140 if (!cookies_in_jar.size()) { |
36 cookie_monster->InitializeFrom(cookies_to_transfer); | 141 net::CookieStore* to_store = |
| 142 to_context_->GetURLRequestContext()->cookie_store(); |
| 143 net::CookieMonster* to_monster = to_store->GetCookieMonster(); |
| 144 to_monster->InitializeFrom(cookies_to_transfer_); |
37 | 145 |
38 BrowserThread::PostTask( | 146 net::ServerBoundCertService* to_cert_service = |
39 BrowserThread::UI, FROM_HERE, cookies_transfered_callback); | 147 to_context_->GetURLRequestContext()->server_bound_cert_service(); |
40 return; | 148 to_cert_service->GetCertStore()->InitializeFrom(certs_to_transfer_); |
| 149 } |
| 150 |
| 151 Finish(); |
41 } | 152 } |
42 | 153 |
43 // Callback for receiving |cookies_to_transfer| from the authentication profile | 154 // Callback for receiving |cookies_to_transfer| from the authentication profile |
44 // cookie jar. | 155 // cookie jar. |
45 void OnGetCookiesToTransfer( | 156 void ProfileAuthDataTransferer::OnGetCookiesToTransfer( |
46 net::CookieMonster* cookie_monster, | |
47 const base::Callback<void()>& cookies_transfered_callback, | |
48 const net::CookieList& cookies_to_transfer) { | 157 const net::CookieList& cookies_to_transfer) { |
49 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
50 | 159 |
51 // Nothing to transfer over? | 160 got_cookies_ = true; |
52 if (!cookies_to_transfer.size()) { | 161 MaybeDoCookieAndCertTransfer(); |
53 BrowserThread::PostTask( | |
54 BrowserThread::UI, FROM_HERE, cookies_transfered_callback); | |
55 return; | |
56 } | |
57 // Now let's see if the target cookie monster's jar is even empty. | |
58 cookie_monster->GetAllCookiesAsync( | |
59 base::Bind(&OnTransferCookiesIfEmptyJar, | |
60 make_scoped_refptr(cookie_monster), | |
61 cookies_to_transfer, | |
62 cookies_transfered_callback)); | |
63 } | 162 } |
64 | 163 |
65 // Transfers initial set of Profile cookies from the |from_context| to cookie | 164 // Retrieves initial set of Profile cookies from the |from_context_|. |
66 // jar of |to_context|. | 165 void ProfileAuthDataTransferer::RetrieveDefaultCookies() { |
67 void TransferDefaultCookiesOnIOThread( | |
68 net::URLRequestContextGetter* from_context, | |
69 net::URLRequestContextGetter* to_context, | |
70 const base::Callback<void()>& cookies_transfered_callback) { | |
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
72 net::CookieStore* to_store = | |
73 to_context->GetURLRequestContext()->cookie_store(); | |
74 net::CookieMonster* to_monster = to_store->GetCookieMonster(); | |
75 | 167 |
76 net::CookieStore* from_store = | 168 net::CookieStore* from_store = |
77 from_context->GetURLRequestContext()->cookie_store(); | 169 from_context_->GetURLRequestContext()->cookie_store(); |
78 net::CookieMonster* from_monster = from_store->GetCookieMonster(); | 170 net::CookieMonster* from_monster = from_store->GetCookieMonster(); |
79 from_monster->SetKeepExpiredCookies(); | 171 from_monster->SetKeepExpiredCookies(); |
80 from_monster->GetAllCookiesAsync(base::Bind(&OnGetCookiesToTransfer, | 172 from_monster->GetAllCookiesAsync( |
81 make_scoped_refptr(to_monster), | 173 base::Bind(&ProfileAuthDataTransferer::OnGetCookiesToTransfer, |
82 cookies_transfered_callback)); | 174 base::Unretained(this))); |
83 } | 175 } |
84 | 176 |
85 // Transfers default server bound certs of |from_context| to server bound certs | 177 // Callback for receiving |cookies_to_transfer| from the authentication profile |
86 // storage of |to_context|. | 178 // cookie jar. |
87 void TransferDefaultServerBoundCertsIOThread( | 179 void ProfileAuthDataTransferer::OnGetServerBoundCertsToTransfer( |
88 net::URLRequestContextGetter* from_context, | 180 const net::ServerBoundCertStore::ServerBoundCertList& certs) { |
89 net::URLRequestContextGetter* to_context) { | |
90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
91 net::ServerBoundCertService* default_service = | 182 certs_to_transfer_ = certs; |
92 from_context->GetURLRequestContext()->server_bound_cert_service(); | 183 got_server_bound_certs_ = true; |
93 | 184 MaybeDoCookieAndCertTransfer(); |
94 net::ServerBoundCertStore::ServerBoundCertList server_bound_certs; | |
95 default_service->GetCertStore()->GetAllServerBoundCerts(&server_bound_certs); | |
96 | |
97 net::ServerBoundCertService* new_service = | |
98 to_context->GetURLRequestContext()->server_bound_cert_service(); | |
99 new_service->GetCertStore()->InitializeFrom(server_bound_certs); | |
100 } | 185 } |
101 | 186 |
102 // Transfers default auth cache of |from_context| to auth cache storage of | 187 // Retrieves server bound certs of |from_context_|. |
103 // |to_context|. | 188 void ProfileAuthDataTransferer::RetrieveDefaultServerBoundCerts() { |
104 void TransferDefaultAuthCacheOnIOThread( | |
105 net::URLRequestContextGetter* from_context, | |
106 net::URLRequestContextGetter* to_context) { | |
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
108 net::HttpAuthCache* new_cache = to_context->GetURLRequestContext()-> | 190 net::ServerBoundCertService* from_service = |
| 191 from_context_->GetURLRequestContext()->server_bound_cert_service(); |
| 192 |
| 193 from_service->GetCertStore()->GetAllServerBoundCerts( |
| 194 base::Bind(&ProfileAuthDataTransferer::OnGetServerBoundCertsToTransfer, |
| 195 base::Unretained(this))); |
| 196 } |
| 197 |
| 198 // Transfers HTTP authentication cache from the |from_context_| |
| 199 // into the |to_context_|. If user was required to authenticate with a proxy |
| 200 // during the login, this authentication information will be transferred |
| 201 // into the new session. |
| 202 void ProfileAuthDataTransferer::TransferDefaultAuthCache() { |
| 203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 204 net::HttpAuthCache* new_cache = to_context_->GetURLRequestContext()-> |
109 http_transaction_factory()->GetSession()->http_auth_cache(); | 205 http_transaction_factory()->GetSession()->http_auth_cache(); |
110 new_cache->UpdateAllFrom(*from_context->GetURLRequestContext()-> | 206 new_cache->UpdateAllFrom(*from_context_->GetURLRequestContext()-> |
111 http_transaction_factory()->GetSession()->http_auth_cache()); | 207 http_transaction_factory()->GetSession()->http_auth_cache()); |
112 } | 208 } |
113 | 209 |
114 // Transfers cookies and server bound certs from the |from_profile| into | |
115 // the |to_profile|. If authentication was performed by an extension, then | |
116 // the set of cookies that was acquired through such that process will be | |
117 // automatically transfered into the profile. | |
118 void TransferDefaultCookiesAndServerBoundCerts( | |
119 Profile* from_profile, | |
120 Profile* to_profile, | |
121 const base::Callback<void()>& cookies_transfered_callback) { | |
122 BrowserThread::PostTask( | |
123 BrowserThread::IO, FROM_HERE, | |
124 base::Bind(&TransferDefaultCookiesOnIOThread, | |
125 make_scoped_refptr(from_profile->GetRequestContext()), | |
126 make_scoped_refptr(to_profile->GetRequestContext()), | |
127 cookies_transfered_callback)); | |
128 BrowserThread::PostTask( | |
129 BrowserThread::IO, FROM_HERE, | |
130 base::Bind(&TransferDefaultServerBoundCertsIOThread, | |
131 make_scoped_refptr(from_profile->GetRequestContext()), | |
132 make_scoped_refptr(to_profile->GetRequestContext()))); | |
133 } | |
134 | |
135 // Transfers HTTP authentication cache from the |from_profile| | |
136 // into the |to_profile|. If user was required to authenticate with a proxy | |
137 // during the login, this authentication information will be transferred | |
138 // into the new session. | |
139 void TransferDefaultAuthCache(Profile* from_profile, | |
140 Profile* to_profile) { | |
141 BrowserThread::PostTask( | |
142 BrowserThread::IO, FROM_HERE, | |
143 base::Bind(&TransferDefaultAuthCacheOnIOThread, | |
144 make_scoped_refptr(from_profile->GetRequestContext()), | |
145 make_scoped_refptr(to_profile->GetRequestContext()))); | |
146 } | |
147 | |
148 } // namespace | 210 } // namespace |
149 | 211 |
150 void ProfileAuthData::Transfer( | 212 void ProfileAuthData::Transfer( |
151 Profile* from_profile, | 213 Profile* from_profile, |
152 Profile* to_profile, | 214 Profile* to_profile, |
153 bool transfer_cookies, | 215 bool transfer_cookies, |
154 const base::Callback<void()>& cookies_transfered_callback) { | 216 const base::Closure& completion_callback) { |
155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
156 if (transfer_cookies) { | 218 (new ProfileAuthDataTransferer(from_profile, to_profile, transfer_cookies, |
157 TransferDefaultCookiesAndServerBoundCerts(from_profile, | 219 completion_callback))->BeginTransfer(); |
158 to_profile, | |
159 cookies_transfered_callback); | |
160 } else { | |
161 BrowserThread::PostTask( | |
162 BrowserThread::UI, FROM_HERE, cookies_transfered_callback); | |
163 } | |
164 | |
165 TransferDefaultAuthCache(from_profile, to_profile); | |
166 } | 220 } |
167 | 221 |
168 } // namespace chromeos | 222 } // namespace chromeos |
OLD | NEW |