diff options
| author | Per Larsson <[email protected]> | 2022-02-02 09:25:28 +0100 |
|---|---|---|
| committer | Per Larsson <[email protected]> | 2022-02-02 09:25:28 +0100 |
| commit | b22e362ae30b669a02825a13ed2544ae0b9ac649 (patch) | |
| tree | fa5e119212535cf44908dfd95f92c37c73322684 /zenserver/auth/authmgr.cpp | |
| parent | Moved cloud cache token provider out from options. (diff) | |
| download | zen-b22e362ae30b669a02825a13ed2544ae0b9ac649.tar.xz zen-b22e362ae30b669a02825a13ed2544ae0b9ac649.zip | |
Parse expire time from OpenID refresh token and added OpenId token provider.
Diffstat (limited to 'zenserver/auth/authmgr.cpp')
| -rw-r--r-- | zenserver/auth/authmgr.cpp | 165 |
1 files changed, 93 insertions, 72 deletions
diff --git a/zenserver/auth/authmgr.cpp b/zenserver/auth/authmgr.cpp index 4d19316dd..9cdd5ed02 100644 --- a/zenserver/auth/authmgr.cpp +++ b/zenserver/auth/authmgr.cpp @@ -9,7 +9,6 @@ #include <zencore/filesystem.h> #include <zencore/logging.h> -#include <chrono> #include <condition_variable> #include <memory> #include <shared_mutex> @@ -24,6 +23,10 @@ using namespace std::literals; class AuthMgrImpl final : public AuthMgr { + using Clock = std::chrono::system_clock; + using TimePoint = Clock::time_point; + using Seconds = std::chrono::seconds; + public: AuthMgrImpl(const AuthConfig& Config) : m_Config(Config), m_Log(logging::Get("auth")) { LoadState(); } @@ -77,7 +80,7 @@ public: return false; } - if (Params.IdentityToken.empty() || Params.RefreshToken.empty() || Params.AccessToken.empty()) + if (Params.RefreshToken.empty()) { ZEN_WARN("add OpenId token FAILED, reason 'Token invalid'"); return false; @@ -94,12 +97,14 @@ public: bool IsNew = false; { + auto Token = OpenIdToken{.IdentityToken = RefreshResult.IdentityToken, + .RefreshToken = RefreshResult.RefreshToken, + .AccessToken = fmt::format("Bearer {}"sv, RefreshResult.AccessToken), + .ExpireTime = Clock::now() + Seconds(RefreshResult.ExpiresInSeconds)}; + std::unique_lock _(m_TokenMutex); - const auto InsertResult = m_OpenIdTokens.try_emplace(std::string(Params.ProviderName), - OpenIdToken{.IdentityToken = RefreshResult.IdentityToken, - .RefreshToken = RefreshResult.RefreshToken, - .AccessToken = RefreshResult.AccessToken}); + const auto InsertResult = m_OpenIdTokens.try_emplace(std::string(Params.ProviderName), std::move(Token)); IsNew = InsertResult.second; } @@ -124,7 +129,7 @@ public: { const OpenIdToken& Token = It->second; - return {.AccessToken = fmt::format("Bearer {}", Token.AccessToken)}; + return {.AccessToken = Token.AccessToken, .ExpireTime = Token.ExpireTime}; } return {}; @@ -160,102 +165,118 @@ private: void LoadState() { - FileContents Result = ReadFile(m_Config.RootDirectory / "authstate"sv); - - if (Result.ErrorCode) + try { - return; - } + FileContents Result = ReadFile(m_Config.RootDirectory / "authstate"sv); - IoBuffer Buffer = Result.Flatten(); + if (Result.ErrorCode) + { + return; + } - const CbValidateError ValidationError = ValidateCompactBinary(Buffer, CbValidateMode::All); + IoBuffer Buffer = Result.Flatten(); - if (ValidationError != CbValidateError::None) - { - ZEN_WARN("load serialized state FAILED, reason 'Invalid compact binary'"); - return; - } + const CbValidateError ValidationError = ValidateCompactBinary(Buffer, CbValidateMode::All); - if (CbObject AuthState = LoadCompactBinaryObject(Buffer)) - { - for (CbFieldView ProviderView : AuthState["OpenIdProviders"sv]) + if (ValidationError != CbValidateError::None) { - CbObjectView ProviderObj = ProviderView.AsObjectView(); - - std::string_view ProviderName = ProviderObj["Name"].AsString(); - std::string_view Url = ProviderObj["Url"].AsString(); - std::string_view ClientId = ProviderObj["ClientId"].AsString(); - - AddOpenIdProvider({.Name = ProviderName, .Url = Url, .ClientId = ClientId}); + ZEN_WARN("load serialized state FAILED, reason 'Invalid compact binary'"); + return; } - for (CbFieldView TokenView : AuthState["OpenIdTokens"sv]) + if (CbObject AuthState = LoadCompactBinaryObject(Buffer)) { - CbObjectView TokenObj = TokenView.AsObjectView(); + for (CbFieldView ProviderView : AuthState["OpenIdProviders"sv]) + { + CbObjectView ProviderObj = ProviderView.AsObjectView(); - std::string_view ProviderName = TokenObj["ProviderName"sv].AsString(); - std::string_view IdentityToken = TokenObj["IdentityToken"sv].AsString(); - std::string_view RefreshToken = TokenObj["RefreshToken"sv].AsString(); - std::string_view AccessToken = TokenObj["AccessToken"sv].AsString(); + std::string_view ProviderName = ProviderObj["Name"].AsString(); + std::string_view Url = ProviderObj["Url"].AsString(); + std::string_view ClientId = ProviderObj["ClientId"].AsString(); - const bool Ok = AddOpenIdToken({.ProviderName = ProviderName, - .IdentityToken = IdentityToken, - .RefreshToken = RefreshToken, - .AccessToken = AccessToken}); + AddOpenIdProvider({.Name = ProviderName, .Url = Url, .ClientId = ClientId}); + } - if (!Ok) + for (CbFieldView TokenView : AuthState["OpenIdTokens"sv]) { - ZEN_WARN("load serialized OpenId token for provider '{}' FAILED", ProviderName); + CbObjectView TokenObj = TokenView.AsObjectView(); + + std::string_view ProviderName = TokenObj["ProviderName"sv].AsString(); + std::string_view RefreshToken = TokenObj["RefreshToken"sv].AsString(); + + const bool Ok = AddOpenIdToken({.ProviderName = ProviderName, .RefreshToken = RefreshToken}); + + if (!Ok) + { + ZEN_WARN("load serialized OpenId token for provider '{}' FAILED", ProviderName); + } } } } + catch (std::exception& Err) + { + ZEN_ERROR("(de)serialize state FAILED, reason '{}'", Err.what()); + + { + std::unique_lock _(m_ProviderMutex); + m_OpenIdProviders.clear(); + } + + { + std::unique_lock _(m_TokenMutex); + m_OpenIdTokens.clear(); + } + } } void SaveState() { - CbObjectWriter AuthState; - + try { - std::unique_lock _(m_ProviderMutex); + CbObjectWriter AuthState; - if (m_OpenIdProviders.size() > 0) { - AuthState.BeginArray("OpenIdProviders"); - for (const auto& Kv : m_OpenIdProviders) + std::unique_lock _(m_ProviderMutex); + + if (m_OpenIdProviders.size() > 0) { - AuthState.BeginObject(); - AuthState << "Name"sv << Kv.second->Name; - AuthState << "Url"sv << Kv.second->Url; - AuthState << "ClientId"sv << Kv.second->ClientId; - AuthState.EndObject(); + AuthState.BeginArray("OpenIdProviders"); + for (const auto& Kv : m_OpenIdProviders) + { + AuthState.BeginObject(); + AuthState << "Name"sv << Kv.second->Name; + AuthState << "Url"sv << Kv.second->Url; + AuthState << "ClientId"sv << Kv.second->ClientId; + AuthState.EndObject(); + } + AuthState.EndArray(); } - AuthState.EndArray(); } - } - { - std::unique_lock _(m_TokenMutex); - - AuthState.BeginArray("OpenIdTokens"); - if (m_OpenIdTokens.size() > 0) { - for (const auto& Kv : m_OpenIdTokens) + std::unique_lock _(m_TokenMutex); + + AuthState.BeginArray("OpenIdTokens"); + if (m_OpenIdTokens.size() > 0) { - AuthState.BeginObject(); - AuthState << "ProviderName"sv << Kv.first; - AuthState << "IdentityToken"sv << Kv.second.IdentityToken; - AuthState << "RefreshToken"sv << Kv.second.RefreshToken; - AuthState << "AccessToken"sv << Kv.second.AccessToken; - AuthState << "ExpireTime"sv << Kv.second.ExpireTime; - AuthState.EndObject(); + for (const auto& Kv : m_OpenIdTokens) + { + AuthState.BeginObject(); + AuthState << "ProviderName"sv << Kv.first; + AuthState << "RefreshToken"sv << Kv.second.RefreshToken; + AuthState.EndObject(); + } } + AuthState.EndArray(); } - AuthState.EndArray(); - } - std::filesystem::create_directories(m_Config.RootDirectory); - WriteFile(m_Config.RootDirectory / "authstate"sv, AuthState.Save().GetBuffer().AsIoBuffer()); + std::filesystem::create_directories(m_Config.RootDirectory); + WriteFile(m_Config.RootDirectory / "authstate"sv, AuthState.Save().GetBuffer().AsIoBuffer()); + } + catch (std::exception& Err) + { + ZEN_ERROR("serialize state FAILED, reason '{}'", Err.what()); + } } struct OpenIdProvider @@ -271,7 +292,7 @@ private: std::string IdentityToken; std::string RefreshToken; std::string AccessToken; - double ExpireTime{}; + TimePoint ExpireTime{}; }; using OpenIdProviderMap = std::unordered_map<std::string, std::unique_ptr<OpenIdProvider>>; |