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
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/login/profile_auth_data.h"
10 #include "base/bind_helpers.h"
11 #include "base/compiler_specific.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/run_loop.h"
14 #include "base/strings/string16.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/time/time.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "content/public/browser/browser_context.h"
19 #include "content/public/test/test_browser_thread_bundle.h"
20 #include "net/cookies/canonical_cookie.h"
21 #include "net/cookies/cookie_constants.h"
22 #include "net/cookies/cookie_monster.h"
23 #include "net/cookies/cookie_store.h"
24 #include "net/http/http_auth.h"
25 #include "net/http/http_auth_cache.h"
26 #include "net/http/http_network_session.h"
27 #include "net/http/http_transaction_factory.h"
28 #include "net/ssl/channel_id_service.h"
29 #include "net/ssl/channel_id_store.h"
30 #include "net/url_request/url_request_context.h"
31 #include "net/url_request/url_request_context_getter.h"
32 #include "testing/gtest/include/gtest/gtest.h"
39 const char kProxyAuthURL
[] = "http://example.com/";
40 const char kProxyAuthRealm
[] = "realm";
41 const char kProxyAuthChallenge
[] = "challenge";
42 const char kProxyAuthPassword1
[] = "password 1";
43 const char kProxyAuthPassword2
[] = "password 2";
45 const char kGAIACookieURL
[] = "http://google.com/";
46 const char kSAMLIdPCookieURL
[] = "http://example.com/";
47 const char kCookieName
[] = "cookie";
48 const char kCookieValue1
[] = "value 1";
49 const char kCookieValue2
[] = "value 2";
50 const char kGAIACookieDomain
[] = "google.com";
51 const char kSAMLIdPCookieDomain
[] = "example.com";
53 const char kChannelIDServerIdentifier
[] = "server";
54 const char kChannelIDPrivateKey1
[] = "private key 1";
55 const char kChannelIDPrivateKey2
[] = "private key 2";
56 const char kChannelIDCert1
[] = "cert 1";
57 const char kChannelIDCert2
[] = "cert 2";
61 class ProfileAuthDataTest
: public testing::Test
{
64 void SetUp() override
;
66 void PopulateUserBrowserContext();
69 bool transfer_auth_cookies_and_channel_ids_on_first_login
,
70 bool transfer_saml_auth_cookies_on_subsequent_login
);
72 net::CookieList
GetUserCookies();
73 net::ChannelIDStore::ChannelIDList
GetUserChannelIDs();
75 void VerifyTransferredUserProxyAuthEntry();
76 void VerifyUserCookies(const std::string
& expected_gaia_cookie_value
,
77 const std::string
& expected_saml_idp_cookie_value
);
78 void VerifyUserChannelID(const std::string
& expected_private_key
,
79 const std::string
& expected_cert
);
82 void PopulateBrowserContext(content::BrowserContext
* browser_context
,
83 const std::string
& proxy_auth_password
,
84 const std::string
& cookie_value
,
85 const std::string
& channel_id_private_key
,
86 const std::string
& channel_id_cert
);
88 net::URLRequestContext
* GetRequestContext(
89 content::BrowserContext
* browser_context
);
90 net::HttpAuthCache
* GetProxyAuth(content::BrowserContext
* browser_context
);
91 net::CookieMonster
* GetCookies(content::BrowserContext
* browser_context
);
92 net::ChannelIDStore
* GetChannelIDs(content::BrowserContext
* browser_context
);
94 void QuitLoop(const net::CookieList
& ignored
);
95 void StoreCookieListAndQuitLoop(const net::CookieList
& cookie_list
);
96 void StoreChannelIDListAndQuitLoop(
97 const net::ChannelIDStore::ChannelIDList
& channel_id_list
);
99 content::TestBrowserThreadBundle thread_bundle_
;
101 TestingProfile login_browser_context_
;
102 TestingProfile user_browser_context_
;
104 net::CookieList user_cookie_list_
;
105 net::ChannelIDStore::ChannelIDList user_channel_id_list_
;
107 scoped_ptr
<base::RunLoop
> run_loop_
;
110 void ProfileAuthDataTest::SetUp() {
111 PopulateBrowserContext(&login_browser_context_
,
114 kChannelIDPrivateKey1
,
118 void ProfileAuthDataTest::PopulateUserBrowserContext() {
119 PopulateBrowserContext(&user_browser_context_
,
122 kChannelIDPrivateKey2
,
126 void ProfileAuthDataTest::Transfer(
127 bool transfer_auth_cookies_and_channel_ids_on_first_login
,
128 bool transfer_saml_auth_cookies_on_subsequent_login
) {
129 base::RunLoop run_loop
;
130 ProfileAuthData::Transfer(
131 &login_browser_context_
,
132 &user_browser_context_
,
133 transfer_auth_cookies_and_channel_ids_on_first_login
,
134 transfer_saml_auth_cookies_on_subsequent_login
,
135 run_loop
.QuitClosure());
137 if (!transfer_auth_cookies_and_channel_ids_on_first_login
&&
138 !transfer_saml_auth_cookies_on_subsequent_login
) {
139 // When only proxy auth state is being transferred, the completion callback
140 // is invoked before the transfer has actually completed. Spin the loop once
141 // more to allow the transfer to complete.
142 base::RunLoop().RunUntilIdle();
146 net::CookieList
ProfileAuthDataTest::GetUserCookies() {
147 run_loop_
.reset(new base::RunLoop
);
148 GetCookies(&user_browser_context_
)->GetAllCookiesAsync(base::Bind(
149 &ProfileAuthDataTest::StoreCookieListAndQuitLoop
,
150 base::Unretained(this)));
152 return user_cookie_list_
;
155 net::ChannelIDStore::ChannelIDList
ProfileAuthDataTest::GetUserChannelIDs() {
156 run_loop_
.reset(new base::RunLoop
);
157 GetChannelIDs(&user_browser_context_
)->GetAllChannelIDs(base::Bind(
158 &ProfileAuthDataTest::StoreChannelIDListAndQuitLoop
,
159 base::Unretained(this)));
161 return user_channel_id_list_
;
164 void ProfileAuthDataTest::VerifyTransferredUserProxyAuthEntry() {
165 net::HttpAuthCache::Entry
* entry
=
166 GetProxyAuth(&user_browser_context_
)->Lookup(
169 net::HttpAuth::AUTH_SCHEME_BASIC
);
171 EXPECT_EQ(base::ASCIIToUTF16(kProxyAuthPassword1
),
172 entry
->credentials().password());
175 void ProfileAuthDataTest::VerifyUserCookies(
176 const std::string
& expected_gaia_cookie_value
,
177 const std::string
& expected_saml_idp_cookie_value
) {
178 net::CookieList user_cookies
= GetUserCookies();
179 ASSERT_EQ(2u, user_cookies
.size());
180 net::CanonicalCookie
* cookie
= &user_cookies
[0];
181 EXPECT_EQ(kSAMLIdPCookieURL
, cookie
->Source());
182 EXPECT_EQ(kCookieName
, cookie
->Name());
183 EXPECT_EQ(expected_saml_idp_cookie_value
, cookie
->Value());
184 EXPECT_EQ(kSAMLIdPCookieDomain
, cookie
->Domain());
185 cookie
= &user_cookies
[1];
186 EXPECT_EQ(kGAIACookieURL
, cookie
->Source());
187 EXPECT_EQ(kCookieName
, cookie
->Name());
188 EXPECT_EQ(expected_gaia_cookie_value
, cookie
->Value());
189 EXPECT_EQ(kGAIACookieDomain
, cookie
->Domain());
192 void ProfileAuthDataTest::VerifyUserChannelID(
193 const std::string
& expected_private_key
,
194 const std::string
& expected_cert
) {
195 net::ChannelIDStore::ChannelIDList user_channel_ids
= GetUserChannelIDs();
196 ASSERT_EQ(1u, user_channel_ids
.size());
197 net::ChannelIDStore::ChannelID
* channel_id
= &user_channel_ids
.front();
198 EXPECT_EQ(kChannelIDServerIdentifier
, channel_id
->server_identifier());
199 EXPECT_EQ(expected_private_key
, channel_id
->private_key());
200 EXPECT_EQ(expected_cert
, channel_id
->cert());
203 void ProfileAuthDataTest::PopulateBrowserContext(
204 content::BrowserContext
* browser_context
,
205 const std::string
& proxy_auth_password
,
206 const std::string
& cookie_value
,
207 const std::string
& channel_id_private_key
,
208 const std::string
& channel_id_cert
) {
209 GetProxyAuth(browser_context
)->Add(
212 net::HttpAuth::AUTH_SCHEME_BASIC
,
214 net::AuthCredentials(base::string16(),
215 base::ASCIIToUTF16(proxy_auth_password
)),
218 net::CookieMonster
* cookies
= GetCookies(browser_context
);
219 // Ensure |cookies| is fully initialized.
220 run_loop_
.reset(new base::RunLoop
);
221 cookies
->GetAllCookiesAsync(base::Bind(&ProfileAuthDataTest::QuitLoop
,
222 base::Unretained(this)));
225 net::CookieList cookie_list
;
226 cookie_list
.push_back(net::CanonicalCookie(
227 GURL(kGAIACookieURL
), kCookieName
, cookie_value
, kGAIACookieDomain
,
228 std::string(), base::Time(), base::Time(), base::Time(), true, false,
229 false, net::COOKIE_PRIORITY_DEFAULT
));
230 cookie_list
.push_back(net::CanonicalCookie(
231 GURL(kSAMLIdPCookieURL
), kCookieName
, cookie_value
, kSAMLIdPCookieDomain
,
232 std::string(), base::Time(), base::Time(), base::Time(), true, false,
233 false, net::COOKIE_PRIORITY_DEFAULT
));
234 cookies
->ImportCookies(cookie_list
);
236 GetChannelIDs(browser_context
)->SetChannelID(kChannelIDServerIdentifier
,
239 channel_id_private_key
,
243 net::URLRequestContext
* ProfileAuthDataTest::GetRequestContext(
244 content::BrowserContext
* browser_context
) {
245 return browser_context
->GetRequestContext()->GetURLRequestContext();
248 net::HttpAuthCache
* ProfileAuthDataTest::GetProxyAuth(
249 content::BrowserContext
* browser_context
) {
250 return GetRequestContext(browser_context
)->http_transaction_factory()->
251 GetSession()->http_auth_cache();
254 net::CookieMonster
* ProfileAuthDataTest::GetCookies(
255 content::BrowserContext
* browser_context
) {
256 return GetRequestContext(browser_context
)->cookie_store()->GetCookieMonster();
259 net::ChannelIDStore
* ProfileAuthDataTest::GetChannelIDs(
260 content::BrowserContext
* browser_context
) {
261 return GetRequestContext(browser_context
)->channel_id_service()->
265 void ProfileAuthDataTest::QuitLoop(const net::CookieList
& ignored
) {
269 void ProfileAuthDataTest::StoreCookieListAndQuitLoop(
270 const net::CookieList
& cookie_list
) {
271 user_cookie_list_
= cookie_list
;
275 void ProfileAuthDataTest::StoreChannelIDListAndQuitLoop(
276 const net::ChannelIDStore::ChannelIDList
& channel_id_list
) {
277 user_channel_id_list_
= channel_id_list
;
281 // Verifies that when no transfer of auth cookies or channel IDs is requested,
282 // only the proxy auth state is transferred.
283 TEST_F(ProfileAuthDataTest
, DoNotTransfer
) {
284 Transfer(false, false);
286 VerifyTransferredUserProxyAuthEntry();
287 EXPECT_TRUE(GetUserCookies().empty());
288 EXPECT_TRUE(GetUserChannelIDs().empty());
291 // Verifies that when the transfer of auth cookies and channel IDs on first
292 // login is requested, they do get transferred along with the proxy auth state
294 TEST_F(ProfileAuthDataTest
, TransferOnFirstLoginWithNewProfile
) {
295 Transfer(true, false);
297 VerifyTransferredUserProxyAuthEntry();
298 VerifyUserCookies(kCookieValue1
, kCookieValue1
);
299 VerifyUserChannelID(kChannelIDPrivateKey1
, kChannelIDCert1
);
302 // Verifies that even if the transfer of auth cookies and channel IDs on first
303 // login is requested, only the proxy auth state is transferred on subsequent
305 TEST_F(ProfileAuthDataTest
, TransferOnFirstLoginWithExistingProfile
) {
306 PopulateUserBrowserContext();
308 Transfer(true, false);
310 VerifyTransferredUserProxyAuthEntry();
311 VerifyUserCookies(kCookieValue2
, kCookieValue2
);
312 VerifyUserChannelID(kChannelIDPrivateKey2
, kChannelIDCert2
);
315 // Verifies that when the transfer of auth cookies set by a SAML IdP on
316 // subsequent login is requested, they do get transferred along with the proxy
317 // auth state on subsequent login.
318 TEST_F(ProfileAuthDataTest
, TransferOnSubsequentLogin
) {
319 PopulateUserBrowserContext();
321 Transfer(false, true);
323 VerifyTransferredUserProxyAuthEntry();
324 VerifyUserCookies(kCookieValue2
, kCookieValue1
);
325 VerifyUserChannelID(kChannelIDPrivateKey2
, kChannelIDCert2
);
328 } // namespace chromeos