aboutsummaryrefslogtreecommitdiff
path: root/zenserver/auth/authmgr.cpp
diff options
context:
space:
mode:
authorPer Larsson <[email protected]>2022-02-02 09:25:28 +0100
committerPer Larsson <[email protected]>2022-02-02 09:25:28 +0100
commitb22e362ae30b669a02825a13ed2544ae0b9ac649 (patch)
treefa5e119212535cf44908dfd95f92c37c73322684 /zenserver/auth/authmgr.cpp
parentMoved cloud cache token provider out from options. (diff)
downloadzen-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.cpp165
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>>;