aboutsummaryrefslogtreecommitdiff
path: root/zenserver/auth/authmgr.cpp
blob: 4c97693f9f3247676d4a7454c8218aeafe1f0dd5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright Epic Games, Inc. All Rights Reserved.

#include <auth/authmgr.h>
#include <zencore/logging.h>

#include <chrono>
#include <condition_variable>
#include <shared_mutex>
#include <thread>
#include <unordered_map>

namespace zen {

class AuthMgrImpl final : public AuthMgr
{
public:
	AuthMgrImpl(const AuthConfig& Config) : m_Log(logging::Get("auth")) { ZEN_UNUSED(Config); }

	virtual ~AuthMgrImpl() {}

	virtual void AddOpenIdProvider(const AddOpenIdProviderParams& Params) final
	{
		std::string NewProviderName = std::string(Params.Name);

		OpenIdProvider* NewProvider = nullptr;

		{
			std::unique_lock _(m_ProviderMutex);

			if (m_OpenIdProviders.contains(NewProviderName))
			{
				return;
			}

			auto InsertResult = m_OpenIdProviders.emplace(NewProviderName, std::make_unique<OpenIdProvider>());
			NewProvider		  = InsertResult.first->second.get();
		}

		NewProvider->Name	  = std::string(Params.Name);
		NewProvider->Url	  = std::string(Params.Url);
		NewProvider->ClientId = std::string(Params.ClientId);

		ZEN_INFO("added OpenID provider '{} - {}'", Params.Name, Params.Url);
	}

	virtual bool AddOpenIdToken(const AddOpenIdTokenParams& Params) final
	{
		if (Params.ProviderName.empty())
		{
			ZEN_WARN("trying add OpenID token with invalid provider name");
			return false;
		}

		if (Params.IdentityToken.empty() || Params.RefreshToken.empty() || Params.AccessToken.empty())
		{
			ZEN_WARN("trying add invalid OpenID token");
			return false;
		}

		bool IsNew = false;

		{
			std::unique_lock _(m_TokenMutex);

			const auto InsertResult = m_OpenIdTokens.try_emplace(std::string(Params.ProviderName),
																 OpenIdToken{.IdentityToken = std::string(Params.IdentityToken),
																			 .RefreshToken	= Params.RefreshToken,
																			 .AccessToken	= Params.AccessToken});

			IsNew = InsertResult.second;
		}

		if (IsNew)
		{
			ZEN_INFO("added new OpenID token for provider '{}'", Params.ProviderName);
		}
		else
		{
			ZEN_INFO("updating OpenID token for provider '{}'", Params.ProviderName);
		}

		return true;
	}

private:
	struct OpenIdProvider
	{
		std::string Name;
		std::string Url;
		std::string ClientId;
	};

	struct OpenIdToken
	{
		std::string_view IdentityToken;
		std::string_view RefreshToken;
		std::string_view AccessToken;
		double			 ExpireTime{};
	};

	using OpenIdProviderMap = std::unordered_map<std::string, std::unique_ptr<OpenIdProvider>>;
	using OpenIdTokenMap	= std::unordered_map<std::string, OpenIdToken>;

	spdlog::logger& Log() { return m_Log; }

	spdlog::logger&	  m_Log;
	OpenIdProviderMap m_OpenIdProviders;
	OpenIdTokenMap	  m_OpenIdTokens;
	std::mutex		  m_ProviderMutex;
	std::shared_mutex m_TokenMutex;
};

std::unique_ptr<AuthMgr>
MakeAuthMgr(const AuthConfig& Config)
{
	return std::make_unique<AuthMgrImpl>(Config);
}

}  // namespace zen