• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9 
10 #include "net/http/http_auth_handler_mock.h"
11 
12 #include <utility>
13 
14 #include "base/functional/bind.h"
15 #include "base/location.h"
16 #include "base/memory/ptr_util.h"
17 #include "base/strings/string_util.h"
18 #include "base/task/single_thread_task_runner.h"
19 #include "net/base/net_errors.h"
20 #include "net/dns/host_resolver.h"
21 #include "net/http/http_auth_challenge_tokenizer.h"
22 #include "net/http/http_request_info.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 
26 namespace net {
27 
PrintTo(const HttpAuthHandlerMock::State & state,::std::ostream * os)28 void PrintTo(const HttpAuthHandlerMock::State& state, ::std::ostream* os) {
29   switch (state) {
30     case HttpAuthHandlerMock::State::WAIT_FOR_INIT:
31       *os << "WAIT_FOR_INIT";
32       break;
33     case HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE:
34       *os << "WAIT_FOR_CHALLENGE";
35       break;
36     case HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN:
37       *os << "WAIT_FOR_GENERATE_AUTH_TOKEN";
38       break;
39     case HttpAuthHandlerMock::State::TOKEN_PENDING:
40       *os << "TOKEN_PENDING";
41       break;
42     case HttpAuthHandlerMock::State::DONE:
43       *os << "DONE";
44       break;
45   }
46 }
47 
48 HttpAuthHandlerMock::HttpAuthHandlerMock() = default;
49 
50 HttpAuthHandlerMock::~HttpAuthHandlerMock() = default;
51 
SetGenerateExpectation(bool async,int rv)52 void HttpAuthHandlerMock::SetGenerateExpectation(bool async, int rv) {
53   generate_async_ = async;
54   generate_rv_ = rv;
55 }
56 
NeedsIdentity()57 bool HttpAuthHandlerMock::NeedsIdentity() {
58   return first_round_;
59 }
60 
AllowsDefaultCredentials()61 bool HttpAuthHandlerMock::AllowsDefaultCredentials() {
62   return allows_default_credentials_;
63 }
64 
AllowsExplicitCredentials()65 bool HttpAuthHandlerMock::AllowsExplicitCredentials() {
66   return allows_explicit_credentials_;
67 }
68 
Init(HttpAuthChallengeTokenizer * challenge,const SSLInfo & ssl_info,const NetworkAnonymizationKey & network_anonymization_key)69 bool HttpAuthHandlerMock::Init(
70     HttpAuthChallengeTokenizer* challenge,
71     const SSLInfo& ssl_info,
72     const NetworkAnonymizationKey& network_anonymization_key) {
73   EXPECT_EQ(State::WAIT_FOR_INIT, state_);
74   state_ = State::WAIT_FOR_GENERATE_AUTH_TOKEN;
75   auth_scheme_ = HttpAuth::AUTH_SCHEME_MOCK;
76   score_ = 1;
77   properties_ = connection_based_ ? IS_CONNECTION_BASED : 0;
78   return true;
79 }
80 
GenerateAuthTokenImpl(const AuthCredentials * credentials,const HttpRequestInfo * request,CompletionOnceCallback callback,std::string * auth_token)81 int HttpAuthHandlerMock::GenerateAuthTokenImpl(
82     const AuthCredentials* credentials,
83     const HttpRequestInfo* request,
84     CompletionOnceCallback callback,
85     std::string* auth_token) {
86   EXPECT_EQ(State::WAIT_FOR_GENERATE_AUTH_TOKEN, state_);
87   first_round_ = false;
88   request_url_ = request->url;
89   if (generate_async_) {
90     EXPECT_TRUE(callback_.is_null());
91     EXPECT_TRUE(auth_token_ == nullptr);
92     callback_ = std::move(callback);
93     auth_token_ = auth_token;
94     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
95         FROM_HERE, base::BindOnce(&HttpAuthHandlerMock::OnGenerateAuthToken,
96                                   weak_factory_.GetWeakPtr()));
97     state_ = State::TOKEN_PENDING;
98     return ERR_IO_PENDING;
99   } else {
100     if (generate_rv_ == OK) {
101       *auth_token = "auth_token";
102       state_ = is_connection_based() ? State::WAIT_FOR_CHALLENGE
103                                      : State::WAIT_FOR_GENERATE_AUTH_TOKEN;
104     } else {
105       state_ = State::DONE;
106     }
107     return generate_rv_;
108   }
109 }
110 
HandleAnotherChallengeImpl(HttpAuthChallengeTokenizer * challenge)111 HttpAuth::AuthorizationResult HttpAuthHandlerMock::HandleAnotherChallengeImpl(
112     HttpAuthChallengeTokenizer* challenge) {
113   EXPECT_THAT(state_, ::testing::AnyOf(State::WAIT_FOR_CHALLENGE,
114                                        State::WAIT_FOR_GENERATE_AUTH_TOKEN));
115   // If we receive an empty challenge for a connection based scheme, or a second
116   // challenge for a non connection based scheme, assume it's a rejection.
117   if (!is_connection_based() || challenge->base64_param().empty()) {
118     state_ = State::DONE;
119     return HttpAuth::AUTHORIZATION_RESULT_REJECT;
120   }
121 
122   if (challenge->auth_scheme() != "mock") {
123     state_ = State::DONE;
124     return HttpAuth::AUTHORIZATION_RESULT_INVALID;
125   }
126 
127   state_ = State::WAIT_FOR_GENERATE_AUTH_TOKEN;
128   return HttpAuth::AUTHORIZATION_RESULT_ACCEPT;
129 }
130 
OnGenerateAuthToken()131 void HttpAuthHandlerMock::OnGenerateAuthToken() {
132   EXPECT_TRUE(generate_async_);
133   EXPECT_TRUE(!callback_.is_null());
134   EXPECT_EQ(State::TOKEN_PENDING, state_);
135   if (generate_rv_ == OK) {
136     *auth_token_ = "auth_token";
137     state_ = is_connection_based() ? State::WAIT_FOR_CHALLENGE
138                                    : State::WAIT_FOR_GENERATE_AUTH_TOKEN;
139   } else {
140     state_ = State::DONE;
141   }
142   auth_token_ = nullptr;
143   std::move(callback_).Run(generate_rv_);
144 }
145 
Factory()146 HttpAuthHandlerMock::Factory::Factory() {
147   // TODO(cbentzel): Default do_init_from_challenge_ to true.
148 }
149 
150 HttpAuthHandlerMock::Factory::~Factory() = default;
151 
AddMockHandler(std::unique_ptr<HttpAuthHandler> handler,HttpAuth::Target target)152 void HttpAuthHandlerMock::Factory::AddMockHandler(
153     std::unique_ptr<HttpAuthHandler> handler,
154     HttpAuth::Target target) {
155   handlers_[target].push_back(std::move(handler));
156 }
157 
CreateAuthHandler(HttpAuthChallengeTokenizer * challenge,HttpAuth::Target target,const SSLInfo & ssl_info,const NetworkAnonymizationKey & network_anonymization_key,const url::SchemeHostPort & scheme_host_port,CreateReason reason,int nonce_count,const NetLogWithSource & net_log,HostResolver * host_resolver,std::unique_ptr<HttpAuthHandler> * handler)158 int HttpAuthHandlerMock::Factory::CreateAuthHandler(
159     HttpAuthChallengeTokenizer* challenge,
160     HttpAuth::Target target,
161     const SSLInfo& ssl_info,
162     const NetworkAnonymizationKey& network_anonymization_key,
163     const url::SchemeHostPort& scheme_host_port,
164     CreateReason reason,
165     int nonce_count,
166     const NetLogWithSource& net_log,
167     HostResolver* host_resolver,
168     std::unique_ptr<HttpAuthHandler>* handler) {
169   if (handlers_[target].empty())
170     return ERR_UNEXPECTED;
171   std::unique_ptr<HttpAuthHandler> tmp_handler =
172       std::move(handlers_[target][0]);
173   std::vector<std::unique_ptr<HttpAuthHandler>>& handlers = handlers_[target];
174   handlers.erase(handlers.begin());
175   if (do_init_from_challenge_ &&
176       !tmp_handler->InitFromChallenge(challenge, target, ssl_info,
177                                       network_anonymization_key,
178                                       scheme_host_port, net_log)) {
179     return ERR_INVALID_RESPONSE;
180   }
181   handler->swap(tmp_handler);
182   return OK;
183 }
184 
185 }  // namespace net
186