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
{
2024-10-14 03:20:44 +02:00
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
}