| OLD | NEW | 
|    1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |    1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "net/http/http_auth_controller.h" |    5 #include "net/http/http_auth_controller.h" | 
|    6  |    6  | 
|    7 #include "base/strings/utf_string_conversions.h" |    7 #include "base/strings/utf_string_conversions.h" | 
|    8 #include "net/base/net_errors.h" |    8 #include "net/base/net_errors.h" | 
|    9 #include "net/base/test_completion_callback.h" |    9 #include "net/base/test_completion_callback.h" | 
|   10 #include "net/http/http_auth_cache.h" |   10 #include "net/http/http_auth_cache.h" | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   79   EXPECT_TRUE(controller->HaveAuth()); |   79   EXPECT_TRUE(controller->HaveAuth()); | 
|   80  |   80  | 
|   81   TestCompletionCallback callback; |   81   TestCompletionCallback callback; | 
|   82   EXPECT_EQ((run_mode == RUN_HANDLER_ASYNC)? ERR_IO_PENDING: |   82   EXPECT_EQ((run_mode == RUN_HANDLER_ASYNC)? ERR_IO_PENDING: | 
|   83             expected_controller_rv, |   83             expected_controller_rv, | 
|   84             controller->MaybeGenerateAuthToken(&request, callback.callback(), |   84             controller->MaybeGenerateAuthToken(&request, callback.callback(), | 
|   85                                                dummy_log)); |   85                                                dummy_log)); | 
|   86   if (run_mode == RUN_HANDLER_ASYNC) |   86   if (run_mode == RUN_HANDLER_ASYNC) | 
|   87     EXPECT_EQ(expected_controller_rv, callback.WaitForResult()); |   87     EXPECT_EQ(expected_controller_rv, callback.WaitForResult()); | 
|   88   EXPECT_EQ((scheme_state == SCHEME_IS_DISABLED), |   88   EXPECT_EQ((scheme_state == SCHEME_IS_DISABLED), | 
|   89             controller->IsAuthSchemeDisabled(HttpAuth::AUTH_SCHEME_MOCK)); |   89             controller->IsAuthSchemeDisabled("mock")); | 
|   90 } |   90 } | 
|   91  |   91  | 
|   92 }  // namespace |   92 }  // namespace | 
|   93  |   93  | 
|   94 // If an HttpAuthHandler returns an error code that indicates a |   94 // If an HttpAuthHandler returns an error code that indicates a | 
|   95 // permanent error, the HttpAuthController should disable the scheme |   95 // permanent error, the HttpAuthController should disable the scheme | 
|   96 // used and retry the request. |   96 // used and retry the request. | 
|   97 TEST(HttpAuthControllerTest, PermanentErrors) { |   97 TEST(HttpAuthControllerTest, PermanentErrors) { | 
|   98  |   98  | 
|   99   // Run a synchronous handler that returns |   99   // Run a synchronous handler that returns | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  115   RunSingleRoundAuthTest(RUN_HANDLER_ASYNC, ERR_INVALID_AUTH_CREDENTIALS, |  115   RunSingleRoundAuthTest(RUN_HANDLER_ASYNC, ERR_INVALID_AUTH_CREDENTIALS, | 
|  116                          ERR_INVALID_AUTH_CREDENTIALS, SCHEME_IS_ENABLED); |  116                          ERR_INVALID_AUTH_CREDENTIALS, SCHEME_IS_ENABLED); | 
|  117 } |  117 } | 
|  118  |  118  | 
|  119 // If an HttpAuthHandler indicates that it doesn't allow explicit |  119 // If an HttpAuthHandler indicates that it doesn't allow explicit | 
|  120 // credentials, don't prompt for credentials. |  120 // credentials, don't prompt for credentials. | 
|  121 TEST(HttpAuthControllerTest, NoExplicitCredentialsAllowed) { |  121 TEST(HttpAuthControllerTest, NoExplicitCredentialsAllowed) { | 
|  122   // Modified mock HttpAuthHandler for this test. |  122   // Modified mock HttpAuthHandler for this test. | 
|  123   class MockHandler : public HttpAuthHandlerMock { |  123   class MockHandler : public HttpAuthHandlerMock { | 
|  124    public: |  124    public: | 
|  125     MockHandler(int expected_rv, HttpAuth::Scheme scheme) |  125     MockHandler(int expected_rv, const std::string& scheme) | 
|  126         : expected_scheme_(scheme) { |  126         : expected_scheme_(scheme) { | 
|  127       SetGenerateExpectation(false, expected_rv); |  127       SetGenerateExpectation(false, expected_rv); | 
|  128     } |  128     } | 
|  129  |  129  | 
|  130    protected: |  130    protected: | 
|  131     bool Init(HttpAuthChallengeTokenizer* challenge) override { |  131     bool Init(HttpAuthChallengeTokenizer* challenge) override { | 
|  132       HttpAuthHandlerMock::Init(challenge); |  132       HttpAuthHandlerMock::Init(challenge); | 
|  133       set_allows_default_credentials(true); |  133       set_allows_default_credentials(true); | 
|  134       set_allows_explicit_credentials(false); |  134       set_allows_explicit_credentials(false); | 
|  135       set_connection_based(true); |  135       // Pretend to be Bert so we can test failover logic. | 
|  136       // Pretend to be SCHEME_BASIC so we can test failover logic. |  136       if (challenge->SchemeIs("bert")) { | 
|  137       if (challenge->scheme() == "Basic") { |  137         auth_scheme_ = "bert"; | 
|  138         auth_scheme_ = HttpAuth::AUTH_SCHEME_BASIC; |  | 
|  139         --score_;  // Reduce score, so we rank below Mock. |  | 
|  140         set_allows_explicit_credentials(true); |  138         set_allows_explicit_credentials(true); | 
 |  139       } else { | 
 |  140         auth_scheme_ = "ernie"; | 
|  141       } |  141       } | 
|  142       EXPECT_EQ(expected_scheme_, auth_scheme_); |  142       EXPECT_EQ(expected_scheme_, auth_scheme_); | 
|  143       return true; |  143       return true; | 
|  144     } |  144     } | 
|  145  |  145  | 
|  146     int GenerateAuthTokenImpl(const AuthCredentials* credentials, |  146     int GenerateAuthTokenImpl(const AuthCredentials* credentials, | 
|  147                               const HttpRequestInfo* request, |  147                               const HttpRequestInfo* request, | 
|  148                               const CompletionCallback& callback, |  148                               const CompletionCallback& callback, | 
|  149                               std::string* auth_token) override { |  149                               std::string* auth_token) override { | 
|  150       int result = |  150       int result = | 
|  151           HttpAuthHandlerMock::GenerateAuthTokenImpl(credentials, |  151           HttpAuthHandlerMock::GenerateAuthTokenImpl(credentials, | 
|  152                                                      request, callback, |  152                                                      request, callback, | 
|  153                                                      auth_token); |  153                                                      auth_token); | 
|  154       EXPECT_TRUE(result != OK || |  154       EXPECT_TRUE(result != OK || | 
|  155                   !AllowsExplicitCredentials() || |  155                   !AllowsExplicitCredentials() || | 
|  156                   !credentials->Empty()); |  156                   !credentials->Empty()); | 
|  157       return result; |  157       return result; | 
|  158     } |  158     } | 
|  159  |  159  | 
|  160    private: |  160    private: | 
|  161     HttpAuth::Scheme expected_scheme_; |  161     std::string expected_scheme_; | 
|  162   }; |  162   }; | 
|  163  |  163  | 
|  164   BoundNetLog dummy_log; |  164   BoundNetLog dummy_log; | 
|  165   HttpAuthCache dummy_auth_cache; |  165   HttpAuthCache dummy_auth_cache; | 
|  166   HttpRequestInfo request; |  166   HttpRequestInfo request; | 
|  167   request.method = "GET"; |  167   request.method = "GET"; | 
|  168   request.url = GURL("http://example.com"); |  168   request.url = GURL("http://example.com"); | 
|  169  |  169  | 
|  170   HttpRequestHeaders request_headers; |  170   HttpRequestHeaders request_headers; | 
|  171   scoped_refptr<HttpResponseHeaders> headers(HeadersFromString( |  171   scoped_refptr<HttpResponseHeaders> headers( | 
|  172       "HTTP/1.1 401\r\n" |  172       HeadersFromString("HTTP/1.1 401\r\n" | 
|  173       "WWW-Authenticate: Mock\r\n" |  173                         "WWW-Authenticate: Ernie\r\n" | 
|  174       "WWW-Authenticate: Basic\r\n" |  174                         "WWW-Authenticate: Bert\r\n" | 
|  175       "\r\n")); |  175                         "\r\n")); | 
|  176  |  176  | 
|  177   HttpAuthHandlerMock::Factory auth_handler_factory; |  177   HttpAuthHandlerMock::Factory auth_handler_factory; | 
 |  178   auth_handler_factory.set_do_init_from_challenge(true); | 
|  178  |  179  | 
|  179   // Handlers for the first attempt at authentication.  AUTH_SCHEME_MOCK handler |  180   // Handler for the first attempt at authentication. "Ernie" handler accepts | 
|  180   // accepts the default identity and successfully constructs a token. |  181   // the default identity and successfully constructs a token. | 
|  181   auth_handler_factory.AddMockHandler( |  182   auth_handler_factory.AddMockHandler(new MockHandler(OK, "ernie"), | 
|  182       new MockHandler(OK, HttpAuth::AUTH_SCHEME_MOCK), HttpAuth::AUTH_SERVER); |  183                                       HttpAuth::AUTH_SERVER); | 
|  183   auth_handler_factory.AddMockHandler( |  | 
|  184       new MockHandler(ERR_UNEXPECTED, HttpAuth::AUTH_SCHEME_BASIC), |  | 
|  185       HttpAuth::AUTH_SERVER); |  | 
|  186  |  | 
|  187   // Handlers for the second attempt.  Neither should be used to generate a |  | 
|  188   // token.  Instead the controller should realize that there are no viable |  | 
|  189   // identities to use with the AUTH_SCHEME_MOCK handler and fail. |  | 
|  190   auth_handler_factory.AddMockHandler( |  | 
|  191       new MockHandler(ERR_UNEXPECTED, HttpAuth::AUTH_SCHEME_MOCK), |  | 
|  192       HttpAuth::AUTH_SERVER); |  | 
|  193   auth_handler_factory.AddMockHandler( |  | 
|  194       new MockHandler(ERR_UNEXPECTED, HttpAuth::AUTH_SCHEME_BASIC), |  | 
|  195       HttpAuth::AUTH_SERVER); |  | 
|  196  |  | 
|  197   // Fallback handlers for the second attempt.  The AUTH_SCHEME_MOCK handler |  | 
|  198   // should be discarded due to the disabled scheme, and the AUTH_SCHEME_BASIC |  | 
|  199   // handler should successfully be used to generate a token. |  | 
|  200   auth_handler_factory.AddMockHandler( |  | 
|  201       new MockHandler(ERR_UNEXPECTED, HttpAuth::AUTH_SCHEME_MOCK), |  | 
|  202       HttpAuth::AUTH_SERVER); |  | 
|  203   auth_handler_factory.AddMockHandler( |  | 
|  204       new MockHandler(OK, HttpAuth::AUTH_SCHEME_BASIC), |  | 
|  205       HttpAuth::AUTH_SERVER); |  | 
|  206   auth_handler_factory.set_do_init_from_challenge(true); |  | 
|  207  |  184  | 
|  208   scoped_refptr<HttpAuthController> controller( |  185   scoped_refptr<HttpAuthController> controller( | 
|  209       new HttpAuthController(HttpAuth::AUTH_SERVER, |  186       new HttpAuthController(HttpAuth::AUTH_SERVER, | 
|  210                              GURL("http://example.com"), |  187                              GURL("http://example.com"), | 
|  211                              &dummy_auth_cache, &auth_handler_factory)); |  188                              &dummy_auth_cache, &auth_handler_factory)); | 
|  212   ASSERT_EQ(OK, |  189   ASSERT_EQ(OK, | 
|  213             controller->HandleAuthChallenge(headers, false, false, dummy_log)); |  190             controller->HandleAuthChallenge(headers, false, false, dummy_log)); | 
|  214   ASSERT_TRUE(controller->HaveAuthHandler()); |  191   ASSERT_TRUE(controller->HaveAuthHandler()); | 
|  215   controller->ResetAuth(AuthCredentials()); |  192   controller->ResetAuth(AuthCredentials()); | 
|  216   EXPECT_TRUE(controller->HaveAuth()); |  193   EXPECT_TRUE(controller->HaveAuth()); | 
 |  194   EXPECT_FALSE(auth_handler_factory.HaveAuthHandlers(HttpAuth::AUTH_SERVER)); | 
|  217  |  195  | 
|  218   // Should only succeed if we are using the AUTH_SCHEME_MOCK MockHandler. |  196   // Should only succeed if we are using the "Ernie" MockHandler. | 
|  219   EXPECT_EQ(OK, controller->MaybeGenerateAuthToken( |  197   EXPECT_EQ(OK, controller->MaybeGenerateAuthToken( | 
|  220       &request, CompletionCallback(), dummy_log)); |  198       &request, CompletionCallback(), dummy_log)); | 
|  221   controller->AddAuthorizationHeader(&request_headers); |  199   controller->AddAuthorizationHeader(&request_headers); | 
|  222  |  200  | 
 |  201   // Handlers for the second attempt. Neither should be used to generate a | 
 |  202   // token. Instead the controller should realize that there are no viable | 
 |  203   // identities to use with the "Ernie" handler and fail. | 
 |  204   auth_handler_factory.AddMockHandler(new MockHandler(ERR_UNEXPECTED, "ernie"), | 
 |  205                                       HttpAuth::AUTH_SERVER); | 
 |  206  | 
 |  207   // Fallback handlers for the second attempt. The "Ernie" handler should be | 
 |  208   // discarded due to the disabled scheme, and the "Bert" handler should | 
 |  209   // successfully be used to generate a token. | 
 |  210   auth_handler_factory.AddMockHandler(new MockHandler(OK, "bert"), | 
 |  211                                       HttpAuth::AUTH_SERVER); | 
 |  212  | 
|  223   // Once a token is generated, simulate the receipt of a server response |  213   // Once a token is generated, simulate the receipt of a server response | 
|  224   // indicating that the authentication attempt was rejected. |  214   // indicating that the authentication attempt was rejected. | 
|  225   ASSERT_EQ(OK, |  215   ASSERT_EQ(OK, | 
|  226             controller->HandleAuthChallenge(headers, false, false, dummy_log)); |  216             controller->HandleAuthChallenge(headers, false, false, dummy_log)); | 
|  227   ASSERT_TRUE(controller->HaveAuthHandler()); |  217   ASSERT_TRUE(controller->HaveAuthHandler()); | 
|  228   controller->ResetAuth(AuthCredentials(base::ASCIIToUTF16("Hello"), |  218   controller->ResetAuth(AuthCredentials(base::ASCIIToUTF16("Hello"), | 
|  229                         base::string16())); |  219                         base::string16())); | 
|  230   EXPECT_TRUE(controller->HaveAuth()); |  220   EXPECT_TRUE(controller->HaveAuth()); | 
|  231   EXPECT_TRUE(controller->IsAuthSchemeDisabled(HttpAuth::AUTH_SCHEME_MOCK)); |  221   EXPECT_TRUE(controller->IsAuthSchemeDisabled("ernie")); | 
|  232   EXPECT_FALSE(controller->IsAuthSchemeDisabled(HttpAuth::AUTH_SCHEME_BASIC)); |  222   EXPECT_FALSE(controller->IsAuthSchemeDisabled("bert")); | 
|  233  |  223  | 
|  234   // Should only succeed if we are using the AUTH_SCHEME_BASIC MockHandler. |  224   // Should only succeed if we are using the "Bert" MockHandler. | 
|  235   EXPECT_EQ(OK, controller->MaybeGenerateAuthToken( |  225   EXPECT_EQ(OK, controller->MaybeGenerateAuthToken( | 
|  236       &request, CompletionCallback(), dummy_log)); |  226       &request, CompletionCallback(), dummy_log)); | 
|  237 } |  227 } | 
|  238  |  228  | 
|  239 }  // namespace net |  229 }  // namespace net | 
| OLD | NEW |