DotBased/DotBased.ASP.Auth/AuthDataCache.cs

98 lines
3.9 KiB
C#
Raw Normal View History

2024-09-27 02:38:18 +02:00
using System.Collections.ObjectModel;
using DotBased.ASP.Auth.Domains.Auth;
2024-11-04 15:45:38 +01:00
using Microsoft.AspNetCore.Components.Authorization;
2024-09-27 02:38:18 +02:00
namespace DotBased.ASP.Auth;
public class AuthDataCache
{
public AuthDataCache(BasedAuthConfiguration configuration)
2024-09-27 02:38:18 +02:00
{
_configuration = configuration;
}
private readonly BasedAuthConfiguration _configuration;
2024-11-04 15:45:38 +01:00
private readonly AuthStateCacheCollection<AuthenticationStateModel, AuthenticationState> _authenticationStateCollection = [];
2024-09-27 02:38:18 +02:00
2024-11-02 01:57:25 +01:00
public Result PurgeSessionState(string id) => _authenticationStateCollection.Remove(id) ? Result.Ok() : Result.Failed("Failed to purge session state from cache! Or the session was not cached...");
2024-09-27 02:38:18 +02:00
2024-11-04 15:45:38 +01:00
public void CacheSessionState(AuthenticationStateModel stateModel, AuthenticationState? state = null) => _authenticationStateCollection[stateModel.Id] =
new AuthStateCacheNode<AuthenticationStateModel, AuthenticationState>(stateModel, state);
2024-11-02 01:57:25 +01:00
2024-11-04 15:45:38 +01:00
public Result<Tuple<AuthenticationStateModel, AuthenticationState?>> RequestSessionState(string id)
2024-09-27 02:38:18 +02:00
{
2024-11-02 01:57:25 +01:00
if (!_authenticationStateCollection.TryGetValue(id, out var node))
2024-11-04 15:45:38 +01:00
return Result<Tuple<AuthenticationStateModel, AuthenticationState?>>.Failed("No cached object found!");
2024-11-02 01:57:25 +01:00
string failedMsg;
2024-11-04 15:45:38 +01:00
if (node.StateModel != null)
2024-09-27 02:38:18 +02:00
{
if (node.IsValidLifespan(_configuration.CachedAuthSessionLifespan))
2024-11-04 15:45:38 +01:00
return Result<Tuple<AuthenticationStateModel, AuthenticationState?>>.Ok(new Tuple<AuthenticationStateModel, AuthenticationState?>(node.StateModel, node.State));
2024-11-02 01:57:25 +01:00
failedMsg = $"Session has invalid lifespan, removing entry: [{id}] from cache!";
2024-09-27 02:38:18 +02:00
}
else
2024-11-02 01:57:25 +01:00
failedMsg = $"Returned object is null, removing entry: [{id}] from cache!";
_authenticationStateCollection.Remove(id);
2024-11-04 15:45:38 +01:00
return Result<Tuple<AuthenticationStateModel, AuthenticationState?>>.Failed(failedMsg);
2024-09-27 02:38:18 +02:00
}
}
2024-11-04 15:45:38 +01:00
public class AuthStateCacheNode<TStateModel, TState> where TStateModel : class where TState : class
2024-09-27 02:38:18 +02:00
{
2024-11-04 15:45:38 +01:00
public AuthStateCacheNode(TStateModel stateModel, TState? state)
2024-09-27 02:38:18 +02:00
{
2024-11-04 15:45:38 +01:00
StateModel = stateModel;
State = state;
2024-09-27 02:38:18 +02:00
}
2024-11-04 15:45:38 +01:00
public TStateModel? StateModel { get; private set; }
public TState? State { get; private set; }
2024-09-27 02:38:18 +02:00
public DateTime DateCached { get; private set; } = DateTime.Now;
2024-11-04 15:45:38 +01:00
public void UpdateObject(TStateModel obj)
2024-09-27 02:38:18 +02:00
{
2024-11-04 15:45:38 +01:00
StateModel = obj;
2024-09-27 02:38:18 +02:00
DateCached = DateTime.Now;
}
/// <summary>
/// Checks if the cached object is within the given lifespan.
/// </summary>
/// <param name="lifespan">The max. lifespan</param>
2024-11-04 15:45:38 +01:00
public bool IsValidLifespan(TimeSpan lifespan) => DateCached.Add(lifespan) > DateTime.Now;
2024-09-27 02:38:18 +02:00
public override bool Equals(object? obj)
{
2024-11-04 15:45:38 +01:00
if (obj is AuthStateCacheNode<TStateModel, TState> cacheObj)
return StateModel != null && StateModel.Equals(cacheObj.StateModel);
2024-09-27 02:38:18 +02:00
return false;
}
2024-11-04 15:45:38 +01:00
public override int GetHashCode() => typeof(TStateModel).GetHashCode();
public override string ToString() => typeof(TStateModel).ToString();
2024-09-27 02:38:18 +02:00
}
2024-11-04 15:45:38 +01:00
public class AuthStateCacheCollection<TStateModel, TState> : KeyedCollection<string, AuthStateCacheNode<TStateModel, TState>> where TStateModel : class where TState : class
2024-09-27 02:38:18 +02:00
{
2024-11-04 15:45:38 +01:00
protected override string GetKeyForItem(AuthStateCacheNode<TStateModel, TState> item) => item.StateModel?.ToString() ?? string.Empty;
2024-11-02 01:57:25 +01:00
2024-11-04 15:45:38 +01:00
public new AuthStateCacheNode<TStateModel, TState>? this[string id]
2024-11-02 01:57:25 +01:00
{
2024-11-04 15:45:38 +01:00
get => TryGetValue(id, out AuthStateCacheNode<TStateModel, TState>? nodeValue) ? nodeValue : null;
2024-11-02 01:57:25 +01:00
set
{
if (value == null)
return;
2024-11-04 15:45:38 +01:00
if (TryGetValue(id, out AuthStateCacheNode<TStateModel, TState>? nodeValue))
2024-11-02 01:57:25 +01:00
Remove(nodeValue);
Add(value);
}
}
2024-11-04 15:45:38 +01:00
public void Insert(AuthStateCacheNode<TStateModel, TState> node)
2024-11-02 01:57:25 +01:00
{
if (Contains(node))
Remove(node);
Add(node);
}
2024-09-27 02:38:18 +02:00
}