1
0
mirror of https://github.com/chylex/Minecraft-Phantom-Panel.git synced 2025-08-16 21:31:45 +02:00
Files
.config
.run
.workdir
Agent
Common
Docker
Server
Phantom.Server
Phantom.Server.Database
Phantom.Server.Database.Postgres
Phantom.Server.Minecraft
Phantom.Server.Rpc
Phantom.Server.Services
Phantom.Server.Web
Phantom.Server.Web.Bootstrap
Phantom.Server.Web.Components
Phantom.Server.Web.Identity
Authentication
PhantomLoginManager.cs
PhantomLoginStore.cs
RevalidatingIdentityAuthenticationStateProvider.cs
Authorization
Data
Interfaces
Phantom.Server.Web.Identity.csproj
PhantomIdentityConfigurator.cs
PhantomIdentityExtensions.cs
PhantomIdentityMiddleware.cs
Utils
.dockerignore
.gitattributes
.gitignore
AddMigration.bat
AddMigration.sh
Directory.Build.props
Directory.Build.targets
Dockerfile
LICENSE
Packages.props
PhantomPanel.sln
README.md
global.json
Minecraft-Phantom-Panel/Server/Phantom.Server.Web.Identity/Authentication/PhantomLoginStore.cs
2023-04-07 01:33:13 +02:00

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;
}
}