// Copyright (c) 2012 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.

#ifndef NET_HTTP_HTTP_AUTH_CONTROLLER_H_
#define NET_HTTP_HTTP_AUTH_CONTROLLER_H_

#include <memory>
#include <set>
#include <string>

#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "base/threading/thread_checker.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_export.h"
#include "net/http/http_auth.h"
#include "url/gurl.h"

namespace net {

class AuthChallengeInfo;
class AuthCredentials;
class HttpAuthHandler;
class HttpAuthHandlerFactory;
class HttpAuthCache;
class HttpRequestHeaders;
class HostResolver;
class NetLogWithSource;
struct HttpRequestInfo;
class SSLInfo;

// HttpAuthController is interface between other classes and HttpAuthHandlers.
// It handles all challenges when attempting to make a single request to a
// server, both in the case of trying multiple sets of credentials (Possibly on
// different sockets), and when going through multiple rounds of auth with
// connection-based auth, creating new HttpAuthHandlers as necessary.
//
// It is unaware of when a round of auth uses a new socket, which can lead to
// problems for connection-based auth.
class NET_EXPORT_PRIVATE HttpAuthController
    : public base::RefCounted<HttpAuthController> {
 public:
  // The arguments are self explanatory except possibly for |auth_url|, which
  // should be both the auth target and auth path in a single url argument.
  // |target| indicates whether this is for authenticating with a proxy or
  // destination server.
  HttpAuthController(HttpAuth::Target target,
                     const GURL& auth_url,
                     HttpAuthCache* http_auth_cache,
                     HttpAuthHandlerFactory* http_auth_handler_factory,
                     HostResolver* host_resolver);

  // Generate an authentication token for |target| if necessary. The return
  // value is a net error code. |OK| will be returned both in the case that
  // a token is correctly generated synchronously, as well as when no tokens
  // were necessary.
  int MaybeGenerateAuthToken(const HttpRequestInfo* request,
                             CompletionOnceCallback callback,
                             const NetLogWithSource& net_log);

  // Adds either the proxy auth header, or the origin server auth header,
  // as specified by |target_|.
  void AddAuthorizationHeader(HttpRequestHeaders* authorization_headers);

  // Checks for and handles HTTP status code 401 or 407.
  // |HandleAuthChallenge()| returns OK on success, or a network error code
  // otherwise. It may also populate |auth_info_|.
  int HandleAuthChallenge(scoped_refptr<HttpResponseHeaders> headers,
                          const SSLInfo& ssl_info,
                          bool do_not_send_server_auth,
                          bool establishing_tunnel,
                          const NetLogWithSource& net_log);

  // Store the supplied credentials and prepare to restart the auth.
  void ResetAuth(const AuthCredentials& credentials);

  bool HaveAuthHandler() const;

  bool HaveAuth() const;

  // Return whether the authentication scheme is incompatible with HTTP/2
  // and thus the server would presumably reject a request on HTTP/2 anyway.
  bool NeedsHTTP11() const;

  // Swaps the authentication challenge info into |other|.
  void TakeAuthInfo(base::Optional<AuthChallengeInfo>* other);

  bool IsAuthSchemeDisabled(HttpAuth::Scheme scheme) const;
  void DisableAuthScheme(HttpAuth::Scheme scheme);
  void DisableEmbeddedIdentity();

  // Called when the connection has been closed, so the current handler (which
  // contains state bound to the connection) should be dropped. If retrying on a
  // new connection, the next call to MaybeGenerateAuthToken will retry the
  // current auth scheme.
  void OnConnectionClosed();

 private:
  // Actions for InvalidateCurrentHandler()
  enum InvalidateHandlerAction {
    INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS,
    INVALIDATE_HANDLER_AND_DISABLE_SCHEME,
    INVALIDATE_HANDLER
  };

  // So that we can mock this object.
  friend class base::RefCounted<HttpAuthController>;

  ~HttpAuthController();

  // Searches the auth cache for an entry that encompasses the request's path.
  // If such an entry is found, updates |identity_| and |handler_| with the
  // cache entry's data and returns true.
  bool SelectPreemptiveAuth(const NetLogWithSource& net_log);

  // Invalidates the current handler.  If |action| is
  // INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, then also invalidate
  // the cached credentials used by the handler.
  void InvalidateCurrentHandler(InvalidateHandlerAction action);

  // Invalidates any auth cache entries after authentication has failed.
  // The identity that was rejected is |identity_|.
  void InvalidateRejectedAuthFromCache();

  // Allows reusing last used identity source.  If the authentication handshake
  // breaks down halfway, then the controller needs to restart it from the
  // beginning and resue the same identity.
  void PrepareIdentityForReuse();

  // Sets |identity_| to the next identity that the transaction should try. It
  // chooses candidates by searching the auth cache and the URL for a
  // username:password. Returns true if an identity was found.
  bool SelectNextAuthIdentityToTry();

  // Populates auth_info_ with the challenge information, so that
  // URLRequestHttpJob can prompt for credentials.
  void PopulateAuthChallenge();

  // Handle the result of calling GenerateAuthToken on an HttpAuthHandler. The
  // return value of this function should be used as the return value of the
  // GenerateAuthToken operation.
  int HandleGenerateTokenResult(int result);

  void OnGenerateAuthTokenDone(int result);

  // Indicates if this handler is for Proxy auth or Server auth.
  HttpAuth::Target target_;

  // Holds the {scheme, host, path, port} for the authentication target.
  const GURL auth_url_;

  // Holds the {scheme, host, port} for the authentication target.
  const GURL auth_origin_;

  // The absolute path of the resource needing authentication.
  // For proxy authentication the path is empty.
  const std::string auth_path_;

  // |handler_| encapsulates the logic for the particular auth-scheme.
  // This includes the challenge's parameters. If NULL, then there is no
  // associated auth handler.
  std::unique_ptr<HttpAuthHandler> handler_;

  // |identity_| holds the credentials that should be used by
  // the handler_ to generate challenge responses. This identity can come from
  // a number of places (url, cache, prompt).
  HttpAuth::Identity identity_;

  // |auth_token_| contains the opaque string to pass to the proxy or
  // server to authenticate the client.
  std::string auth_token_;

  // Contains information about the auth challenge.
  base::Optional<AuthChallengeInfo> auth_info_;

  // True if we've used the username:password embedded in the URL.  This
  // makes sure we use the embedded identity only once for the transaction,
  // preventing an infinite auth restart loop.
  bool embedded_identity_used_;

  // True if default credentials have already been tried for this transaction
  // in response to an HTTP authentication challenge.
  bool default_credentials_used_;

  // These two are owned by the HttpNetworkSession/IOThread, which own the
  // objects which reference |this|.  Therefore, these raw pointers are valid
  // for the lifetime of this object.
  HttpAuthCache* const http_auth_cache_;
  HttpAuthHandlerFactory* const http_auth_handler_factory_;
  HostResolver* const host_resolver_;

  std::set<HttpAuth::Scheme> disabled_schemes_;

  CompletionOnceCallback callback_;

  THREAD_CHECKER(thread_checker_);
};

}  // namespace net

#endif  // NET_HTTP_HTTP_AUTH_CONTROLLER_H_
