aboutsummaryrefslogtreecommitdiff
path: root/zenserver/upstream/jupiter.cpp
diff options
context:
space:
mode:
authorPer Larsson <[email protected]>2022-02-01 10:47:12 +0100
committerPer Larsson <[email protected]>2022-02-01 10:47:12 +0100
commitee00d9db3e0b65667d9b2a792cf0567aff2844fb (patch)
treecda98c52a90ecb1edbafa5651ca31e016037fc05 /zenserver/upstream/jupiter.cpp
parentMerged main. (diff)
downloadzen-ee00d9db3e0b65667d9b2a792cf0567aff2844fb.tar.xz
zen-ee00d9db3e0b65667d9b2a792cf0567aff2844fb.zip
Parital completed cloud cache token provider interface.
Diffstat (limited to 'zenserver/upstream/jupiter.cpp')
-rw-r--r--zenserver/upstream/jupiter.cpp360
1 files changed, 122 insertions, 238 deletions
diff --git a/zenserver/upstream/jupiter.cpp b/zenserver/upstream/jupiter.cpp
index c952d8e10..86c7e1611 100644
--- a/zenserver/upstream/jupiter.cpp
+++ b/zenserver/upstream/jupiter.cpp
@@ -31,37 +31,26 @@ namespace zen {
namespace detail {
struct CloudCacheSessionState
{
- CloudCacheSessionState(CloudCacheClient& Client) : OwnerClient(Client) {}
- ~CloudCacheSessionState() {}
+ CloudCacheSessionState(CloudCacheClient& Client) : m_Client(Client) {}
- const CloudCacheAccessToken& GetAccessToken()
- {
- if (!AccessToken.IsValid())
- {
- AccessToken = OwnerClient.AcquireAccessToken();
- }
- return AccessToken;
- }
+ const CloudCacheAccessToken& GetAccessToken() { return m_AccessToken; }
- void InvalidateAccessToken() { AccessToken = {}; }
+ cpr::Session& GetSession() { return m_Session; }
void Reset(std::chrono::milliseconds ConnectTimeout, std::chrono::milliseconds Timeout)
{
- Session.SetBody({});
- Session.SetHeader({});
- Session.SetConnectTimeout(ConnectTimeout);
- Session.SetTimeout(Timeout);
- AccessToken = GetAccessToken();
+ m_Session.SetBody({});
+ m_Session.SetHeader({});
+ m_Session.SetConnectTimeout(ConnectTimeout);
+ m_Session.SetTimeout(Timeout);
}
- cpr::Session& GetSession() { return Session; }
-
private:
friend class zen::CloudCacheClient;
- CloudCacheClient& OwnerClient;
- CloudCacheAccessToken AccessToken;
- cpr::Session Session;
+ CloudCacheClient& m_Client;
+ CloudCacheAccessToken m_AccessToken;
+ cpr::Session m_Session;
};
} // namespace detail
@@ -88,16 +77,11 @@ CloudCacheSession::GetDerivedData(std::string_view BucketId, std::string_view Ke
{
ZEN_TRACE_CPU("HordeClient::GetDerivedData");
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/c/ddc/" << m_CacheClient->DdcNamespace() << "/" << BucketId << "/" << Key;
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Accept", "application/octet-stream"}});
@@ -129,19 +113,14 @@ CloudCacheSession::GetDerivedData(std::string_view BucketId, const IoHash& Key)
CloudCacheResult
CloudCacheSession::GetRef(std::string_view BucketId, const IoHash& Key, ZenContentType RefType)
{
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
const std::string ContentType = RefType == ZenContentType::kCbObject ? "application/x-ue-cb" : "application/octet-stream";
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/refs/" << m_CacheClient->BlobStoreNamespace() << "/" << BucketId << "/"
<< Key.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Accept", ContentType}});
@@ -168,16 +147,11 @@ CloudCacheSession::GetRef(std::string_view BucketId, const IoHash& Key, ZenConte
CloudCacheResult
CloudCacheSession::GetBlob(const IoHash& Key)
{
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/blobs/" << m_CacheClient->BlobStoreNamespace() << "/" << Key.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Accept", "application/octet-stream"}});
@@ -207,16 +181,11 @@ CloudCacheSession::GetCompressedBlob(const IoHash& Key)
{
ZEN_TRACE_CPU("HordeClient::GetCompressedBlob");
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/compressed-blobs/" << m_CacheClient->BlobStoreNamespace() << "/" << Key.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Accept", "application/x-ue-comp"}});
@@ -245,16 +214,11 @@ CloudCacheSession::GetObject(const IoHash& Key)
{
ZEN_TRACE_CPU("HordeClient::GetObject");
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/objects/" << m_CacheClient->BlobStoreNamespace() << "/" << Key.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Accept", "application/x-ue-cb"}});
@@ -283,18 +247,13 @@ CloudCacheSession::PutDerivedData(std::string_view BucketId, std::string_view Ke
{
ZEN_TRACE_CPU("HordeClient::PutDerivedData");
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
IoHash Hash = IoHash::HashBuffer(DerivedData.Data(), DerivedData.Size());
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/c/ddc/" << m_CacheClient->DdcNamespace() << "/" << BucketId << "/" << Key;
- auto& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value},
@@ -330,15 +289,6 @@ CloudCacheSession::PutRef(std::string_view BucketId, const IoHash& Key, IoBuffer
{
ZEN_TRACE_CPU("HordeClient::PutRef");
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- PutRefResult Result;
- Result.ErrorCode = 401;
- Result.Reason = "Invalid access token"sv;
- return Result;
- }
-
IoHash Hash = IoHash::HashBuffer(Ref.Data(), Ref.Size());
const std::string ContentType = RefType == ZenContentType::kCbObject ? "application/x-ue-cb" : "application/octet-stream";
@@ -347,7 +297,8 @@ CloudCacheSession::PutRef(std::string_view BucketId, const IoHash& Key, IoBuffer
Uri << m_CacheClient->ServiceUrl() << "/api/v1/refs/" << m_CacheClient->BlobStoreNamespace() << "/" << BucketId << "/"
<< Key.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(
@@ -399,20 +350,12 @@ CloudCacheSession::FinalizeRef(std::string_view BucketId, const IoHash& Key, con
{
ZEN_TRACE_CPU("HordeClient::FinalizeRef");
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- FinalizeRefResult Result;
- Result.ErrorCode = 401;
- Result.Reason = "Invalid access token"sv;
- return Result;
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/refs/" << m_CacheClient->BlobStoreNamespace() << "/" << BucketId << "/"
<< Key.ToHexString() << "/finalize/" << RefHash.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value},
@@ -465,16 +408,11 @@ CloudCacheSession::PutBlob(const IoHash& Key, IoBuffer Blob)
{
ZEN_TRACE_CPU("HordeClient::PutBlob");
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/blobs/" << m_CacheClient->BlobStoreNamespace() << "/" << Key.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Content-Type", "application/octet-stream"}});
@@ -502,16 +440,11 @@ CloudCacheSession::PutCompressedBlob(const IoHash& Key, IoBuffer Blob)
{
ZEN_TRACE_CPU("HordeClient::PutCompressedBlob");
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/compressed-blobs/" << m_CacheClient->BlobStoreNamespace() << "/" << Key.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Content-Type", "application/x-ue-comp"}});
@@ -539,16 +472,11 @@ CloudCacheSession::PutObject(const IoHash& Key, IoBuffer Object)
{
ZEN_TRACE_CPU("HordeClient::PutObject");
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/objects/" << m_CacheClient->BlobStoreNamespace() << "/" << Key.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Content-Type", "application/x-ue-cb"}});
@@ -576,17 +504,12 @@ CloudCacheSession::RefExists(std::string_view BucketId, const IoHash& Key)
{
ZEN_TRACE_CPU("HordeClient::RefExists");
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/refs/" << m_CacheClient->BlobStoreNamespace() << "/" << BucketId << "/"
<< Key.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}});
@@ -648,16 +571,11 @@ CloudCacheSession::PostComputeTasks(std::string_view ChannelId, IoBuffer TasksDa
{
ZEN_TRACE_CPU("HordeClient::PostComputeTasks");
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/compute/" << ChannelId;
- auto& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Content-Type", "application/x-ue-cb"}});
@@ -681,16 +599,11 @@ CloudCacheSession::PostComputeTasks(std::string_view ChannelId, IoBuffer TasksDa
CloudCacheResult
CloudCacheSession::GetComputeUpdates(std::string_view ChannelId, const uint32_t WaitSeconds)
{
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/compute/" << ChannelId << "/updates?wait=" << WaitSeconds;
- auto& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Accept", "application/x-ue-cb"}});
@@ -719,16 +632,11 @@ CloudCacheSession::GetObjectTree(const IoHash& Key)
{
ZEN_TRACE_CPU("HordeClient::GetObjectTree");
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/objects/" << m_CacheClient->BlobStoreNamespace() << "/" << Key.ToHexString() << "/tree";
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Accept", "application/octet-stream"}});
@@ -764,7 +672,13 @@ CloudCacheSession::Filter(std::string_view BucketId, const std::vector<IoHash>&
return {};
}
-const CloudCacheAccessToken&
+cpr::Session&
+CloudCacheSession::GetSession()
+{
+ return m_SessionState->GetSession();
+}
+
+CloudCacheAccessToken
CloudCacheSession::GetAccessToken()
{
return m_SessionState->GetAccessToken();
@@ -773,27 +687,17 @@ CloudCacheSession::GetAccessToken()
bool
CloudCacheSession::VerifyAccessToken(long StatusCode)
{
- if (StatusCode == 401)
- {
- m_SessionState->InvalidateAccessToken();
- return false;
- }
- return true;
+ return StatusCode != 401;
}
CloudCacheResult
CloudCacheSession::CacheTypeExists(std::string_view TypeId, const IoHash& Key)
{
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
- }
-
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/" << TypeId << "/" << m_CacheClient->BlobStoreNamespace() << "/" << Key.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}});
@@ -817,12 +721,6 @@ CloudCacheSession::CacheTypeExists(std::string_view TypeId, const IoHash& Key)
CloudCacheExistsResult
CloudCacheSession::CacheTypeExists(std::string_view TypeId, const std::set<IoHash>& Keys)
{
- const CloudCacheAccessToken& AccessToken = GetAccessToken();
- if (!AccessToken.IsValid())
- {
- return {CloudCacheResult{.ErrorCode = 401, .Reason = std::string("Invalid access token")}};
- }
-
ExtendableStringBuilder<256> Query;
for (const auto& Key : Keys)
{
@@ -832,7 +730,8 @@ CloudCacheSession::CacheTypeExists(std::string_view TypeId, const std::set<IoHas
ExtendableStringBuilder<256> Uri;
Uri << m_CacheClient->ServiceUrl() << "/api/v1/" << TypeId << "/" << m_CacheClient->BlobStoreNamespace() << "/exists?" << Query;
- cpr::Session& Session = m_SessionState->GetSession();
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
Session.SetOption(cpr::Url{Uri.c_str()});
Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Accept", "application/x-ue-cb"}});
@@ -869,65 +768,90 @@ CloudCacheSession::CacheTypeExists(std::string_view TypeId, const std::set<IoHas
return Result;
}
-//////////////////////////////////////////////////////////////////////////
-//
-// ServiceUrl: https://jupiter.devtools.epicgames.com
-// DdcNamespace: ue4.ddc
-// OAuthClientId: 0oao91lrhqPiAlaGD0x7
-// OAuthProvider: https://epicgames.okta.com/oauth2/auso645ojjWVdRI3d0x7/v1/token
-// OAuthSecret: -GBWjjenhCgOwhxL5yBKNJECVIoDPH0MK4RDuN7d
-//
+/**
+ * An access token provider that holds a token that will never change.
+ */
+class StaticTokenProvider final : public CloudCacheTokenProvider
+{
+public:
+ StaticTokenProvider(CloudCacheAccessToken Token) : m_Token(std::move(Token)) {}
-CloudCacheClient::CloudCacheClient(const CloudCacheClientOptions& Options)
-: m_Log(zen::logging::Get("jupiter"))
-, m_ServiceUrl(Options.ServiceUrl)
-, m_OAuthFullUri(Options.OAuthProvider)
-, m_DdcNamespace(Options.DdcNamespace)
-, m_BlobStoreNamespace(Options.BlobStoreNamespace)
-, m_OAuthClientId(Options.OAuthClientId)
-, m_OAuthSecret(Options.OAuthSecret)
-, m_AccessToken(Options.AccessToken)
-, m_ConnectTimeout(Options.ConnectTimeout)
-, m_Timeout(Options.Timeout)
+ virtual ~StaticTokenProvider() = default;
+
+ virtual CloudCacheAccessToken GetAccessToken() final override { return m_Token; }
+
+private:
+ CloudCacheAccessToken m_Token;
+};
+
+std::unique_ptr<CloudCacheTokenProvider>
+CloudCacheTokenProvider::MakeFromStaticToken(CloudCacheAccessToken Token)
{
- if (!Options.AccessToken.empty())
+ return std::make_unique<StaticTokenProvider>(std::move(Token));
+}
+
+class OAuthClientCredentialsTokenProvider final : public CloudCacheTokenProvider
+{
+public:
+ OAuthClientCredentialsTokenProvider(const CloudCacheTokenProvider::OAuthClientCredentialsParams& Params)
{
- // If an access token was provided, OAuth settings are not used.
- return;
+ m_Url = std::string(Params.Url);
+ m_ClientId = std::string(Params.ClientId);
+ m_ClientSecret = std::string(Params.ClientSecret);
}
- if (!Options.OAuthProvider.starts_with("http://"sv) && !Options.OAuthProvider.starts_with("https://"sv))
- {
- ZEN_WARN("bad provider specification: '{}' - must be fully qualified", Options.OAuthProvider);
- m_IsValid = false;
+ virtual ~OAuthClientCredentialsTokenProvider() = default;
- return;
- }
+ virtual CloudCacheAccessToken GetAccessToken() final override
+ {
+ using namespace std::chrono;
- // Split into host and Uri substrings
+ std::string Body =
+ fmt::format("client_id={}&scope=cache_access&grant_type=client_credentials&client_secret={k}", m_ClientId, m_ClientSecret);
- auto SchemePos = Options.OAuthProvider.find("://"sv);
+ cpr::Response Response =
+ cpr::Post(cpr::Url{m_Url}, cpr::Header{{"Content-Type", "application/x-www-form-urlencoded"}}, cpr::Body{std::move(Body)});
- if (SchemePos == std::string::npos)
- {
- ZEN_WARN("Bad service URL passed to cloud cache client: '{}'", Options.ServiceUrl);
- m_IsValid = false;
+ if (Response.error || Response.status_code != 200)
+ {
+ return {};
+ }
- return;
- }
+ std::string JsonError;
+ json11::Json Json = json11::Json::parse(Response.text, JsonError);
- auto DomainEnd = Options.OAuthProvider.find('/', /* also skip the :// */ SchemePos + 3);
+ if (JsonError.empty() == false)
+ {
+ return {};
+ }
- if (DomainEnd == std::string::npos)
- {
- ZEN_WARN("Bad service URL passed to cloud cache client: '{}' no path delimiter found", Options.ServiceUrl);
- m_IsValid = false;
+ std::string Token = Json["access_token"].string_value();
+ int64_t ExpiresInSeconds = static_cast<int64_t>(Json["expires_in"].int_value());
+ CloudCacheAccessToken::TimePoint ExpireTime = CloudCacheAccessToken::Clock::now() + seconds(ExpiresInSeconds);
- return;
+ return {.Value = fmt::format("Bearer {}", Token), .ExpireTime = ExpireTime};
}
- m_OAuthDomain = Options.OAuthProvider.substr(SchemePos + 3, DomainEnd - SchemePos - 3); // epicgames.okta.com
- m_OAuthUriPath = Options.OAuthProvider.substr(DomainEnd + 1); // oauth2/..../v1/token
+private:
+ std::string m_Url;
+ std::string m_ClientId;
+ std::string m_ClientSecret;
+};
+
+std::unique_ptr<CloudCacheTokenProvider>
+CloudCacheTokenProvider::MakeFromOAuthClientCredentials(const OAuthClientCredentialsParams& Params)
+{
+ return std::make_unique<OAuthClientCredentialsTokenProvider>(Params);
+}
+
+CloudCacheClient::CloudCacheClient(const CloudCacheClientOptions& Options)
+: m_Log(zen::logging::Get("jupiter"))
+, m_ServiceUrl(Options.ServiceUrl)
+, m_DdcNamespace(Options.DdcNamespace)
+, m_BlobStoreNamespace(Options.BlobStoreNamespace)
+, m_ConnectTimeout(Options.ConnectTimeout)
+, m_Timeout(Options.Timeout)
+{
}
CloudCacheClient::~CloudCacheClient()
@@ -945,36 +869,7 @@ CloudCacheClient::AcquireAccessToken()
{
ZEN_TRACE_CPU("HordeClient::AcquireAccessToken");
- using namespace std::chrono;
-
- // If an access token was provided, return it instead of querying OAuth
- if (!m_AccessToken.empty())
- {
- return {m_AccessToken, steady_clock::time_point::max()};
- }
-
- ExtendableStringBuilder<128> OAuthFormData;
- OAuthFormData << "client_id=" << m_OAuthClientId << "&scope=cache_access&grant_type=client_credentials&client_secret=" << m_OAuthSecret;
-
- std::string Body{OAuthFormData};
-
- cpr::Response Response =
- cpr::Post(cpr::Url{m_OAuthFullUri}, cpr::Header{{"Content-Type", "application/x-www-form-urlencoded"}}, cpr::Body{Body});
-
- Body = std::move(Response.text);
-
- std::string JsonError;
- json11::Json JsonResponse = json11::Json::parse(Body, JsonError);
- if (!JsonError.empty())
- {
- return {};
- }
-
- std::string AccessToken = std::string("Bearer ") + JsonResponse["access_token"].string_value();
- int64_t ExpiresInSeconds = static_cast<int64_t>(JsonResponse["expires_in"].int_value());
- steady_clock::time_point ExpireTime = steady_clock::now() + seconds(ExpiresInSeconds);
-
- return {std::move(AccessToken), ExpireTime};
+ return m_TokenProvider->GetAccessToken();
}
detail::CloudCacheSessionState*
@@ -1001,19 +896,8 @@ CloudCacheClient::AllocSessionState()
void
CloudCacheClient::FreeSessionState(detail::CloudCacheSessionState* State)
{
- const bool IsTokenValid = State->AccessToken.IsValid();
-
RwLock::ExclusiveLockScope _(m_SessionStateLock);
m_SessionStateCache.push_front(State);
-
- // Invalidate all cached access tokens if any one fails
- if (!IsTokenValid)
- {
- for (auto& CachedState : m_SessionStateCache)
- {
- CachedState->AccessToken = {};
- }
- }
}
} // namespace zen