#ifndef GOOGLE_APIS_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_
#define GOOGLE_APIS_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_
#include <set>
#include <string>
#include <string_view>
#include <vector>
#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/values.h"
#include "google_apis/gaia/gaia_id.h"
#include "google_apis/gaia/oauth2_api_call_flow.h"
#include "net/cookies/canonical_cookie.h"
#include "services/network/public/mojom/url_response_head.mojom-forward.h"
#include "url/gurl.h"
class GoogleServiceAuthError;
class OAuth2MintTokenFlowTest;
enum class OAuth2MintTokenApiCallResult {
kMintTokenSuccess = 0,
kRemoteConsentSuccess = 2,
kApiCallFailure = 3,
kParseJsonFailure = 4,
kIssueAdviceKeyNotFoundFailure = 5,
kParseMintTokenFailure = 6,
kParseRemoteConsentFailure = 9,
kChallengeResponseRequiredFailure = 11,
kMaxValue = kChallengeResponseRequiredFailure
};
struct COMPONENT_EXPORT(GOOGLE_APIS) RemoteConsentResolutionData {
RemoteConsentResolutionData();
~RemoteConsentResolutionData();
RemoteConsentResolutionData(const RemoteConsentResolutionData& other);
RemoteConsentResolutionData& operator=(
const RemoteConsentResolutionData& other);
GURL url;
net::CookieList cookies;
friend bool operator==(const RemoteConsentResolutionData&,
const RemoteConsentResolutionData&) = default;
};
class COMPONENT_EXPORT(GOOGLE_APIS) OAuth2MintTokenFlow
: public OAuth2ApiCallFlow {
public:
enum Mode {
MODE_ISSUE_ADVICE,
MODE_RECORD_GRANT,
MODE_MINT_TOKEN_NO_FORCE,
MODE_MINT_TOKEN_FORCE,
};
struct COMPONENT_EXPORT(GOOGLE_APIS) Parameters {
public:
Parameters();
static Parameters CreateForExtensionFlow(
std::string_view extension_id,
std::string_view client_id,
base::span<const std::string_view> scopes,
Mode mode,
bool enable_granular_permissions,
std::string_view version,
std::string_view channel,
std::string_view device_id = {},
const GaiaId& selected_user_id = GaiaId(),
std::string_view consent_result = {});
static Parameters CreateForClientFlow(
std::string_view client_id,
base::span<const std::string_view> scopes,
std::string_view version,
std::string_view channel,
std::string_view device_id = {},
std::string_view bound_oauth_token = {});
Parameters(Parameters&& other) noexcept;
Parameters& operator=(Parameters&& other) noexcept;
~Parameters();
Parameters Clone();
std::string client_id;
std::vector<std::string> scopes;
Mode mode = MODE_ISSUE_ADVICE;
bool enable_granular_permissions = false;
std::string version;
std::string channel;
std::string extension_id;
std::string device_id;
GaiaId selected_user_id;
std::string consent_result;
std::string bound_oauth_token;
private:
Parameters(const Parameters&);
Parameters& operator=(const Parameters&);
};
struct COMPONENT_EXPORT(GOOGLE_APIS) MintTokenResult {
MintTokenResult();
~MintTokenResult();
MintTokenResult(const MintTokenResult&) = delete;
MintTokenResult& operator=(const MintTokenResult&) = delete;
MintTokenResult(MintTokenResult&& other) noexcept;
MintTokenResult& operator=(MintTokenResult&& other) noexcept;
std::string access_token;
std::set<std::string> granted_scopes;
base::TimeDelta time_to_live;
bool is_token_encrypted = false;
};
class COMPONENT_EXPORT(GOOGLE_APIS) Delegate {
public:
virtual void OnMintTokenSuccess(const MintTokenResult& result) {}
virtual void OnMintTokenFailure(const GoogleServiceAuthError& error) {}
virtual void OnRemoteConsentSuccess(
const RemoteConsentResolutionData& resolution_data) {}
protected:
virtual ~Delegate() = default;
};
OAuth2MintTokenFlow(Delegate* delegate, Parameters parameters);
OAuth2MintTokenFlow(const OAuth2MintTokenFlow&) = delete;
OAuth2MintTokenFlow& operator=(const OAuth2MintTokenFlow&) = delete;
~OAuth2MintTokenFlow() override;
protected:
GURL CreateApiCallUrl() override;
net::HttpRequestHeaders CreateApiCallHeaders() override;
std::string CreateApiCallBody() override;
std::string CreateAuthorizationHeaderValue(
const std::string& access_token) override;
void ProcessApiCallSuccess(const network::mojom::URLResponseHead* head,
std::optional<std::string> body) override;
void ProcessApiCallFailure(int net_error,
const network::mojom::URLResponseHead* head,
std::optional<std::string> body) override;
net::PartialNetworkTrafficAnnotationTag GetNetworkTrafficAnnotationTag()
override;
private:
friend class OAuth2MintTokenFlowTest;
void ReportSuccess(const MintTokenResult& result);
void ReportRemoteConsentSuccess(
const RemoteConsentResolutionData& resolution_data);
void ReportFailure(const GoogleServiceAuthError& error);
static bool ParseRemoteConsentResponse(
const base::Value::Dict& dict,
RemoteConsentResolutionData* resolution_data);
static std::optional<MintTokenResult> ParseMintTokenResponse(
const base::Value::Dict& dict);
raw_ptr<Delegate> delegate_;
Parameters parameters_;
base::WeakPtrFactory<OAuth2MintTokenFlow> weak_factory_{this};
};
#endif