aboutsummaryrefslogtreecommitdiff
path: root/zenserver/auth/authmgr.cpp
diff options
context:
space:
mode:
authorPer Larsson <[email protected]>2022-02-02 16:56:38 +0100
committerPer Larsson <[email protected]>2022-02-02 16:56:38 +0100
commit5b7c068b482b563443320453064fe5fa5601d446 (patch)
tree3309bc01ef5ab2f4d08580b5e6c1098c6b45570b /zenserver/auth/authmgr.cpp
parentParse expire time from OpenID refresh token and added OpenId token provider. (diff)
downloadzen-5b7c068b482b563443320453064fe5fa5601d446.tar.xz
zen-5b7c068b482b563443320453064fe5fa5601d446.zip
Added upstream auth config and removed the possibility to add endpoints via REST.
Diffstat (limited to 'zenserver/auth/authmgr.cpp')
-rw-r--r--zenserver/auth/authmgr.cpp109
1 files changed, 107 insertions, 2 deletions
diff --git a/zenserver/auth/authmgr.cpp b/zenserver/auth/authmgr.cpp
index 9cdd5ed02..7b6c30640 100644
--- a/zenserver/auth/authmgr.cpp
+++ b/zenserver/auth/authmgr.cpp
@@ -28,7 +28,13 @@ class AuthMgrImpl final : public AuthMgr
using Seconds = std::chrono::seconds;
public:
- AuthMgrImpl(const AuthConfig& Config) : m_Config(Config), m_Log(logging::Get("auth")) { LoadState(); }
+ AuthMgrImpl(const AuthConfig& Config) : m_Config(Config), m_Log(logging::Get("auth"))
+ {
+ LoadState();
+
+ m_BackgroundThread.Interval = Config.UpdateInterval;
+ m_BackgroundThread.Thread = std::thread(&AuthMgrImpl::BackgroundThreadEntry, this);
+ }
virtual ~AuthMgrImpl() { SaveState(); }
@@ -161,7 +167,11 @@ private:
return Client.RefreshToken(RefreshToken);
}
- void Shutdown() { SaveState(); }
+ void Shutdown()
+ {
+ BackgroundThread::Stop(m_BackgroundThread);
+ SaveState();
+ }
void LoadState()
{
@@ -279,6 +289,100 @@ private:
}
}
+ void BackgroundThreadEntry()
+ {
+ for (;;)
+ {
+ std::cv_status SignalStatus = BackgroundThread::WaitForSignal(m_BackgroundThread);
+
+ if (m_BackgroundThread.Running.load() == false)
+ {
+ break;
+ }
+
+ if (SignalStatus != std::cv_status::timeout)
+ {
+ continue;
+ }
+
+ {
+ // Refresh Open ID token(s)
+
+ std::vector<OpenIdTokenMap::value_type> ExpiredTokens;
+
+ {
+ std::unique_lock _(m_TokenMutex);
+
+ for (const auto& Kv : m_OpenIdTokens)
+ {
+ const Seconds ExpiresIn = std::chrono::duration_cast<Seconds>(Kv.second.ExpireTime - Clock::now());
+ const bool Expired = ExpiresIn < Seconds(m_BackgroundThread.Interval * 2);
+
+ if (Expired)
+ {
+ ExpiredTokens.push_back(Kv);
+ }
+ }
+ }
+
+ ZEN_DEBUG("refreshing '{}' OpenID token(s)", ExpiredTokens.size());
+
+ for (const auto& Kv : ExpiredTokens)
+ {
+ OidcClient::RefreshTokenResult RefreshResult = RefreshOpenIdToken(Kv.first, Kv.second.RefreshToken);
+
+ if (RefreshResult.Ok)
+ {
+ ZEN_DEBUG("refresh access token from provider '{}' Ok", Kv.first);
+
+ 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);
+ m_OpenIdTokens.insert_or_assign(Kv.first, std::move(Token));
+ }
+ }
+ else
+ {
+ ZEN_WARN("refresh access token from provider '{}' FAILED, reason '{}'", Kv.first, RefreshResult.Reason);
+ }
+ }
+ }
+ }
+ }
+
+ struct BackgroundThread
+ {
+ std::chrono::seconds Interval{10};
+ std::mutex Mutex;
+ std::condition_variable Signal;
+ std::atomic_bool Running{true};
+ std::thread Thread;
+
+ static void Stop(BackgroundThread& State)
+ {
+ if (State.Running.load())
+ {
+ State.Running.store(true);
+ State.Signal.notify_one();
+ }
+
+ if (State.Thread.joinable())
+ {
+ State.Thread.join();
+ }
+ }
+
+ static std::cv_status WaitForSignal(BackgroundThread& State)
+ {
+ std::unique_lock Lock(State.Mutex);
+ return State.Signal.wait_for(Lock, State.Interval);
+ }
+ };
+
struct OpenIdProvider
{
std::string Name;
@@ -302,6 +406,7 @@ private:
AuthConfig m_Config;
spdlog::logger& m_Log;
+ BackgroundThread m_BackgroundThread;
OpenIdProviderMap m_OpenIdProviders;
OpenIdTokenMap m_OpenIdTokens;
std::mutex m_ProviderMutex;