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