diff --git a/ApiPlugin.cs b/ApiPlugin.cs index f574fa4..3bb82aa 100644 --- a/ApiPlugin.cs +++ b/ApiPlugin.cs @@ -1,15 +1,13 @@ #nullable enable -using System.Collections.Generic; -using System.Linq; using System.Reflection; using BepInEx; -using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using UnityEngine; using VRisingServerApiPlugin.command; +using VRisingServerApiPlugin.http.security; using VRisingServerApiPlugin.query; namespace VRisingServerApiPlugin; @@ -25,15 +23,15 @@ public class ApiPlugin : BasePlugin public static ApiPlugin Instance { get; private set; } #nullable enable - private ConfigEntry _authorizedUsers; - public ApiPlugin() : base() { Instance = this; Logger = Log; - _authorizedUsers = Config.Bind("Authentication", "AuthorizedUsers", "", + var authorizedUsers = Config.Bind("Authentication", "AuthorizedUsers", "", "A list of comma separated username:password entries that defines the accounts allowed to query the API"); + + HttpSecuritySingleton.GetInstance().Initialize(authorizedUsers); } public override void Load() @@ -65,36 +63,4 @@ public override bool Unload() return true; } - - public List GetAuthorizedUserList() - { - return AuthorizedUser.ParseConfig(this._authorizedUsers.Value); - } - - public bool CheckAuthenticationOfUser(string username, string password) - { - return GetAuthorizedUserList() - .Count(user => user.Username.Equals(username) && user.Password.Equals(password)) == 1; - } - - public class AuthorizedUser - { - public string Username { get; set; } - public string Password { get; set; } - - private AuthorizedUser(string username, string password) - { - Username = username; - Password = password; - } - - public static List ParseConfig(string authorizedUsers) - { - return (from user in authorizedUsers.Split(",") - select user.Split(':') - into parts - where parts.Length == 2 - select new AuthorizedUser(parts[0].Trim(), parts[1].Trim())).ToList(); - } - } } \ No newline at end of file diff --git a/VRisingServerApiPlugin.csproj b/VRisingServerApiPlugin.csproj index 1edb600..0992bd2 100644 --- a/VRisingServerApiPlugin.csproj +++ b/VRisingServerApiPlugin.csproj @@ -23,9 +23,6 @@ - - - diff --git a/http/HttpRequestParser.cs b/http/HttpRequestParser.cs index 3ff9d62..94e0fe8 100644 --- a/http/HttpRequestParser.cs +++ b/http/HttpRequestParser.cs @@ -3,6 +3,7 @@ using Il2CppSystem.Net; using Il2CppSystem.Security.Principal; using VRisingServerApiPlugin.command; +using VRisingServerApiPlugin.http.security; namespace VRisingServerApiPlugin.http; @@ -64,7 +65,7 @@ public static HttpRequest ParseHttpRequest(HttpListenerContext context, Command var username = identity.Name; var password = identity.password; - var isAuthorized = ApiPlugin.Instance.CheckAuthenticationOfUser(username, password); + var isAuthorized = HttpSecuritySingleton.GetInstance().CheckAuthenticationOfUser(username, password); return new AuthenticatedUser(Username: identity.Name, Password: identity.password, IsAuthorized: isAuthorized); diff --git a/http/security/AuthorizedUser.cs b/http/security/AuthorizedUser.cs new file mode 100644 index 0000000..83fe542 --- /dev/null +++ b/http/security/AuthorizedUser.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Linq; + +namespace VRisingServerApiPlugin.http.security; + +public class AuthorizedUser +{ + public string Username { get; set; } + public string Password { get; set; } + + private AuthorizedUser(string username, string password) + { + Username = username; + Password = password; + } + + public static IEnumerable ParseConfig(string authorizedUsers) + { + return (from user in authorizedUsers.Split(",") + select user.Split(':') + into parts + where parts.Length == 2 + select new AuthorizedUser(parts[0].Trim(), parts[1].Trim())).ToList(); + } +} \ No newline at end of file diff --git a/http/security/HttpSecuritySingleton.cs b/http/security/HttpSecuritySingleton.cs new file mode 100644 index 0000000..8f3f5ce --- /dev/null +++ b/http/security/HttpSecuritySingleton.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using System.Linq; +using BepInEx.Configuration; + +namespace VRisingServerApiPlugin.http.security; + +public class HttpSecuritySingleton +{ + private static HttpSecuritySingleton _instance; + + private IEnumerable _authorizedUsers; + + public static HttpSecuritySingleton GetInstance() + { + return _instance ??= new HttpSecuritySingleton(); + } + + public void Initialize(ConfigEntry authorizedUsers) + { + authorizedUsers.SettingChanged += (_, args) => + { + var changedArgs = (SettingChangedEventArgs)args; + var changedSettings = (ConfigEntry)changedArgs.ChangedSetting; + + _authorizedUsers = GetAuthorizedUserList(changedSettings.Value); + }; + _authorizedUsers = GetAuthorizedUserList(authorizedUsers.Value); + } + + private static IEnumerable GetAuthorizedUserList(string authorizedUsers) + { + return AuthorizedUser.ParseConfig(authorizedUsers); + } + + public bool CheckAuthenticationOfUser(string username, string password) + { + return _authorizedUsers + .Count(user => user.Username.Equals(username) && user.Password.Equals(password)) == 1; + } +} \ No newline at end of file