diff options
| author | Per Larsson <[email protected]> | 2022-02-02 16:56:38 +0100 |
|---|---|---|
| committer | Per Larsson <[email protected]> | 2022-02-02 16:56:38 +0100 |
| commit | 5b7c068b482b563443320453064fe5fa5601d446 (patch) | |
| tree | 3309bc01ef5ab2f4d08580b5e6c1098c6b45570b /zenserver/auth/authmgr.cpp | |
| parent | Parse expire time from OpenID refresh token and added OpenId token provider. (diff) | |
| download | zen-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.cpp | 109 |
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; |