56 lines
1.7 KiB
C#
56 lines
1.7 KiB
C#
using System.Collections;
|
|
using System.Collections.Concurrent;
|
|
using Femto.Modules.Auth.Models;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
|
|
namespace Femto.Modules.Auth.Infrastructure;
|
|
|
|
internal class SessionStorage(TimeProvider timeProvider)
|
|
{
|
|
private readonly IMemoryCache _storage = new MemoryCache(new MemoryCacheOptions());
|
|
|
|
public async Task<Session?> GetSession(string id)
|
|
{
|
|
var session = this._storage.Get<Session>($"session:{id}");
|
|
|
|
if (session is null)
|
|
return null;
|
|
|
|
var invalidUntil = this._storage.Get<DateTimeOffset?>(
|
|
$"user:invalid_until:{session.UserId}"
|
|
);
|
|
|
|
if (invalidUntil is not null && invalidUntil > session.Expires)
|
|
return null;
|
|
|
|
return session;
|
|
}
|
|
|
|
public Task AddSession(Session session)
|
|
{
|
|
using var sessionEntry = this._storage.CreateEntry($"session:{session.Id}");
|
|
sessionEntry.Value = session;
|
|
sessionEntry.SetAbsoluteExpiration(session.Expires);
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task DeleteSession(string id)
|
|
{
|
|
this._storage.Remove($"session:{id}");
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task InvalidateUserSessions(Guid userId)
|
|
{
|
|
var invalidUntil = timeProvider.GetUtcNow() + Session.ValidityPeriod;
|
|
|
|
// invalidate sessions who are currently valid
|
|
// any sessions created after this will have a validity period that extends past invalid_until
|
|
// this cache entry doesn't need to live longer than that point in time
|
|
this._storage.Set($"user:invalid_until:{userId}", invalidUntil, invalidUntil);
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|