using Microsoft.EntityFrameworkCore; using OwnChar.Data.Model.Base; using OwnChar.Server.Api; using OwnChar.Server.Api.Endpoint; using OwnChar.Server.Api.Plugins; using OwnChar.Server.Data; using Pilz.Configuration; using Pilz.Cryptography; using Pilz.Extensions.Collections; using Pilz.Net.Api; using Pilz.Plugins.Advanced; namespace OwnChar.Server; internal class ServerContext(ISettings settings) : ApiServer(settings.Get().ApiUrl!), IOwnCharServer { private readonly Dictionary users = []; public DbContext? Data { get; private set; } public ISettings Settings { get; } = settings; public override void Start() { Log.Info("Prepairing server"); // Load database var settings = Settings.Get(); Log.Debug("Loading database"); Data = new DatabaseContext(settings.DbServer, settings.DbUser, settings.DbPassword); // Built-in endpoints Log.Debug("Loading internal api endpoints"); RegisterHandler(new LoginApi(this)); RegisterHandler(new UsersApi(this)); RegisterHandler(new GroupsApi(this)); RegisterHandler(new CharactersApi(this)); // Plugin endpoints Log.Debug("Loading plugin api endpoints"); PluginFeatureController.Instance.Features.Get(ApiEndpointFeature.FeatureType).OfType().ForEach(n => n.OnServerInit(this)); // Run server Log.Info("Starting webserver"); base.Start(); } protected override string? DecodeAuthKey(string authKey) { if (!string.IsNullOrWhiteSpace(authKey)) return new SecureString(authKey, true).Value; return authKey; } protected override bool CheckAuthentication(string authKey) { return string.IsNullOrWhiteSpace(authKey) || authKey.Split(":") is not string[] authKeyParts || authKey.Length != 2 || string.IsNullOrWhiteSpace(authKeyParts[0]) || string.IsNullOrWhiteSpace(authKeyParts[1]) || !IsLoggedIn(authKeyParts[1]); } public string Login(UserAccountBase 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 UserAccountBase? GetUser(string secret) { Log.DebugFormat("Getting user with secret {0}", secret); if (users.TryGetValue(secret, out UserAccountBase? value)) return value; return null; } }