aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Larsson <[email protected]>2022-01-25 18:36:41 +0100
committerPer Larsson <[email protected]>2022-01-25 18:36:41 +0100
commit060c3ed4b49c6341d1a917ec728d26bda7e41494 (patch)
tree054b147827833efd715a08f08f85d7d2e25c609c
parentFixed missing object in project oplog response. (diff)
downloadzen-060c3ed4b49c6341d1a917ec728d26bda7e41494.tar.xz
zen-060c3ed4b49c6341d1a917ec728d26bda7e41494.zip
Added auth manager with support for OIDC providers.
-rw-r--r--zenserver/auth/authmgr.cpp72
-rw-r--r--zenserver/auth/authmgr.h36
-rw-r--r--zenserver/auth/authservice.cpp33
-rw-r--r--zenserver/auth/authservice.h5
-rw-r--r--zenserver/config.cpp5
-rw-r--r--zenserver/zenserver.cpp8
6 files changed, 155 insertions, 4 deletions
diff --git a/zenserver/auth/authmgr.cpp b/zenserver/auth/authmgr.cpp
new file mode 100644
index 000000000..af579d950
--- /dev/null
+++ b/zenserver/auth/authmgr.cpp
@@ -0,0 +1,72 @@
+// 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);
+ }
+
+private:
+ struct OpenIdProvider
+ {
+ std::string Name;
+ std::string Url;
+ std::string ClientId;
+ };
+
+ using OpenIdProviderMap = std::unordered_map<std::string, std::unique_ptr<OpenIdProvider>>;
+
+ spdlog::logger& Log() { return m_Log; }
+
+ spdlog::logger& m_Log;
+ std::mutex m_ProviderMutex;
+ OpenIdProviderMap m_OpenIdProviders;
+};
+
+std::unique_ptr<AuthMgr>
+MakeAuthMgr(const AuthConfig& Config)
+{
+ return std::make_unique<AuthMgrImpl>(Config);
+}
+
+} // namespace zen
diff --git a/zenserver/auth/authmgr.h b/zenserver/auth/authmgr.h
new file mode 100644
index 000000000..33bd15ee9
--- /dev/null
+++ b/zenserver/auth/authmgr.h
@@ -0,0 +1,36 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include <zencore/string.h>
+
+#include <filesystem>
+#include <memory>
+
+namespace zen {
+
+class AuthMgr
+{
+public:
+ virtual ~AuthMgr() = default;
+
+ struct AddOpenIdProviderParams
+ {
+ std::string_view Name;
+ std::string_view Url;
+ std::string_view ClientId;
+ };
+
+ virtual void AddOpenIdProvider(const AddOpenIdProviderParams& Params) = 0;
+
+ struct AddOpenIdTokenParams
+ {
+ };
+};
+
+struct AuthConfig
+{
+ std::filesystem::path RootDirectory;
+};
+
+std::unique_ptr<AuthMgr> MakeAuthMgr(const AuthConfig& Config);
+
+} // namespace zen
diff --git a/zenserver/auth/authservice.cpp b/zenserver/auth/authservice.cpp
index c6def15b4..8200b9c9b 100644
--- a/zenserver/auth/authservice.cpp
+++ b/zenserver/auth/authservice.cpp
@@ -1,18 +1,49 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include <auth/authservice.h>
+#include <auth/authmgr.h>
+
+#include <zencore/compactbinarybuilder.h>
#include <zencore/string.h>
+#include <json11.hpp>
+
namespace zen {
using namespace std::literals;
-HttpAuthService::HttpAuthService()
+HttpAuthService::HttpAuthService(AuthMgr& AuthMgr) : m_AuthMgr(AuthMgr)
{
m_Router.RegisterRoute(
"token",
[this](HttpRouterRequest& RouterRequest) {
HttpServerRequest& ServerRequest = RouterRequest.ServerRequest();
+
+ const HttpContentType ContentType = ServerRequest.RequestContentType();
+
+ if ((ContentType == HttpContentType::kUnknownContentType || ContentType == HttpContentType::kJSON) == false)
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest);
+ }
+
+ const IoBuffer Body = ServerRequest.ReadPayload();
+
+ std::string JsonText(reinterpret_cast<const char*>(Body.GetData()), Body.GetSize());
+ std::string JsonError;
+ json11::Json TokenInfo = json11::Json::parse(JsonText, JsonError);
+
+ if (!JsonError.empty())
+ {
+ CbObjectWriter Response;
+ Response << "Result"sv << false;
+ Response << "Error"sv << JsonError;
+
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest, Response.Save());
+ }
+
+ const std::string RefreshToken = TokenInfo["RefreshToken"].string_value();
+ const std::string AccessToken = TokenInfo["AccessToken"].string_value();
+
ServerRequest.WriteResponse(HttpResponseCode::OK);
},
HttpVerb::kPost);
diff --git a/zenserver/auth/authservice.h b/zenserver/auth/authservice.h
index 30b2b5864..64b86e21f 100644
--- a/zenserver/auth/authservice.h
+++ b/zenserver/auth/authservice.h
@@ -6,16 +6,19 @@
namespace zen {
+class AuthMgr;
+
class HttpAuthService final : public zen::HttpService
{
public:
- HttpAuthService();
+ HttpAuthService(AuthMgr& AuthMgr);
virtual ~HttpAuthService();
virtual const char* BaseUri() const override;
virtual void HandleRequest(zen::HttpServerRequest& Request) override;
private:
+ AuthMgr& m_AuthMgr;
HttpRequestRouter m_Router;
};
diff --git a/zenserver/config.cpp b/zenserver/config.cpp
index 4afe012dd..a4439d914 100644
--- a/zenserver/config.cpp
+++ b/zenserver/config.cpp
@@ -91,6 +91,8 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
const char* DefaultHttp = "asio";
#endif
+ std::string DataDir;
+
cxxopts::Options options("zenserver", "Zen Server");
options.add_options()("dedicated",
"Enable dedicated server mode",
@@ -99,7 +101,7 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
options.add_options()("help", "Show command line help");
options.add_options()("t, test", "Enable test mode", cxxopts::value<bool>(ServerOptions.IsTest)->default_value("false"));
options.add_options()("log-id", "Specify id for adding context to log output", cxxopts::value<std::string>(ServerOptions.LogId));
- options.add_options()("data-dir", "Specify persistence root", cxxopts::value<std::filesystem::path>(ServerOptions.DataDir));
+ options.add_options()("data-dir", "Specify persistence root", cxxopts::value<std::string>(DataDir));
options.add_options()("content-dir", "Frontend content directory", cxxopts::value<std::filesystem::path>(ServerOptions.ContentDir));
options.add_options()("abslog", "Path to log file", cxxopts::value<std::filesystem::path>(ServerOptions.AbsLogFile));
options.add_options()("config", "Path to Lua config file", cxxopts::value<std::filesystem::path>(ServerOptions.ConfigFile));
@@ -313,6 +315,7 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
try
{
auto result = options.parse(argc, argv);
+ ServerOptions.DataDir = DataDir;
if (result.count("help"))
{
diff --git a/zenserver/zenserver.cpp b/zenserver/zenserver.cpp
index b8648c8ee..524207921 100644
--- a/zenserver/zenserver.cpp
+++ b/zenserver/zenserver.cpp
@@ -99,6 +99,7 @@ ZEN_THIRD_PARTY_INCLUDES_END
//
#include "admin/admin.h"
+#include "auth/authmgr.h"
#include "auth/authservice.h"
#include "cache/structuredcache.h"
#include "cache/structuredcachestore.h"
@@ -203,9 +204,13 @@ public:
m_Http = zen::CreateHttpServer(ServerOptions.HttpServerClass);
m_Http->Initialize(ServerOptions.BasePort);
- m_AuthService = std::make_unique<zen::HttpAuthService>();
+ m_AuthMgr = MakeAuthMgr({.RootDirectory = m_DataRoot / "auth"});
+ m_AuthService = std::make_unique<zen::HttpAuthService>(*m_AuthMgr);
m_Http->RegisterService(*m_AuthService);
+ m_AuthMgr->AddOpenIdProvider(
+ {.Name = "Okta"sv, .Url = "https://epicgames.okta.com/oauth2/auso645ojjWVdRI3d0x7"sv, .ClientId = "0oapq1knoglGFqQvr0x7"sv});
+
m_Http->RegisterService(m_HealthService);
m_Http->RegisterService(m_StatsService);
m_Http->RegisterService(m_StatusService);
@@ -527,6 +532,7 @@ private:
}
zen::Ref<zen::HttpServer> m_Http;
+ std::unique_ptr<zen::AuthMgr> m_AuthMgr;
std::unique_ptr<zen::HttpAuthService> m_AuthService;
zen::HttpStatusService m_StatusService;
zen::HttpStatsService m_StatsService;