Home | History | Annotate | Download | only in login
      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.
      4 
      5 #include "chrome/browser/chromeos/login/profile_auth_data.h"
      6 
      7 #include <string>
      8 
      9 #include "base/bind.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"
     33 #include "url/gurl.h"
     34 
     35 namespace chromeos {
     36 
     37 namespace {
     38 
     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";
     44 
     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";
     52 
     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";
     58 
     59 }  // namespace
     60 
     61 class ProfileAuthDataTest : public testing::Test {
     62  public:
     63   // testing::Test:
     64   virtual void SetUp() OVERRIDE;
     65 
     66   void PopulateUserBrowserContext();
     67 
     68   void Transfer(
     69       bool transfer_auth_cookies_and_channel_ids_on_first_login,
     70       bool transfer_saml_auth_cookies_on_subsequent_login);
     71 
     72   net::CookieList GetUserCookies();
     73   net::ChannelIDStore::ChannelIDList GetUserChannelIDs();
     74 
     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);
     80 
     81  private:
     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);
     87 
     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);
     93 
     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);
     98 
     99   content::TestBrowserThreadBundle thread_bundle_;
    100 
    101   TestingProfile login_browser_context_;
    102   TestingProfile user_browser_context_;
    103 
    104   net::CookieList user_cookie_list_;
    105   net::ChannelIDStore::ChannelIDList user_channel_id_list_;
    106 
    107   scoped_ptr<base::RunLoop> run_loop_;
    108 };
    109 
    110 void ProfileAuthDataTest::SetUp() {
    111   PopulateBrowserContext(&login_browser_context_,
    112                          kProxyAuthPassword1,
    113                          kCookieValue1,
    114                          kChannelIDPrivateKey1,
    115                          kChannelIDCert1);
    116 }
    117 
    118 void ProfileAuthDataTest::PopulateUserBrowserContext() {
    119   PopulateBrowserContext(&user_browser_context_,
    120                          kProxyAuthPassword2,
    121                          kCookieValue2,
    122                          kChannelIDPrivateKey2,
    123                          kChannelIDCert2);
    124 }
    125 
    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());
    136   run_loop.Run();
    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();
    143   }
    144 }
    145 
    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)));
    151   run_loop_->Run();
    152   return user_cookie_list_;
    153 }
    154 
    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)));
    160   run_loop_->Run();
    161   return user_channel_id_list_;
    162 }
    163 
    164 void ProfileAuthDataTest::VerifyTransferredUserProxyAuthEntry() {
    165   net::HttpAuthCache::Entry* entry =
    166       GetProxyAuth(&user_browser_context_)->Lookup(
    167           GURL(kProxyAuthURL),
    168           kProxyAuthRealm,
    169           net::HttpAuth::AUTH_SCHEME_BASIC);
    170   ASSERT_TRUE(entry);
    171   EXPECT_EQ(base::ASCIIToUTF16(kProxyAuthPassword1),
    172             entry->credentials().password());
    173 }
    174 
    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());
    190 }
    191 
    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());
    201 }
    202 
    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(
    210       GURL(kProxyAuthURL),
    211       kProxyAuthRealm,
    212       net::HttpAuth::AUTH_SCHEME_BASIC,
    213       kProxyAuthChallenge,
    214       net::AuthCredentials(base::string16(),
    215                            base::ASCIIToUTF16(proxy_auth_password)),
    216       std::string());
    217 
    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)));
    223   run_loop_->Run();
    224 
    225   net::CookieList cookie_list;
    226   cookie_list.push_back(net::CanonicalCookie(GURL(kGAIACookieURL),
    227                                              kCookieName,
    228                                              cookie_value,
    229                                              kGAIACookieDomain,
    230                                              std::string(),
    231                                              base::Time(),
    232                                              base::Time(),
    233                                              base::Time(),
    234                                              true,
    235                                              false,
    236                                              net::COOKIE_PRIORITY_DEFAULT));
    237   cookie_list.push_back(net::CanonicalCookie(GURL(kSAMLIdPCookieURL),
    238                                              kCookieName,
    239                                              cookie_value,
    240                                              kSAMLIdPCookieDomain,
    241                                              std::string(),
    242                                              base::Time(),
    243                                              base::Time(),
    244                                              base::Time(),
    245                                              true,
    246                                              false,
    247                                              net::COOKIE_PRIORITY_DEFAULT));
    248   cookies->ImportCookies(cookie_list);
    249 
    250   GetChannelIDs(browser_context)->SetChannelID(kChannelIDServerIdentifier,
    251                                                base::Time(),
    252                                                base::Time(),
    253                                                channel_id_private_key,
    254                                                channel_id_cert);
    255 }
    256 
    257 net::URLRequestContext* ProfileAuthDataTest::GetRequestContext(
    258     content::BrowserContext* browser_context) {
    259   return browser_context->GetRequestContext()->GetURLRequestContext();
    260 }
    261 
    262 net::HttpAuthCache* ProfileAuthDataTest::GetProxyAuth(
    263     content::BrowserContext* browser_context) {
    264   return GetRequestContext(browser_context)->http_transaction_factory()->
    265       GetSession()->http_auth_cache();
    266 }
    267 
    268 net::CookieMonster* ProfileAuthDataTest::GetCookies(
    269     content::BrowserContext* browser_context) {
    270   return GetRequestContext(browser_context)->cookie_store()->GetCookieMonster();
    271 }
    272 
    273 net::ChannelIDStore* ProfileAuthDataTest::GetChannelIDs(
    274     content::BrowserContext* browser_context) {
    275   return GetRequestContext(browser_context)->channel_id_service()->
    276       GetChannelIDStore();
    277 }
    278 
    279 void ProfileAuthDataTest::QuitLoop(const net::CookieList& ignored) {
    280   run_loop_->Quit();
    281 }
    282 
    283 void ProfileAuthDataTest::StoreCookieListAndQuitLoop(
    284     const net::CookieList& cookie_list) {
    285   user_cookie_list_ = cookie_list;
    286   run_loop_->Quit();
    287 }
    288 
    289 void ProfileAuthDataTest::StoreChannelIDListAndQuitLoop(
    290     const net::ChannelIDStore::ChannelIDList& channel_id_list) {
    291   user_channel_id_list_ = channel_id_list;
    292   run_loop_->Quit();
    293 }
    294 
    295 // Verifies that when no transfer of auth cookies or channel IDs is requested,
    296 // only the proxy auth state is transferred.
    297 TEST_F(ProfileAuthDataTest, DoNotTransfer) {
    298   Transfer(false, false);
    299 
    300   VerifyTransferredUserProxyAuthEntry();
    301   EXPECT_TRUE(GetUserCookies().empty());
    302   EXPECT_TRUE(GetUserChannelIDs().empty());
    303 }
    304 
    305 // Verifies that when the transfer of auth cookies and channel IDs on first
    306 // login is requested, they do get transferred along with the proxy auth state
    307 // on first login.
    308 TEST_F(ProfileAuthDataTest, TransferOnFirstLoginWithNewProfile) {
    309   Transfer(true, false);
    310 
    311   VerifyTransferredUserProxyAuthEntry();
    312   VerifyUserCookies(kCookieValue1, kCookieValue1);
    313   VerifyUserChannelID(kChannelIDPrivateKey1, kChannelIDCert1);
    314 }
    315 
    316 // Verifies that even if the transfer of auth cookies and channel IDs on first
    317 // login is requested, only the proxy auth state is transferred on subsequent
    318 // login.
    319 TEST_F(ProfileAuthDataTest, TransferOnFirstLoginWithExistingProfile) {
    320   PopulateUserBrowserContext();
    321 
    322   Transfer(true, false);
    323 
    324   VerifyTransferredUserProxyAuthEntry();
    325   VerifyUserCookies(kCookieValue2, kCookieValue2);
    326   VerifyUserChannelID(kChannelIDPrivateKey2, kChannelIDCert2);
    327 }
    328 
    329 // Verifies that when the transfer of auth cookies set by a SAML IdP on
    330 // subsequent login is requested, they do get transferred along with the proxy
    331 // auth state on subsequent login.
    332 TEST_F(ProfileAuthDataTest, TransferOnSubsequentLogin) {
    333   PopulateUserBrowserContext();
    334 
    335   Transfer(false, true);
    336 
    337   VerifyTransferredUserProxyAuthEntry();
    338   VerifyUserCookies(kCookieValue2, kCookieValue1);
    339   VerifyUserChannelID(kChannelIDPrivateKey2, kChannelIDCert2);
    340 }
    341 
    342 }  // namespace chromeos
    343