up
Some checks failed
Build Test Deploy / build-test (push) Has been cancelled
Build Test Deploy / authority-container (push) Has been cancelled
Build Test Deploy / docs (push) Has been cancelled
Build Test Deploy / deploy (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Build Test Deploy / build-test (push) Has been cancelled
Build Test Deploy / authority-container (push) Has been cancelled
Build Test Deploy / docs (push) Has been cancelled
Build Test Deploy / deploy (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../../../__Libraries/Ablera.Serdica.Plugin/Ablera.Serdica.Plugin.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Ablera.Serdica.Authority.Plugins.Base.Constants;
|
||||
|
||||
public static class ConstantsClass
|
||||
{
|
||||
public const string YesKey = "Y";
|
||||
public const string NoKey = "N";
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Ablera.Serdica.Authority.Plugins.Base.Models;
|
||||
|
||||
namespace Ablera.Serdica.Authority.Plugins.Base.Contracts;
|
||||
|
||||
public interface IAccountLockManager<TUser>
|
||||
where TUser : class
|
||||
{
|
||||
Task<OperationResult> LockAsync(TUser user, CancellationToken ct = default);
|
||||
Task<OperationResult> UnlockAsync(TUser user, CancellationToken ct = default);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Ablera.Serdica.Authority.Plugins.Base.Models;
|
||||
|
||||
namespace Ablera.Serdica.Authority.Plugins.Base.Contracts;
|
||||
|
||||
public interface IAuthService<TUser>
|
||||
where TUser : class
|
||||
{
|
||||
/// <summary>
|
||||
/// Authenticates a user given a login identifier (email/username) and password.
|
||||
/// </summary>
|
||||
Task<AuthenticationResult> AuthenticateAsync(TUser user, string password, bool lockoutOnFailure = false, CancellationToken ct = default);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace Ablera.Serdica.Authority.Plugins.Base.Contracts;
|
||||
|
||||
public interface IClaimStore<TUser>
|
||||
where TUser : class
|
||||
{
|
||||
Task<IReadOnlyCollection<Claim>> GetBaseClaimsAsync(TUser user, CancellationToken ct = default);
|
||||
Task<IReadOnlyCollection<Claim>?> GetRolesClaimsAsync(TUser user, CancellationToken ct = default);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Ablera.Serdica.Authority.Plugins.Base.Models;
|
||||
|
||||
namespace Ablera.Serdica.Authority.Plugins.Base.Contracts;
|
||||
|
||||
public interface IPasswordManager<TUser>
|
||||
where TUser : class
|
||||
{
|
||||
Task<OperationResult> ChangePasswordAsync(TUser user, string currentPassword, string newPassword, CancellationToken ct = default);
|
||||
Task<OperationResult> ResetPasswordAsync(TUser user, string resetToken, string newPassword, CancellationToken ct = default);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Ablera.Serdica.Authority.Plugins.Base.Contracts;
|
||||
|
||||
/*===========================================================*/
|
||||
/* Facade for legacy code that expects a single user manager */
|
||||
/*===========================================================*/
|
||||
|
||||
public interface IUserManagementFacade<TUser> :
|
||||
IUserRepository<TUser>,
|
||||
IPasswordManager<TUser>,
|
||||
IClaimStore<TUser>,
|
||||
IAccountLockManager<TUser>,
|
||||
IAuthService<TUser>
|
||||
where TUser : class
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Ablera.Serdica.Authority.Plugins.Base.Models;
|
||||
|
||||
namespace Ablera.Serdica.Authority.Plugins.Base.Contracts;
|
||||
|
||||
/*====================================================================*/
|
||||
/* Core, storage‑agnostic responsibilities are split across focused */
|
||||
/* contracts. Implementations can cherry‑pick or aggregate as needed */
|
||||
/*====================================================================*/
|
||||
|
||||
public interface IUserRepository<TUser>
|
||||
where TUser : class
|
||||
{
|
||||
Task<OperationResult> CreateAsync(TUser user, string password, CancellationToken ct = default);
|
||||
Task<OperationResult> UpdateAsync(TUser user, CancellationToken ct = default);
|
||||
Task<TUser?> FindByIdAsync(string id, CancellationToken ct = default);
|
||||
Task<TUser?> FindByEmailAsync(string email, CancellationToken ct = default);
|
||||
Task<TUser?> FindByNameAsync(string username, CancellationToken ct = default);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace Ablera.Serdica.Authority.Plugins.Base.Models;
|
||||
|
||||
public enum AuthenticationCode
|
||||
{
|
||||
GenericError,
|
||||
AccountIsNotFound,
|
||||
AccountIsLocked,
|
||||
AccountIsNotActive,
|
||||
EmptyCredentials,
|
||||
InvalidPassword,
|
||||
NoAuthBackend,
|
||||
ClientIsUnknown,
|
||||
ClientWithNoSecretDoesNotMatchAllowedMask,
|
||||
ClientSecretIsInvalid,
|
||||
InvalidCredentials,
|
||||
AccountIsNotAuthenticaAble
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Result of an authentication attempt. Use the static helpers for convenience.
|
||||
/// </summary>
|
||||
public sealed class AuthenticationResult
|
||||
{
|
||||
private AuthenticationResult(bool succeeded, string? errorCode, ClaimsPrincipal? claimsPrincipal)
|
||||
{
|
||||
Succeeded = succeeded;
|
||||
ErrorCode = errorCode;
|
||||
ClaimsPrincipal = claimsPrincipal;
|
||||
}
|
||||
|
||||
public bool Succeeded { get; }
|
||||
public string? ErrorCode { get; }
|
||||
public ClaimsPrincipal? ClaimsPrincipal { get; }
|
||||
|
||||
public static AuthenticationResult Success(ClaimsPrincipal? claimsPrincipal) =>
|
||||
new AuthenticationResult(true, null, claimsPrincipal);
|
||||
|
||||
public static AuthenticationResult Fail(string errorCode) =>
|
||||
new AuthenticationResult(false, errorCode, null);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace Ablera.Serdica.Authority.Plugins.Base.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Generic result wrapper for write operations that need more detail than a boolean.
|
||||
/// </summary>
|
||||
public sealed class OperationResult
|
||||
{
|
||||
private OperationResult(bool succeeded, string? errorCode)
|
||||
{
|
||||
Succeeded = succeeded;
|
||||
ErrorCode = errorCode;
|
||||
}
|
||||
|
||||
public bool Succeeded { get; }
|
||||
public string? ErrorCode { get; }
|
||||
|
||||
public static OperationResult Success() => new OperationResult(true, null);
|
||||
public static OperationResult Fail(string errorCode) => new OperationResult(false, errorCode);
|
||||
}
|
||||
Reference in New Issue
Block a user