diff options
| author | Per Larsson <[email protected]> | 2022-02-01 10:47:12 +0100 |
|---|---|---|
| committer | Per Larsson <[email protected]> | 2022-02-01 10:47:12 +0100 |
| commit | ee00d9db3e0b65667d9b2a792cf0567aff2844fb (patch) | |
| tree | cda98c52a90ecb1edbafa5651ca31e016037fc05 /zenserver/upstream/jupiter.cpp | |
| parent | Merged main. (diff) | |
| download | zen-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.cpp | 360 |
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 |