From 4cd52de441725821135e0e0b96b71449c46e5f33 Mon Sep 17 00:00:00 2001 From: Schedel Pascal Date: Fri, 23 Aug 2024 11:18:46 +0200 Subject: [PATCH] finish migration to Pilz.NET --- OwnChar.Server/Api/Endpoint/CharactersApi.cs | 2 +- OwnChar.Server/Api/Endpoint/GroupsApi.cs | 106 +++++++++--------- OwnChar.Server/Api/Endpoint/IApiEndpoint.cs | 6 - OwnChar.Server/Api/Endpoint/LoginApi.cs | 44 +++----- OwnChar.Server/Api/Endpoint/UsersApi.cs | 2 +- .../Api/{IServer.cs => IOwnCharServer.cs} | 2 +- .../Api/Plugins/ApiEndpointFeature.cs | 5 +- .../Plugins/OwnCharServerPluginInitParams.cs | 4 +- .../Extensions/GeneralExtensions.cs | 29 +++-- OwnChar.Server/ServerContext.cs | 13 ++- 10 files changed, 103 insertions(+), 110 deletions(-) delete mode 100644 OwnChar.Server/Api/Endpoint/IApiEndpoint.cs rename OwnChar.Server/Api/{IServer.cs => IOwnCharServer.cs} (91%) diff --git a/OwnChar.Server/Api/Endpoint/CharactersApi.cs b/OwnChar.Server/Api/Endpoint/CharactersApi.cs index 40469e1..80c8900 100644 --- a/OwnChar.Server/Api/Endpoint/CharactersApi.cs +++ b/OwnChar.Server/Api/Endpoint/CharactersApi.cs @@ -1,6 +1,6 @@ namespace OwnChar.Server.Api.Endpoint; -internal class CharactersApi(IServer server) : IApiEndpoint +internal class CharactersApi(IOwnCharServer server) : IApiEndpoint { public void Initialize(IApiBuilder builder) { diff --git a/OwnChar.Server/Api/Endpoint/GroupsApi.cs b/OwnChar.Server/Api/Endpoint/GroupsApi.cs index 808ebaf..ecfc95e 100644 --- a/OwnChar.Server/Api/Endpoint/GroupsApi.cs +++ b/OwnChar.Server/Api/Endpoint/GroupsApi.cs @@ -1,44 +1,33 @@ -using OwnChar.Api.Packets; -using OwnChar.Api.Packets.General; +using OwnChar.Api.Packets.General; using OwnChar.Api.Packets.Groups; using OwnChar.Api.Updates; using OwnChar.Data; using OwnChar.Data.Model.Client; using OwnChar.Server.Data.Model; using OwnChar.Server.Extensions; +using Pilz.Net.Api; namespace OwnChar.Server.Api.Endpoint; -internal class GroupsApi(IServer server) : IApiEndpoint +internal class GroupsApi(IOwnCharServer server) { - public void Initialize(IApiBuilder builder) + [MessageHandler("/group/get/byid")] + public ApiResult GetById(GetSinlgeObjectRequest request, ApiRequestInfo info) { - builder.Map("/groups/get/byid", GetById); - builder.Map("/groups/get", Get); - builder.Map("/groups/create", Create); - builder.Map("/groups/update", Update); - builder.Map("/groups/delete", Delete); - builder.Map("/groups/members/get", GetMembers); - builder.Map("/groups/members/add", AddMembers); - builder.Map("/groups/members/update", UpdateMember); - builder.Map("/groups/members/remove", RemoveMembers); - } - - private IResult GetById(GetSinlgeObjectRequest request) - { - if (!server.CheckLogin(request, UserType.Guest, out UserAccountDb? user)) - return TypedResults.Unauthorized(); + if (!server.CheckLogin(info, UserType.Guest, out UserAccountDb? user)) + return ApiResult.Unauthorized(); if (server.Data?.Set().FirstOrDefault(n => n.Id == request.ObjectId && n.Members.Any(m => m.User != null && m.User.Id == user.Id)) is not GroupDb group) - return TypedResults.Ok(new GetSingleObjectResponse(null).With(OwnCharResponseError.NotFound)); + return ApiResult.NotFound(); - return TypedResults.Ok(new GetSingleObjectResponse(group.ToClient())); + return ApiResult.Ok(new GetSingleObjectResponse(group.ToClient())); } - private IResult Get(GetGroupsRequest request) + [MessageHandler("/group/get", RequiesAuth = true)] + public ApiResult Get(GetGroupsRequest request, ApiRequestInfo info) { - if (!server.CheckLogin(request, UserType.Guest, out UserAccountDb? user)) - return TypedResults.Unauthorized(); + if (!server.CheckLogin(info, UserType.Guest, out UserAccountDb? user)) + return ApiResult.Unauthorized(); IQueryable groups; @@ -49,13 +38,14 @@ internal class GroupsApi(IServer server) : IApiEndpoint else groups = Array.Empty().AsQueryable(); // Currently not supported. - return TypedResults.Ok(new GetGroupsResponse([.. groups.Select(g => g.ToClient())])); + return ApiResult.Ok(new GetGroupsResponse([.. groups.Select(g => g.ToClient())])); } - private IResult Create(CreateGroupRequest request) + [MessageHandler("/group/create", RequiesAuth = true)] + public ApiResult Create(CreateGroupRequest request, ApiRequestInfo info) { - if (!server.CheckLogin(request, UserType.User, out UserAccountDb? user)) - return TypedResults.Unauthorized(); + if (!server.CheckLogin(info, UserType.User, out UserAccountDb? user)) + return ApiResult.Unauthorized(); var group = new GroupDb(); @@ -71,19 +61,20 @@ internal class GroupsApi(IServer server) : IApiEndpoint server.Data!.Update(group); server.Data.SaveChanges(); - return TypedResults.Ok(new CreateGroupResponse(group.ToClient())); + return ApiResult.Ok(new CreateGroupResponse(group.ToClient())); } - private IResult Update(UpdateRequest request) + [MessageHandler("/group/update", RequiesAuth = true)] + public ApiResult Update(UpdateRequest request, ApiRequestInfo info) { - if (!server.CheckLogin(request, UserType.User, out UserAccountDb? user) + if (!server.CheckLogin(info, UserType.User, out UserAccountDb? user) || server.Data?.Set().FirstOrDefault(n => n.Id == request.Update.Id) is not GroupDb group || !group.Members.Any(m => m.Id == user.Profile!.Id && m.Level >= MemberLevel.Admin || user.IsNot(UserType.Admin))) - return TypedResults.Unauthorized(); + return ApiResult.Unauthorized(); if (request.Update is not GroupUpdate update) - return TypedResults.Ok(new UpdateResponse().With(OwnCharResponseError.Default)); + return ApiResult.NotFound(); group.Name = update.Name; group.Fandom = update.Fandom; @@ -91,42 +82,45 @@ internal class GroupsApi(IServer server) : IApiEndpoint server.Data.Update(group); server.Data.SaveChanges(); - return TypedResults.Ok(new UpdateResponse()); + return ApiResult.Ok(); } - private IResult Delete(DeleteObjectRequest request) + [MessageHandler("/group/delete", RequiesAuth = true)] + public ApiResult Delete(DeleteObjectRequest request, ApiRequestInfo info) { - if (!server.CheckLogin(request, UserType.User, out UserAccountDb? user) + if (!server.CheckLogin(info, UserType.User, out UserAccountDb? user) || server.Data?.Set().FirstOrDefault(n => n.Id == request.ObjectId) is not GroupDb group || !group.Members.Any(m => m.Id == user.Profile!.Id && m.Level >= MemberLevel.Owner) || user.IsNot(UserType.Admin)) - return TypedResults.Unauthorized(); + return ApiResult.Unauthorized(); server.Data.Remove(group); server.Data.SaveChanges(); - return TypedResults.Ok(new DeleteObjectResponse()); + return ApiResult.Ok(); } - private IResult GetMembers(GetGroupMembersRequest request) + [MessageHandler("/group/members/get", RequiesAuth = true)] + public ApiResult GetMembers(GetGroupMembersRequest request, ApiRequestInfo info) { - if (!server.CheckLogin(request, UserType.User, out UserAccountDb? user) + if (!server.CheckLogin(info, UserType.User, out UserAccountDb? user) || server.Data?.Set().FirstOrDefault(n => n.Id == request.GroupId) is not GroupDb group || !group.Members.Any(m => m.Id == user.Profile!.Id && m.Level >= MemberLevel.Member) || user.IsNot(UserType.Admin)) - return TypedResults.Unauthorized(); + return ApiResult.Unauthorized(); var members = group.Members.Select(n => n.ToClient()); - return TypedResults.Ok(new GetGroupMembersResponse(members.ToList())); + return ApiResult.Ok(new GetGroupMembersResponse(members.ToList())); } - private IResult AddMembers(GroupMemberAddRequest request) + [MessageHandler("/group/members/add", RequiesAuth = true)] + public ApiResult AddMembers(GroupMemberAddRequest request, ApiRequestInfo info) { - if (!server.CheckLogin(request, UserType.User, out UserAccountDb? user) + if (!server.CheckLogin(info, UserType.User, out UserAccountDb? user) || server.Data?.Set().FirstOrDefault(n => n.Id == request.GroupId) is not GroupDb group || !group.Members.Any(m => m.Id == user.Profile!.Id && m.Level >= MemberLevel.Admin) || user.IsNot(UserType.Admin)) - return TypedResults.Unauthorized(); + return ApiResult.Unauthorized(); var addedMembers = new List(); @@ -146,43 +140,45 @@ internal class GroupsApi(IServer server) : IApiEndpoint } } - return TypedResults.Ok(new GroupMemberAddResponse(addedMembers.Select(m => m.ToClient()).ToList())); + return ApiResult.Ok(new GroupMemberAddResponse(addedMembers.Select(m => m.ToClient()).ToList())); } - private IResult UpdateMember(UpdateRequest request) + [MessageHandler("/group/members/update", RequiesAuth = true)] + public ApiResult UpdateMember(UpdateRequest request, ApiRequestInfo info) { - if (!server.CheckLogin(request, UserType.User, out UserAccountDb? user) + if (!server.CheckLogin(info, UserType.User, out UserAccountDb? user) || server.Data?.Set().FirstOrDefault(n => n.Id == request.Update.Id) is not GroupDb group || group.Members.FirstOrDefault(m => m.Id == request.Update.Id) is not MemberEntryDb member || !group.Members.Any(m => m.Id == user.Profile!.Id && m.Level >= MemberLevel.Admin || user.IsNot(UserType.Admin))) - return TypedResults.Unauthorized(); + return ApiResult.Unauthorized(); if (request.Update is not MemberUpdate update) - return TypedResults.Ok(new UpdateResponse().With(OwnCharResponseError.Default)); + return ApiResult.NotFound(); member.Level = update.Level; server.Data.Update(member); server.Data.SaveChanges(); - return TypedResults.Ok(new UpdateResponse()); + return ApiResult.Ok(); } - private IResult RemoveMembers(DeleteObjectRequest request) + [MessageHandler("/group/members/remove", RequiesAuth = true)] + public ApiResult RemoveMembers(DeleteObjectRequest request, ApiRequestInfo info) { - if (!server.CheckLogin(request, UserType.User, out UserAccountDb? user) + if (!server.CheckLogin(info, UserType.User, out UserAccountDb? user) || server.Data?.Set().FirstOrDefault(m => m.Id == request.ObjectId) is not MemberEntryDb member || server.Data?.Set().FirstOrDefault(n => n.Members.Contains(member)) is not GroupDb group || !group.Members.Any(m => m.Id == user.Profile!.Id && m.Level >= MemberLevel.Admin || user.IsNot(UserType.Admin))) - return TypedResults.Unauthorized(); + return ApiResult.Unauthorized(); group.Members.Remove(member); server.Data.Remove(member); server.Data.Update(group); server.Data.SaveChanges(); - return TypedResults.Ok(new DeleteObjectResponse()); + return ApiResult.Ok(); } } diff --git a/OwnChar.Server/Api/Endpoint/IApiEndpoint.cs b/OwnChar.Server/Api/Endpoint/IApiEndpoint.cs deleted file mode 100644 index 5bcf7cd..0000000 --- a/OwnChar.Server/Api/Endpoint/IApiEndpoint.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace OwnChar.Server.Api.Endpoint; - -internal interface IApiEndpoint -{ - void Initialize(IApiBuilder builder); -} diff --git a/OwnChar.Server/Api/Endpoint/LoginApi.cs b/OwnChar.Server/Api/Endpoint/LoginApi.cs index 69aab94..f0a82b2 100644 --- a/OwnChar.Server/Api/Endpoint/LoginApi.cs +++ b/OwnChar.Server/Api/Endpoint/LoginApi.cs @@ -2,41 +2,29 @@ using OwnChar.Api.Packets.General; using OwnChar.Server.Data.Model; using OwnChar.Server.Extensions; +using Pilz.Net.Api; namespace OwnChar.Server.Api.Endpoint; -internal class LoginApi(ServerContext server) : IApiEndpoint +internal class LoginApi(ServerContext server) { - public void Initialize(IApiBuilder builder) + [MessageHandler("/auth/login")] + public ApiResult Login(LoginRequest request, ApiRequestInfo info) { - builder.Map("/auth/login", Login); - builder.Map("/auth/logout", Logout); + if (server.Data?.Set()?.FirstOrDefault(n => n.Username == request.Username && n.Password == request.Password) is UserAccountDb acc && acc.Profile != null) + { + if (info.IsAuthenticated) + server.Logout(info.AuthKey); + return ApiResult.Ok(new LoginResponse(acc.ToClient(), acc.Profile.ToClient(), server.Login(acc))); + } + return ApiResult.NotFound(); } - private IResult Login(LoginRequest request) + [MessageHandler("/auth/logout")] + public ApiResult Logout(ApiRequestInfo info) { - LoginResponse? result; - - if (server.Data != null - && server.Data.Set()?.FirstOrDefault(n => n.Username == request.Username && n.Password == request.Password) is UserAccountDb acc - && acc.Profile != null) - { - result = new(acc.ToClient(), acc.Profile.ToClient(), server.Login(acc)); - } - else - { - result = new(null, null, null) - { - ErrorCode = OwnCharResponseError.NotFound, - }; - } - - return TypedResults.Ok(result); - } - - private IResult Logout(LogoutRequest request) - { - server.Logout(request.AuthSecret); - return TypedResults.Ok(new LogoutResponse()); + if (info.IsAuthenticated) + server.Logout(info.AuthKey); + return ApiResult.Ok(); } } diff --git a/OwnChar.Server/Api/Endpoint/UsersApi.cs b/OwnChar.Server/Api/Endpoint/UsersApi.cs index f0167bb..aef2d6d 100644 --- a/OwnChar.Server/Api/Endpoint/UsersApi.cs +++ b/OwnChar.Server/Api/Endpoint/UsersApi.cs @@ -1,6 +1,6 @@ namespace OwnChar.Server.Api.Endpoint; -internal class UsersApi(IServer server) : IApiEndpoint +internal class UsersApi(IOwnCharServer server) : IApiEndpoint { public void Initialize(IApiBuilder builder) { diff --git a/OwnChar.Server/Api/IServer.cs b/OwnChar.Server/Api/IOwnCharServer.cs similarity index 91% rename from OwnChar.Server/Api/IServer.cs rename to OwnChar.Server/Api/IOwnCharServer.cs index 8c64d5e..b4a2a94 100644 --- a/OwnChar.Server/Api/IServer.cs +++ b/OwnChar.Server/Api/IOwnCharServer.cs @@ -6,7 +6,7 @@ using System.Diagnostics.CodeAnalysis; namespace OwnChar.Server.Api; -public interface IServer : IApiServer +public interface IOwnCharServer : IApiServer { ISettings Settings { get; } DbContext? Data { get; } diff --git a/OwnChar.Server/Api/Plugins/ApiEndpointFeature.cs b/OwnChar.Server/Api/Plugins/ApiEndpointFeature.cs index e4a770c..d547cdb 100644 --- a/OwnChar.Server/Api/Plugins/ApiEndpointFeature.cs +++ b/OwnChar.Server/Api/Plugins/ApiEndpointFeature.cs @@ -1,5 +1,4 @@ -using OwnChar.Server.Api.Endpoint; -using Pilz.Plugins.Advanced; +using Pilz.Plugins.Advanced; namespace OwnChar.Server.Api.Plugins; @@ -7,5 +6,5 @@ public abstract class ApiEndpointFeature(string identifier) : PluginFeature(Feat { public static string FeatureType => "ownchar.server.apiep"; - public abstract void OnServerInit(IServer init); + public abstract void OnServerInit(IOwnCharServer init); } diff --git a/OwnChar.Server/Api/Plugins/OwnCharServerPluginInitParams.cs b/OwnChar.Server/Api/Plugins/OwnCharServerPluginInitParams.cs index 72df5ad..a13e0c7 100644 --- a/OwnChar.Server/Api/Plugins/OwnCharServerPluginInitParams.cs +++ b/OwnChar.Server/Api/Plugins/OwnCharServerPluginInitParams.cs @@ -3,7 +3,7 @@ using OwnChar.Server.Api; namespace OwnChar.Server.Api.Plugins; -public class OwnCharServerPluginInitParams(IServer server) : OwnCharPluginInitParams +public class OwnCharServerPluginInitParams(IOwnCharServer server) : OwnCharPluginInitParams { - public IServer Server { get; } = server; + public IOwnCharServer Server { get; } = server; } diff --git a/OwnChar.Server/Extensions/GeneralExtensions.cs b/OwnChar.Server/Extensions/GeneralExtensions.cs index 4aabbe7..1947498 100644 --- a/OwnChar.Server/Extensions/GeneralExtensions.cs +++ b/OwnChar.Server/Extensions/GeneralExtensions.cs @@ -3,31 +3,40 @@ using OwnChar.Data; using OwnChar.Data.Model.Base; using OwnChar.Server.Api; using OwnChar.Server.Data.Model; +using Pilz.Net.Api; using System.Diagnostics.CodeAnalysis; namespace OwnChar.Server.Extensions; public static class GeneralExtensions { - public static bool CheckLogin(this IServer server, OwnCharRequest request, UserType userType) + public static bool CheckLogin(this IOwnCharServer server, ApiRequestInfo request, UserType userType) { if (server.Data is null - || string.IsNullOrWhiteSpace(request.Username) - || string.IsNullOrWhiteSpace(request.AuthSecret) - || !server.IsLoggedIn(request.AuthSecret) - || server.GetUser(request.AuthSecret) is not UserAccountBase usr + || !request.IsAuthenticated + || request.AuthKey.Split(":") is not string[] authKey + || authKey.ElementAtOrDefault(0) is not string username + || authKey.ElementAtOrDefault(1) is not string secret + || string.IsNullOrWhiteSpace(username) + || string.IsNullOrWhiteSpace(secret) + || !server.IsLoggedIn(secret) + || server.GetUser(secret) is not UserAccountBase usr || usr.Type < userType) return false; return true; } - public static bool CheckLogin(this IServer server, OwnCharRequest request, UserType userType, [NotNullWhen(true)] out UserAccountDb? user) + public static bool CheckLogin(this IOwnCharServer server, ApiRequestInfo request, UserType userType, [NotNullWhen(true)] out UserAccountDb? user) { if (server.Data is null - || string.IsNullOrWhiteSpace(request.Username) - || string.IsNullOrWhiteSpace(request.AuthSecret) - || !server.IsLoggedIn(request.AuthSecret) - || server.GetUser(request.AuthSecret) is not UserAccountDb usr + || !request.IsAuthenticated + || request.AuthKey.Split(":") is not string[] authKey + || authKey.ElementAtOrDefault(0) is not string username + || authKey.ElementAtOrDefault(1) is not string secret + || string.IsNullOrWhiteSpace(username) + || string.IsNullOrWhiteSpace(secret) + || !server.IsLoggedIn(secret) + || server.GetUser(secret) is not UserAccountDb usr || usr.Type < userType) { user = null; diff --git a/OwnChar.Server/ServerContext.cs b/OwnChar.Server/ServerContext.cs index 9cf8e0f..ef3715f 100644 --- a/OwnChar.Server/ServerContext.cs +++ b/OwnChar.Server/ServerContext.cs @@ -12,7 +12,7 @@ using Pilz.Plugins.Advanced; namespace OwnChar.Server; -internal class ServerContext(ISettings settings) : ApiServer(settings.Get().ApiUrl!), IServer +internal class ServerContext(ISettings settings) : ApiServer(settings.Get().ApiUrl!), IOwnCharServer { private readonly Dictionary users = []; @@ -47,12 +47,19 @@ internal class ServerContext(ISettings settings) : ApiServer(settings.Get