1
0
mirror of https://github.com/chylex/Minecraft-Phantom-Panel.git synced 2025-04-28 01:15:47 +02:00
Minecraft-Phantom-Panel/Controller/Phantom.Controller.Services/Users/UserLoginManager.cs

65 lines
2.1 KiB
C#

using System.Collections.Concurrent;
using System.Collections.Immutable;
using System.Security.Cryptography;
using Phantom.Common.Data.Web.Users;
using Phantom.Controller.Database;
using Phantom.Controller.Database.Repositories;
namespace Phantom.Controller.Services.Users;
sealed class UserLoginManager {
private const int SessionIdBytes = 20;
private readonly ConcurrentDictionary<Guid, List<ImmutableArray<byte>>> sessionTokensByUserGuid = new ();
private readonly UserManager userManager;
private readonly PermissionManager permissionManager;
private readonly IDbContextProvider dbProvider;
public UserLoginManager(UserManager userManager, PermissionManager permissionManager, IDbContextProvider dbProvider) {
this.userManager = userManager;
this.permissionManager = permissionManager;
this.dbProvider = dbProvider;
}
public async Task<LogInSuccess?> LogIn(string username, string password) {
var user = await userManager.GetAuthenticated(username, password);
if (user == null) {
return null;
}
var token = ImmutableArray.Create(RandomNumberGenerator.GetBytes(SessionIdBytes));
var sessionTokens = sessionTokensByUserGuid.GetOrAdd(user.UserGuid, static _ => new List<ImmutableArray<byte>>());
lock (sessionTokens) {
sessionTokens.Add(token);
}
await using (var db = dbProvider.Lazy()) {
var auditLogWriter = new AuditLogRepository(db).Writer(user.UserGuid);
auditLogWriter.UserLoggedIn(user);
await db.Ctx.SaveChangesAsync();
}
return new LogInSuccess(user.UserGuid, await permissionManager.FetchPermissionsForUserId(user.UserGuid), token);
}
public async Task LogOut(Guid userGuid, ImmutableArray<byte> sessionToken) {
if (!sessionTokensByUserGuid.TryGetValue(userGuid, out var sessionTokens)) {
return;
}
lock (sessionTokens) {
if (sessionTokens.RemoveAll(token => token.SequenceEqual(sessionToken)) == 0) {
return;
}
}
await using var db = dbProvider.Lazy();
var auditLogWriter = new AuditLogRepository(db).Writer(userGuid);
auditLogWriter.UserLoggedOut(userGuid);
await db.Ctx.SaveChangesAsync();
}
}