15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/ftp/ftp_auth_cache.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
85e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/auth.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::ASCIIToUTF16;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::FtpAuthCache;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBogus(ASCIIToUTF16("bogus"));
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kOthername(ASCIIToUTF16("othername"));
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kOtherword(ASCIIToUTF16("otherword"));
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kPassword(ASCIIToUTF16("password"));
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kPassword1(ASCIIToUTF16("password1"));
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kPassword2(ASCIIToUTF16("password2"));
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kPassword3(ASCIIToUTF16("password3"));
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kUsername(ASCIIToUTF16("username"));
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kUsername1(ASCIIToUTF16("username1"));
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kUsername2(ASCIIToUTF16("username2"));
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kUsername3(ASCIIToUTF16("username3"));
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FtpAuthCacheTest, LookupAddRemove) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FtpAuthCache cache;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin1("ftp://foo1");
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin2("ftp://foo2");
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lookup non-existent entry.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(cache.Lookup(origin1) == NULL);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add entry for origin1.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Add(origin1, net::AuthCredentials(kUsername1, kPassword1));
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FtpAuthCache::Entry* entry1 = cache.Lookup(origin1);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry1);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(origin1, entry1->origin);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUsername1, entry1->credentials.username());
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kPassword1, entry1->credentials.password());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add an entry for origin2.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Add(origin2, net::AuthCredentials(kUsername2, kPassword2));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FtpAuthCache::Entry* entry2 = cache.Lookup(origin2);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry2);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(origin2, entry2->origin);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUsername2, entry2->credentials.username());
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kPassword2, entry2->credentials.password());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The original entry1 should still be there.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(entry1, cache.Lookup(origin1));
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overwrite the entry for origin1.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Add(origin1, net::AuthCredentials(kUsername3, kPassword3));
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FtpAuthCache::Entry* entry3 = cache.Lookup(origin1);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry3);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(origin1, entry3->origin);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUsername3, entry3->credentials.username());
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kPassword3, entry3->credentials.password());
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove entry of origin1.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Remove(origin1, net::AuthCredentials(kUsername3, kPassword3));
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(cache.Lookup(origin1) == NULL);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove non-existent entry.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Remove(origin1, net::AuthCredentials(kUsername3, kPassword3));
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(cache.Lookup(origin1) == NULL);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that if the origin differs only by port number, it is considered
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a separate origin.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FtpAuthCacheTest, LookupWithPort) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FtpAuthCache cache;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin1("ftp://foo:80");
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin2("ftp://foo:21");
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Add(origin1, net::AuthCredentials(kUsername, kPassword));
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Add(origin2, net::AuthCredentials(kUsername, kPassword));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(cache.Lookup(origin1), cache.Lookup(origin2));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FtpAuthCacheTest, NormalizedKey) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GURL is automatically canonicalized. Hence the following variations in
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // url format should all map to the same entry (case insensitive host,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // default port of 21).
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FtpAuthCache cache;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Add(GURL("ftp://HoSt:21"), net::AuthCredentials(kUsername, kPassword));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lookup.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FtpAuthCache::Entry* entry1 = cache.Lookup(GURL("ftp://HoSt:21"));
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry1);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(entry1, cache.Lookup(GURL("ftp://host:21")));
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(entry1, cache.Lookup(GURL("ftp://host")));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overwrite.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Add(GURL("ftp://host"), net::AuthCredentials(kOthername, kOtherword));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FtpAuthCache::Entry* entry2 = cache.Lookup(GURL("ftp://HoSt:21"));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry2);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("ftp://host"), entry2->origin);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kOthername, entry2->credentials.username());
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kOtherword, entry2->credentials.password());
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Remove(GURL("ftp://HOsT"),
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               net::AuthCredentials(kOthername, kOtherword));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(cache.Lookup(GURL("ftp://host")) == NULL);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FtpAuthCacheTest, OnlyRemoveMatching) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FtpAuthCache cache;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Add(GURL("ftp://host"), net::AuthCredentials(kUsername, kPassword));
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(cache.Lookup(GURL("ftp://host")));
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Auth data doesn't match, shouldn't remove.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Remove(GURL("ftp://host"), net::AuthCredentials(kBogus, kBogus));
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(cache.Lookup(GURL("ftp://host")));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Auth data matches, should remove.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Remove(GURL("ftp://host"), net::AuthCredentials(kUsername, kPassword));
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(cache.Lookup(GURL("ftp://host")) == NULL);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(FtpAuthCacheTest, EvictOldEntries) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FtpAuthCache cache;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < FtpAuthCache::kMaxEntries; i++) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache.Add(GURL("ftp://host" + base::IntToString(i)),
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              net::AuthCredentials(kUsername, kPassword));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No entries should be evicted before reaching the limit.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < FtpAuthCache::kMaxEntries; i++) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(cache.Lookup(GURL("ftp://host" + base::IntToString(i))));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adding one entry should cause eviction of the first entry.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache.Add(GURL("ftp://last_host"),
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::AuthCredentials(kUsername, kPassword));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(cache.Lookup(GURL("ftp://host0")) == NULL);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remaining entries should not get evicted.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 1; i < FtpAuthCache::kMaxEntries; i++) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(cache.Lookup(GURL("ftp://host" + base::IntToString(i))));
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(cache.Lookup(GURL("ftp://last_host")));
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
161