Home | History | Annotate | Download | only in browser
      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 
      6 #include "components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h"
      7 
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/strings/string16.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "base/time/time.h"
     12 #include "components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.h"
     13 #include "net/base/auth.h"
     14 #include "testing/gmock/include/gmock/gmock.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace data_reduction_proxy {
     18 
     19 namespace {
     20 
     21 const char kInvalidTestRealm[] = "invalid-test-realm";
     22 const char kTestChallenger[] = "https://test-challenger.com:443";
     23 const char kTestRealm[] = "test-realm";
     24 const char kTestToken[] = "test-token";
     25 const char kTestUser[] = "fw-cookie";
     26 
     27 }  // namespace
     28 
     29 // Test class that overrides underlying calls to see if an auth challenge is
     30 // acceptible for the data reduction proxy, and to get a valid token if so.
     31 class TestDataReductionProxyAuthRequestHandler
     32     : public DataReductionProxyAuthRequestHandler {
     33  public:
     34   TestDataReductionProxyAuthRequestHandler(int time_step_ms,
     35                                            int64 initial_time_ms,
     36                                            DataReductionProxySettings* settings)
     37       : DataReductionProxyAuthRequestHandler(settings),
     38         time_step_ms_(time_step_ms),
     39         now_(base::TimeTicks() +
     40              base::TimeDelta::FromMilliseconds(initial_time_ms)) {}
     41  protected:
     42   // Test implementation.
     43   virtual bool IsAcceptableAuthChallenge(
     44       net::AuthChallengeInfo* auth_info) OVERRIDE {
     45     if (net::HostPortPair::FromString(
     46         kTestChallenger).Equals(auth_info->challenger) &&
     47         auth_info->realm == kTestRealm) {
     48     return true;
     49     }
     50     return false;
     51   }
     52 
     53   // Test implementation.
     54   virtual base::string16 GetTokenForAuthChallenge(
     55       net::AuthChallengeInfo* auth_info) OVERRIDE {
     56     return base::ASCIIToUTF16(kTestToken);
     57   }
     58 
     59   virtual base::TimeTicks Now() OVERRIDE {
     60     now_ += base::TimeDelta::FromMilliseconds(time_step_ms_);
     61     return now_;
     62   }
     63   int time_step_ms_;
     64   base::TimeTicks now_;
     65 };
     66 
     67 class DataReductionProxyAuthRequestHandlerTest : public testing::Test {
     68  public:
     69 
     70   virtual void SetUp() OVERRIDE {
     71     DataReductionProxySettingsTestBase::AddTestProxyToCommandLine();
     72     settings_.reset(
     73         new MockDataReductionProxySettings<DataReductionProxySettings>(
     74             DataReductionProxyParams::kAllowed |
     75             DataReductionProxyParams::kFallbackAllowed |
     76             DataReductionProxyParams::kPromoAllowed));
     77   }
     78 
     79   // Checks that |PROCEED| was returned with expected user and password.
     80   void ExpectProceed(
     81       DataReductionProxyAuthRequestHandler::TryHandleResult result,
     82       const base::string16& user,
     83       const base::string16& password) {
     84     base::string16 expected_user = base::ASCIIToUTF16(kTestUser);
     85     base::string16 expected_password = base::ASCIIToUTF16(kTestToken);
     86     EXPECT_EQ(DataReductionProxyAuthRequestHandler::TRY_HANDLE_RESULT_PROCEED,
     87               result);
     88     EXPECT_EQ(expected_user, user);
     89     EXPECT_EQ(expected_password, password);
     90   }
     91 
     92   // Checks that |CANCEL| was returned.
     93   void ExpectCancel(
     94       DataReductionProxyAuthRequestHandler::TryHandleResult result,
     95       const base::string16& user,
     96       const base::string16& password) {
     97     EXPECT_EQ(DataReductionProxyAuthRequestHandler::TRY_HANDLE_RESULT_CANCEL,
     98               result);
     99     EXPECT_EQ(base::string16(), user);
    100     EXPECT_EQ(base::string16(), password);
    101   }
    102 
    103   // Checks that |IGNORE| was returned.
    104   void ExpectIgnore(
    105       DataReductionProxyAuthRequestHandler::TryHandleResult result,
    106       const base::string16& user,
    107       const base::string16& password) {
    108     EXPECT_EQ(DataReductionProxyAuthRequestHandler::TRY_HANDLE_RESULT_IGNORE,
    109               result);
    110     EXPECT_EQ(base::string16(), user);
    111     EXPECT_EQ(base::string16(), password);
    112   }
    113 
    114   scoped_ptr<DataReductionProxySettings> settings_;
    115 };
    116 
    117 TEST_F(DataReductionProxyAuthRequestHandlerTest,
    118        CancelAfterSuccessiveAuthAttempts) {
    119   DataReductionProxyAuthRequestHandler::auth_request_timestamp_ = 0;
    120   DataReductionProxyAuthRequestHandler::back_to_back_failure_count_ = 0;
    121   DataReductionProxyAuthRequestHandler::auth_token_invalidation_timestamp_ = 0;
    122   scoped_refptr<net::AuthChallengeInfo> auth_info(new net::AuthChallengeInfo);
    123   auth_info->realm =  kTestRealm;
    124   auth_info->challenger = net::HostPortPair::FromString(kTestChallenger);
    125   TestDataReductionProxyAuthRequestHandler handler(
    126       499, 3600001, settings_.get());
    127   base::string16 user, password;
    128   DataReductionProxyAuthRequestHandler::TryHandleResult result =
    129       handler.TryHandleAuthentication(auth_info.get(), &user, &password);
    130   ExpectProceed(result, user, password);
    131 
    132   // Successive retries should also succeed up to a maximum count.
    133   for (int i = 0; i < 5; ++i) {
    134     user = base::string16();
    135     password = base::string16();
    136     result = handler.TryHandleAuthentication(auth_info.get(), &user, &password);
    137     ExpectProceed(result, user, password);
    138   }
    139 
    140   // Then another retry should fail.
    141   user = base::string16();
    142   password = base::string16();
    143   result = handler.TryHandleAuthentication(auth_info.get(), &user, &password);
    144   ExpectCancel(result, user, password);
    145 
    146   // After canceling, the next one should proceed.
    147   user = base::string16();
    148   password = base::string16();
    149   result = handler.TryHandleAuthentication(auth_info.get(), &user, &password);
    150   ExpectProceed(result, user, password);
    151 }
    152 
    153 TEST_F(DataReductionProxyAuthRequestHandlerTest, Ignore) {
    154   scoped_refptr<net::AuthChallengeInfo> auth_info(new net::AuthChallengeInfo);
    155   auth_info->realm =  kInvalidTestRealm;
    156   auth_info->challenger = net::HostPortPair::FromString(kTestChallenger);
    157   TestDataReductionProxyAuthRequestHandler handler(
    158       100, 3600001, settings_.get());
    159   base::string16 user, password;
    160   DataReductionProxyAuthRequestHandler::TryHandleResult result =
    161       handler.TryHandleAuthentication(auth_info.get(), &user, &password);
    162   ExpectIgnore(result, user, password);
    163 }
    164 
    165 }  // namespace data_reduction_proxy
    166