blob: 756fd96393f83cc17146dabf028ef3e061ca7ac8 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.h"
#include "net/base/auth.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace data_reduction_proxy {
namespace {
const char kInvalidTestRealm[] = "invalid-test-realm";
const char kTestChallenger[] = "https://test-challenger.com:443";
const char kTestRealm[] = "test-realm";
const char kTestToken[] = "test-token";
const char kTestUser[] = "fw-cookie";
} // namespace
// Test class that overrides underlying calls to see if an auth challenge is
// acceptible for the data reduction proxy, and to get a valid token if so.
class TestDataReductionProxyAuthRequestHandler
: public DataReductionProxyAuthRequestHandler {
public:
TestDataReductionProxyAuthRequestHandler(int time_step_ms,
int64 initial_time_ms,
DataReductionProxySettings* settings)
: DataReductionProxyAuthRequestHandler(settings),
time_step_ms_(time_step_ms),
now_(base::TimeTicks() +
base::TimeDelta::FromMilliseconds(initial_time_ms)) {}
protected:
// Test implementation.
virtual bool IsAcceptableAuthChallenge(
net::AuthChallengeInfo* auth_info) OVERRIDE {
if (net::HostPortPair::FromString(
kTestChallenger).Equals(auth_info->challenger) &&
auth_info->realm == kTestRealm) {
return true;
}
return false;
}
// Test implementation.
virtual base::string16 GetTokenForAuthChallenge(
net::AuthChallengeInfo* auth_info) OVERRIDE {
return base::ASCIIToUTF16(kTestToken);
}
virtual base::TimeTicks Now() OVERRIDE {
now_ += base::TimeDelta::FromMilliseconds(time_step_ms_);
return now_;
}
int time_step_ms_;
base::TimeTicks now_;
};
class DataReductionProxyAuthRequestHandlerTest : public testing::Test {
public:
virtual void SetUp() OVERRIDE {
DataReductionProxySettingsTestBase::AddTestProxyToCommandLine();
settings_.reset(
new MockDataReductionProxySettings<DataReductionProxySettings>(
DataReductionProxyParams::kAllowed |
DataReductionProxyParams::kFallbackAllowed |
DataReductionProxyParams::kPromoAllowed));
}
// Checks that |PROCEED| was returned with expected user and password.
void ExpectProceed(
DataReductionProxyAuthRequestHandler::TryHandleResult result,
const base::string16& user,
const base::string16& password) {
base::string16 expected_user = base::ASCIIToUTF16(kTestUser);
base::string16 expected_password = base::ASCIIToUTF16(kTestToken);
EXPECT_EQ(DataReductionProxyAuthRequestHandler::TRY_HANDLE_RESULT_PROCEED,
result);
EXPECT_EQ(expected_user, user);
EXPECT_EQ(expected_password, password);
}
// Checks that |CANCEL| was returned.
void ExpectCancel(
DataReductionProxyAuthRequestHandler::TryHandleResult result,
const base::string16& user,
const base::string16& password) {
EXPECT_EQ(DataReductionProxyAuthRequestHandler::TRY_HANDLE_RESULT_CANCEL,
result);
EXPECT_EQ(base::string16(), user);
EXPECT_EQ(base::string16(), password);
}
// Checks that |IGNORE| was returned.
void ExpectIgnore(
DataReductionProxyAuthRequestHandler::TryHandleResult result,
const base::string16& user,
const base::string16& password) {
EXPECT_EQ(DataReductionProxyAuthRequestHandler::TRY_HANDLE_RESULT_IGNORE,
result);
EXPECT_EQ(base::string16(), user);
EXPECT_EQ(base::string16(), password);
}
scoped_ptr<DataReductionProxySettings> settings_;
};
TEST_F(DataReductionProxyAuthRequestHandlerTest,
CancelAfterSuccessiveAuthAttempts) {
DataReductionProxyAuthRequestHandler::auth_request_timestamp_ = 0;
DataReductionProxyAuthRequestHandler::back_to_back_failure_count_ = 0;
DataReductionProxyAuthRequestHandler::auth_token_invalidation_timestamp_ = 0;
scoped_refptr<net::AuthChallengeInfo> auth_info(new net::AuthChallengeInfo);
auth_info->realm = kTestRealm;
auth_info->challenger = net::HostPortPair::FromString(kTestChallenger);
TestDataReductionProxyAuthRequestHandler handler(
499, 3600001, settings_.get());
base::string16 user, password;
DataReductionProxyAuthRequestHandler::TryHandleResult result =
handler.TryHandleAuthentication(auth_info.get(), &user, &password);
ExpectProceed(result, user, password);
// Successive retries should also succeed up to a maximum count.
for (int i = 0; i < 5; ++i) {
user = base::string16();
password = base::string16();
result = handler.TryHandleAuthentication(auth_info.get(), &user, &password);
ExpectProceed(result, user, password);
}
// Then another retry should fail.
user = base::string16();
password = base::string16();
result = handler.TryHandleAuthentication(auth_info.get(), &user, &password);
ExpectCancel(result, user, password);
// After canceling, the next one should proceed.
user = base::string16();
password = base::string16();
result = handler.TryHandleAuthentication(auth_info.get(), &user, &password);
ExpectProceed(result, user, password);
}
TEST_F(DataReductionProxyAuthRequestHandlerTest, Ignore) {
scoped_refptr<net::AuthChallengeInfo> auth_info(new net::AuthChallengeInfo);
auth_info->realm = kInvalidTestRealm;
auth_info->challenger = net::HostPortPair::FromString(kTestChallenger);
TestDataReductionProxyAuthRequestHandler handler(
100, 3600001, settings_.get());
base::string16 user, password;
DataReductionProxyAuthRequestHandler::TryHandleResult result =
handler.TryHandleAuthentication(auth_info.get(), &user, &password);
ExpectIgnore(result, user, password);
}
} // namespace data_reduction_proxy