Compare commits

...

1 Commits

Author SHA1 Message Date
Schedel Pascal
f268058cdc finish migration to Pilz.NET 2024-08-23 11:18:50 +02:00
21 changed files with 127 additions and 119 deletions

View File

@@ -1,5 +1,5 @@
namespace OwnChar.Api.Clients;
public class CharactersApiClient(OwnCharApiClient client)
internal class CharactersApiClient(OwnCharApiClient client) : ICharactersApiClient
{
}

View File

@@ -4,40 +4,40 @@ using OwnChar.Data.Model.Client;
namespace OwnChar.Api.Clients;
public class GroupsApiClient(OwnCharApiClient client)
internal class GroupsApiClient(IOwnCharApiClient client) : IGroupsApiClient
{
public async Task<Group?> GetGroup(long id)
{
var result = await client.MakeRequest<GetSinlgeObjectRequest, GetSingleObjectResponse<Group>>("/groups/get/byid", new(id));
result.EnsureSuccess();
return result.Result;
var result = await client.SendRequest<GetSingleObjectResponse<Group>>("/groups/get/byid", new GetSinlgeObjectRequest(id));
result.EnsureOk();
return result.Message.Result;
}
public async Task<IEnumerable<Group>> GetGroupsForProfile(long userProfileId)
{
var result = await client.MakeRequest<GetGroupsRequest, GetGroupsResponse>("/groups/get", new()
var result = await client.SendRequest<GetGroupsResponse>("/groups/get", new GetGroupsRequest
{
ProfileId = userProfileId,
UseProfileId = true,
});
result.EnsureSuccess();
return result.Groups;
result.EnsureOk();
return result.Message.Groups;
}
public async Task<IEnumerable<Group>> GetPublicGroups()
{
var result = await client.MakeRequest<GetGroupsRequest, GetGroupsResponse>("/groups/get", new());
result.EnsureSuccess();
return result.Groups;
var result = await client.SendRequest<GetGroupsResponse>("/groups/get", new GetGroupsRequest());
result.EnsureOk();
return result.Message.Groups;
}
public async Task<IEnumerable<Group>> GetAllGroups()
{
var result = await client.MakeRequest<GetGroupsRequest, GetGroupsResponse>("/groups/get", new()
var result = await client.SendRequest<GetGroupsResponse>("/groups/get", new GetGroupsRequest
{
IncludeNonPublic = true,
});
result.EnsureSuccess();
return result.Groups;
result.EnsureOk();
return result.Message.Groups;
}
}

View File

@@ -0,0 +1,5 @@
namespace OwnChar.Api.Clients;
public interface ICharactersApiClient
{
}

View File

@@ -0,0 +1,10 @@
using OwnChar.Data.Model.Client;
namespace OwnChar.Api.Clients;
public interface IGroupsApiClient
{
Task<IEnumerable<Group>> GetAllGroups();
Task<Group?> GetGroup(long id);
Task<IEnumerable<Group>> GetGroupsForProfile(long userProfileId);
Task<IEnumerable<Group>> GetPublicGroups();
}

View File

@@ -0,0 +1,9 @@
using OwnChar.Data.Model.Client;
using Pilz.Cryptography;
namespace OwnChar.Api.Clients;
public interface ILoginApiClient
{
Task<UserProfile?> Login(string username, SecureString password);
Task<bool> Logout();
}

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OwnChar.Api.Clients;
public interface IUsersApiClient
{
}

View File

@@ -1,20 +1,21 @@
using OwnChar.Api.Packets;
using OwnChar.Api.Packets.General;
using OwnChar.Api.Packets.General;
using OwnChar.Data.Model.Client;
using Pilz.Cryptography;
namespace OwnChar.Api.Clients;
public class LoginApiClient(OwnCharApiClient client)
internal class LoginApiClient(OwnCharApiClient client) : ILoginApiClient
{
public async Task<UserProfile?> Login(string username, SecureString password)
{
var result = await client.MakeRequest<LoginRequest, LoginResponse>("/auth/login", new(username, password));
var result = await client.SendRequest<LoginResponse>("/auth/login", new LoginRequest(username, password));
result.EnsureOk();
if (!string.IsNullOrEmpty(result.Secret) && result.Profile != null && result.Account != null)
if (!string.IsNullOrEmpty(result.Message.Secret) && result.Message.Profile != null && result.Message.Account != null)
{
client.AuthSecret = result.Secret;
return result.Profile;
client.AuthKey = result.Message.Secret;
client.CurrentUser = result.Message.Account;
return result.Message.Profile;
}
return null;
@@ -22,8 +23,8 @@ public class LoginApiClient(OwnCharApiClient client)
public async Task<bool> Logout()
{
await client.MakeRequest<LogoutRequest, OwnCharResponse>("/auth/logout", new());
client.AuthSecret = null;
return true;
var res = await client.SendRequest("/auth/logout");
client.AuthKey = null;
return res.IsOk;
}
}

View File

@@ -1,5 +1,5 @@
namespace OwnChar.Api.Clients;
public class UsersApiClient(OwnCharApiClient client)
internal class UsersApiClient(IOwnCharApiClient client) : IUsersApiClient
{
}

View File

@@ -0,0 +1,21 @@
using OwnChar.Api.Clients;
using OwnChar.Data.Model.Client;
using Pilz.Net.Api;
using System.Diagnostics.CodeAnalysis;
namespace OwnChar.Api;
public interface IOwnCharApiClient : IApiClient
{
UserAccount? CurrentUser { get; }
[MemberNotNullWhen(true, nameof(AuthKey), nameof(CurrentUser))]
bool IsLoggedIn { get; }
ILoginApiClient Auth { get; }
IGroupsApiClient Groups { get; }
ICharactersApiClient Characters { get; }
IUsersApiClient Users { get; }
}

View File

@@ -1,49 +1,38 @@
using OwnChar.Api.Clients;
using OwnChar.Api.Exceptions;
using OwnChar.Api.Packets;
using OwnChar.Data.Model.Client;
using Pilz.Cryptography;
using Pilz.Net.Api;
using System.Diagnostics.CodeAnalysis;
namespace OwnChar.Api;
public class OwnCharApiClient : ApiClient
internal class OwnCharApiClient : ApiClient, IOwnCharApiClient
{
private readonly Dictionary<Type, object> clients = [];
public UserAccount? CurrentUser { get; internal set; }
internal string? AuthSecret { get; set; } = null;
public bool IsLoggedIn => AuthSecret != null;
[MemberNotNullWhen(true, nameof(AuthKey), nameof(CurrentUser))]
public bool IsLoggedIn => CurrentUser != null && !string.IsNullOrWhiteSpace(AuthKey);
public LoginApiClient Auth { get; }
public UsersApiClient Users { get; }
public CharactersApiClient Characters { get; }
public GroupsApiClient Groups { get; }
public ILoginApiClient Auth { get; }
public IGroupsApiClient Groups { get; }
public ICharactersApiClient Characters { get; }
public IUsersApiClient Users { get; }
public OwnCharApiClient(string apiUrl) : base(apiUrl)
{
Auth = GetClient<LoginApiClient>();
Users = GetClient<UsersApiClient>();
Characters = GetClient<CharactersApiClient>();
Groups = GetClient<GroupsApiClient>();
}
public T GetClient<T>() where T : class
{
var t = typeof(T);
if (clients.TryGetValue(t, out var client) && client is T clientT1)
return clientT1;
if (Activator.CreateInstance(t, this) is T clientT2)
{
clients.Add(t, clientT2);
return clientT2;
}
throw new Exception("Client could not be created!");
Auth = new LoginApiClient(this);
Groups = new GroupsApiClient(this);
Characters = new CharactersApiClient(this);
Users = new UsersApiClient(this);
}
protected override string? EncodeAuthKey()
{
return new SecureString(base.EncodeAuthKey(), false);
if (IsLoggedIn && !string.IsNullOrWhiteSpace(CurrentUser.Username))
return new SecureString($"{CurrentUser}:{AuthKey}", false).EncryptedValue;
return AuthKey;
}
}

View File

@@ -1,7 +0,0 @@
using OwnChar.Api.Packets;
namespace OwnChar.Api.Packets.General;
public class DeleteObjectResponse : OwnCharResponse
{
}

View File

@@ -1,7 +0,0 @@
using OwnChar.Api.Packets;
namespace OwnChar.Api.Packets.General;
public class LogoutRequest : OwnCharRequest
{
}

View File

@@ -1,7 +0,0 @@
using OwnChar.Api.Packets;
namespace OwnChar.Api.Packets.General;
public class LogoutResponse : OwnCharResponse
{
}

View File

@@ -1,5 +0,0 @@
namespace OwnChar.Api.Packets.General;
public class SetOwnerResponse : OwnCharResponse
{
}

View File

@@ -1,7 +0,0 @@
using OwnChar.Api.Packets;
namespace OwnChar.Api.Packets.General;
public class UpdateResponse : OwnCharResponse
{
}

View File

@@ -1,9 +1,7 @@
using Pilz.Cryptography;
using Pilz.Net.Api;
namespace OwnChar.Api.Packets;
public class OwnCharRequest
public class OwnCharRequest : ApiMessage
{
public string? Username { get; set; } = null;
public SecureString? AuthSecret { get; set; } = null;
}

View File

@@ -1,11 +1,7 @@
using System.Text.Json.Serialization;
using Pilz.Net.Api;
namespace OwnChar.Api.Packets;
public class OwnCharResponse
public class OwnCharResponse : ApiMessage
{
public OwnCharResponseError ErrorCode { get; set; }
[JsonIgnore]
public bool IsSuccess => ErrorCode != OwnCharResponseError.None;
}

View File

@@ -1,9 +0,0 @@
namespace OwnChar.Api.Packets;
public enum OwnCharResponseError
{
None,
Default,
NotFound,
StillInUse,
}

View File

@@ -0,0 +1,11 @@
using Pilz.Net.Api;
namespace OwnChar.Extensions;
public static class ApiRequestInfoExtensions
{
public static string? GetUsername(this ApiRequestInfo @this)
{
return @this.AuthKey?.Split(':').ElementAtOrDefault(0);
}
}

View File

@@ -8,17 +8,16 @@ namespace OwnChar;
public interface IOwnCharManager
{
bool IsLoggedIn { get; }
OwnCharApiClient? Api { get; }
IOwnCharApiClient? Api { get; }
IUserManager Users { get; }
IGroupsManager Groups { get; }
ICharacterManager Characters { get; }
Task<UserProfile?> Login(string? username, SecureString? password);
Task<bool> Logout();
public static IOwnCharManager CreateDefault()
{
return new OwnCharManager();
}
Task<bool> Logout();
}

View File

@@ -7,17 +7,17 @@ using System.Diagnostics.CodeAnalysis;
namespace OwnChar;
internal class OwnCharManager : IOwnCharManager
public class OwnCharManager : IOwnCharManager
{
// User
[MemberNotNullWhen(true, nameof(Api))]
public bool IsLoggedIn => Api is not null && Api.IsLoggedIn;
// Data Provider
public OwnCharApiClient? Api { get; private set; }
public IOwnCharApiClient? Api { get; private set; }
// Manager
public IUserManager Users { get; }
public IGroupsManager Groups { get; }
public ICharacterManager Characters { get; }
public OwnCharManager()