#ifndef GOOGLE_APIS_GAIA_OAUTH2_ACCESS_TOKEN_FETCHER_IMPL_H_
#define GOOGLE_APIS_GAIA_OAUTH2_ACCESS_TOKEN_FETCHER_IMPL_H_
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/component_export.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_refptr.h"
#include "google_apis/gaia/oauth2_access_token_consumer.h"
#include "google_apis/gaia/oauth2_access_token_fetcher.h"
#include "google_apis/gaia/oauth2_response.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
class OAuth2AccessTokenFetcherImplTest;
namespace network {
class SimpleURLLoader;
class SharedURLLoaderFactory;
}
class COMPONENT_EXPORT(GOOGLE_APIS) OAuth2AccessTokenFetcherImpl
: public OAuth2AccessTokenFetcher {
public:
OAuth2AccessTokenFetcherImpl(
OAuth2AccessTokenConsumer* consumer,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
const std::string& refresh_token,
const std::string& auth_code = std::string());
OAuth2AccessTokenFetcherImpl(const OAuth2AccessTokenFetcherImpl&) = delete;
OAuth2AccessTokenFetcherImpl& operator=(const OAuth2AccessTokenFetcherImpl&) =
delete;
~OAuth2AccessTokenFetcherImpl() override;
void Start(const std::string& client_id,
const std::string& client_secret,
const std::vector<std::string>& scopes) override;
void CancelRequest() override;
private:
enum State {
INITIAL,
GET_ACCESS_TOKEN_STARTED,
GET_ACCESS_TOKEN_DONE,
GET_ACCESS_TOKEN_CANCELED,
ERROR_STATE,
};
virtual void RecordResponseCodeUma(int error_value) const {}
virtual void RecordOAuth2Response(OAuth2Response response) const {}
virtual GURL GetAccessTokenURL() const = 0;
virtual net::NetworkTrafficAnnotationTag GetTrafficAnnotationTag() const = 0;
void OnURLLoadComplete(std::optional<std::string> response_body);
void StartGetAccessToken();
void EndGetAccessToken(std::optional<std::string> response_body);
void OnGetTokenSuccess(
const OAuth2AccessTokenConsumer::TokenResponse& token_response);
void OnGetTokenFailure(const GoogleServiceAuthError& error);
static std::string MakeGetAccessTokenBody(
const std::string& client_id,
const std::string& client_secret,
const std::string& refresh_token,
const std::string& auth_code,
const std::vector<std::string>& scopes);
static bool ParseGetAccessTokenSuccessResponse(
const std::string& response_body,
OAuth2AccessTokenConsumer::TokenResponse* token_response);
static bool ParseGetAccessTokenFailureResponse(
const std::string& response_body,
std::string* error,
std::string* error_subtype,
std::string* error_description);
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
const std::string refresh_token_;
const std::string auth_code_;
State state_;
std::unique_ptr<network::SimpleURLLoader> url_loader_;
std::string client_id_;
std::string client_secret_;
std::vector<std::string> scopes_;
friend class OAuth2AccessTokenFetcherImplTest;
FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherImplTest,
ParseGetAccessTokenResponseNoBody);
FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherImplTest,
MakeGetAccessTokenBodyNoScope);
FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherImplTest,
MakeGetAccessTokenBodyOneScope);
FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherImplTest,
MakeGetAccessTokenBodyMultipleScopes);
FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherImplTest,
ParseGetAccessTokenResponseBadJson);
FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherImplTest,
ParseGetAccessTokenResponseNoAccessToken);
FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherImplTest,
ParseGetAccessTokenResponseSuccess);
FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherImplTest,
ParseGetAccessTokenFailure);
FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherImplTest,
ParseGetAccessTokenFailureInvalidError);
FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherImplTest,
ParseGetAccessTokenFailureForMissingRaptError);
FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherImplTest,
ParseGetAccessTokenFailureForInvalidRaptError);
};
#endif