From ecbb3c0ab744f472a91a803cff7e861f064f6789 Mon Sep 17 00:00:00 2001 From: Pilzinsel64 Date: Thu, 18 Jul 2024 16:42:35 +0200 Subject: [PATCH] some work (need to thing about client and server data model as next step) --- .../Api/Endpoint/Implementations/LoginApi.cs | 2 +- OwnChar.Server/Api/IServer.cs | 6 +- .../Api/Plugins/IPluginLoadContextServer.cs | 5 -- OwnChar.Server/OwnChar.Server.csproj | 1 + OwnChar.Server/Program.cs | 49 +++---------- OwnChar.Server/ServerContext.cs | 70 +++++++++++++++++-- OwnChar.Server/ServerSettings.cs | 19 +++++ 7 files changed, 99 insertions(+), 53 deletions(-) delete mode 100644 OwnChar.Server/Api/Plugins/IPluginLoadContextServer.cs create mode 100644 OwnChar.Server/ServerSettings.cs diff --git a/OwnChar.Server/Api/Endpoint/Implementations/LoginApi.cs b/OwnChar.Server/Api/Endpoint/Implementations/LoginApi.cs index 4fd4ad9..c702638 100644 --- a/OwnChar.Server/Api/Endpoint/Implementations/LoginApi.cs +++ b/OwnChar.Server/Api/Endpoint/Implementations/LoginApi.cs @@ -14,7 +14,7 @@ internal class LoginApi(ServerContext server) : IApiEndpoint private IResult Login(string username, [FromHeader(Name = "X-USER-PASSWORD")] string password) { - if (server.Data != null && server.Data.GetAll()?.FirstOrDefault(n => n.Username == username && n.Password == password) is UserAccount account) + if (server.Data != null && server.Data.Set()?.FirstOrDefault(n => n.Username == username && n.Password == password) is UserAccount account) return TypedResults.Ok(new LoginResponse { Secret = server.Login(account), diff --git a/OwnChar.Server/Api/IServer.cs b/OwnChar.Server/Api/IServer.cs index f87ab86..4306eca 100644 --- a/OwnChar.Server/Api/IServer.cs +++ b/OwnChar.Server/Api/IServer.cs @@ -1,14 +1,16 @@ -using OwnChar.Data; +using Microsoft.EntityFrameworkCore; using OwnChar.Model; using Pilz.Configuration; using System.Diagnostics.CodeAnalysis; +using ILogger = Castle.Core.Logging.ILogger; namespace OwnChar.ServerNew.Api; public interface IServer { ISettings Settings { get; } - IDataProvider? Data { get; } + DbContext? Data { get; } + ILogger Log { get; } [MemberNotNull(nameof(Data))] void CheckLogin(string secret); diff --git a/OwnChar.Server/Api/Plugins/IPluginLoadContextServer.cs b/OwnChar.Server/Api/Plugins/IPluginLoadContextServer.cs deleted file mode 100644 index 15b6615..0000000 --- a/OwnChar.Server/Api/Plugins/IPluginLoadContextServer.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace OwnChar.ServerNew.Api.Plugins; - -public interface IPluginLoadContextServer -{ -} diff --git a/OwnChar.Server/OwnChar.Server.csproj b/OwnChar.Server/OwnChar.Server.csproj index 1259423..4d6a891 100644 --- a/OwnChar.Server/OwnChar.Server.csproj +++ b/OwnChar.Server/OwnChar.Server.csproj @@ -7,6 +7,7 @@ + diff --git a/OwnChar.Server/Program.cs b/OwnChar.Server/Program.cs index 6bd16e8..cfd5ecf 100644 --- a/OwnChar.Server/Program.cs +++ b/OwnChar.Server/Program.cs @@ -1,11 +1,6 @@ -using OwnChar.Data; using OwnChar.Plugins; -using OwnChar.ServerNew.Api.Endpoint; -using OwnChar.ServerNew.Api.Endpoint.Implementations; using OwnChar.ServerNew.Api.Plugins; using Pilz.Configuration; -using Pilz.Plugins; -using Pilz.Plugins.Advanced; namespace OwnChar.ServerNew; @@ -24,46 +19,18 @@ internal class Program // Create server context var server = new ServerContext(SettingsManager.Instance); + // Load log + // ... + // Load plugins + server.Log.Debug("Loading plugins"); var pluginPath = Path.Combine(AppTempFolder, "Plugins"); Directory.CreateDirectory(pluginPath); var pluginPaths = Directory.GetDirectories(pluginPath, "*", SearchOption.TopDirectoryOnly).Select(n => Path.Combine(n, n + ".dll")).ToArray(); - OwnCharPlugins.Instance.LoadPlugins(pluginPaths, new OwnCharServerPluginInitParams(server)); + var plugins = OwnCharPlugins.Instance.LoadPlugins(pluginPaths, new OwnCharServerPluginInitParams(server)); + server.Log.InfoFormat("{0} plugins loaded", plugins.Count()); - // Add services to the container. - var builder = WebApplication.CreateBuilder(args); - builder.Services.AddAuthorization(); - builder.Services.AddEndpointsApiExplorer(); - builder.Services.AddSwaggerGen(); - - // Build app - var app = builder.Build(); - - // Configure the HTTP request pipeline. - if (app.Environment.IsDevelopment()) - { - app.UseSwagger(); - app.UseSwaggerUI(); - } - app.UseHttpsRedirection(); - app.UseAuthorization(); - - // Built-in endpoints - var apibuilder = new ApiBuilder(app); - new LoginApi(server).Initialize(apibuilder); - new UsersApi(server).Initialize(apibuilder); - new GroupsApi(server).Initialize(apibuilder); - new CharactersApi(server).Initialize(apibuilder); - - // Plugin endpoints - var endpoints = PluginFeatureController.Instance.Features.Get(ApiEndpointFeature.FeatureType).OfType(); - if (endpoints.Any()) - { - foreach (var endpoint in endpoints) - endpoint.Initialize(apibuilder); - } - - // Run server - app.Run(); + // Start server app + server.Start(args); } } diff --git a/OwnChar.Server/ServerContext.cs b/OwnChar.Server/ServerContext.cs index d61a6a3..7c09e49 100644 --- a/OwnChar.Server/ServerContext.cs +++ b/OwnChar.Server/ServerContext.cs @@ -1,45 +1,107 @@ -using OwnChar.Data; +using Castle.Core.Logging; +using Microsoft.EntityFrameworkCore; +using OwnChar.Data; using OwnChar.Model; -using OwnChar.ServerNew.Api; +using OwnChar.Server; +using OwnChar.ServerNew.Api.Endpoint; +using OwnChar.ServerNew.Api.Endpoint.Implementations; using OwnChar.ServerNew.Api.Plugins; using Pilz.Configuration; using Pilz.Cryptography; +using Pilz.Plugins.Advanced; +using ILogger = Castle.Core.Logging.ILogger; namespace OwnChar.ServerNew; -internal class ServerContext(ISettings settings) : IServer, IPluginLoadContextServer +internal class ServerContext(ISettings settings) : Api.IServer { private readonly Dictionary users = []; - public IDataProvider? Data { get; private set; } + public DbContext? Data { get; private set; } public ISettings Settings { get; } = settings; + public ILogger Log { get; set; } = NullLogger.Instance; + + public void Start(string[] args) + { + Log.Info("Prepairing server context"); + + // Add services to the container. + var builder = WebApplication.CreateBuilder(args); + builder.Services.AddAuthorization(); + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); + + // Build app + var app = builder.Build(); + + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + app.UseHttpsRedirection(); + app.UseAuthorization(); + + // Load database + Log.Debug("Loading database"); + var settings = Settings.Get(); + Data = new DatabaseContext(settings.DbServer, settings.DbUser, settings.DbPassword); + + // Built-in endpoints + Log.Debug("Loading internal api endpoints"); + var apibuilder = new ApiBuilder(app); + new LoginApi(this).Initialize(apibuilder); + new UsersApi(this).Initialize(apibuilder); + new GroupsApi(this).Initialize(apibuilder); + new CharactersApi(this).Initialize(apibuilder); + + // Plugin endpoints + Log.Debug("Loading plugin api endpoints"); + var endpoints = PluginFeatureController.Instance.Features.Get(ApiEndpointFeature.FeatureType).OfType(); + if (endpoints.Any()) + { + foreach (var endpoint in endpoints) + endpoint.Initialize(apibuilder); + } + + // Run server + Log.Info("Starting webserver"); + app.Run(); + } + public string Login(UserAccount account) { var secret = new UniquieID(UniquieIDGenerationMode.GenerateOnInit).ID; users.Add(secret, account); + Log.DebugFormat("Logged-in out user with secret {0}", secret); return secret; } public void Logout(string secret) { users.Remove(secret); + Log.DebugFormat("Logged-out user with secret {0}", secret); } public bool IsLoggedIn(string secret) { + Log.DebugFormat("Deleting user with secret {0}", secret); return users.ContainsKey(secret); } public void CheckLogin(string secret) { + Log.DebugFormat("Checking login for user with secret {0}", secret); if (!IsLoggedIn(secret)) throw new UnauthorizedAccessException(); } public UserAccount? GetUser(string secret) { + Log.DebugFormat("Getting user with secret {0}", secret); if (users.TryGetValue(secret, out UserAccount? value)) return value; return null; diff --git a/OwnChar.Server/ServerSettings.cs b/OwnChar.Server/ServerSettings.cs new file mode 100644 index 0000000..cf6e87f --- /dev/null +++ b/OwnChar.Server/ServerSettings.cs @@ -0,0 +1,19 @@ +using Pilz.Configuration; + +namespace OwnChar.Server; + +public class ServerSettings : IChildSettings, ISettingsIdentifier +{ + public static string Identifier => "ownchar.server.data.sql"; + + public string? DbServer { get; set; } + public string? DbUser { get; set; } + public string? DbPassword { get; set; } + + public void Reset() + { + DbServer = null; + DbUser = null; + DbPassword = null; + } +}