mirror of
https://github.com/chylex/Minecraft-Phantom-Panel.git
synced 2025-05-28 07:34:06 +02:00
64 lines
2.0 KiB
C#
64 lines
2.0 KiB
C#
using System.Collections.Concurrent;
|
|
using System.Diagnostics;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Phantom.Common.Logging;
|
|
using Phantom.Utils.Tasks;
|
|
using ILogger = Serilog.ILogger;
|
|
|
|
namespace Phantom.Server.Web.Identity.Authentication;
|
|
|
|
public sealed class PhantomLoginStore {
|
|
private static readonly ILogger Logger = PhantomLogger.Create<PhantomLoginStore>();
|
|
private static readonly TimeSpan ExpirationTime = TimeSpan.FromMinutes(1);
|
|
|
|
internal static Func<IServiceProvider, PhantomLoginStore> Create(CancellationToken cancellationToken) {
|
|
return provider => new PhantomLoginStore(provider.GetRequiredService<TaskManager>(), cancellationToken);
|
|
}
|
|
|
|
private readonly ConcurrentDictionary<string, LoginEntry> loginEntries = new ();
|
|
private readonly CancellationToken cancellationToken;
|
|
|
|
private PhantomLoginStore(TaskManager taskManager, CancellationToken cancellationToken) {
|
|
this.cancellationToken = cancellationToken;
|
|
taskManager.Run("Web login entry expiration loop", RunExpirationLoop);
|
|
}
|
|
|
|
private async Task RunExpirationLoop() {
|
|
try {
|
|
while (true) {
|
|
await Task.Delay(ExpirationTime, cancellationToken);
|
|
|
|
foreach (var (token, entry) in loginEntries) {
|
|
if (entry.IsExpired) {
|
|
Logger.Debug("Expired login entry for {Username}.", entry.User.UserName);
|
|
loginEntries.TryRemove(token, out _);
|
|
}
|
|
}
|
|
}
|
|
} finally {
|
|
Logger.Information("Expiration loop stopped.");
|
|
}
|
|
}
|
|
|
|
internal void Add(string token, IdentityUser user, string password, string returnUrl) {
|
|
loginEntries[token] = new LoginEntry(user, password, returnUrl, Stopwatch.StartNew());
|
|
}
|
|
|
|
internal LoginEntry? Pop(string token) {
|
|
if (!loginEntries.TryRemove(token, out var entry)) {
|
|
return null;
|
|
}
|
|
|
|
if (entry.IsExpired) {
|
|
Logger.Debug("Expired login entry for {Username}.", entry.User.UserName);
|
|
return null;
|
|
}
|
|
|
|
return entry;
|
|
}
|
|
|
|
internal sealed record LoginEntry(IdentityUser User, string Password, string ReturnUrl, Stopwatch AddedTime) {
|
|
public bool IsExpired => AddedTime.Elapsed >= ExpirationTime;
|
|
}
|
|
}
|