mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-22 12:37:24 +01:00
@@ -357,7 +357,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
var identExpiry = token.ParseJwt().ValidTo;
|
||||
identExpiry += tokenFactory.ValidationParameters.ClockSkew;
|
||||
identExpiry += TimeSpan.FromSeconds(15);
|
||||
identityCache.CacheSystemIdentity(user, systemIdentity!, identExpiry);
|
||||
await identityCache.CacheSystemIdentity(user, systemIdentity!, identExpiry);
|
||||
}
|
||||
|
||||
Logger.LogDebug("Successfully logged in user {userId}!", user.Id);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Tgstation.Server.Host.Models;
|
||||
|
||||
@@ -15,7 +16,8 @@ namespace Tgstation.Server.Host.Security
|
||||
/// <param name="user">The <see cref="User"/> the <paramref name="systemIdentity"/> belongs to.</param>
|
||||
/// <param name="systemIdentity">The <see cref="ISystemIdentity"/> to cache.</param>
|
||||
/// <param name="expiry">When the <paramref name="systemIdentity"/> should expire.</param>
|
||||
void CacheSystemIdentity(User user, ISystemIdentity systemIdentity, DateTimeOffset expiry);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask CacheSystemIdentity(User user, ISystemIdentity systemIdentity, DateTimeOffset expiry);
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to load a cached <see cref="ISystemIdentity"/>.
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using Tgstation.Server.Common.Extensions;
|
||||
using Tgstation.Server.Host.Models;
|
||||
using Tgstation.Server.Host.Utils;
|
||||
|
||||
namespace Tgstation.Server.Host.Security
|
||||
{
|
||||
/// <inheritdoc cref="IIdentityCache" />
|
||||
sealed class IdentityCache : IIdentityCache, IDisposable
|
||||
sealed class IdentityCache : IIdentityCache, IAsyncDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IAsyncDelayer"/> for the <see cref="IdentityCache"/>.
|
||||
@@ -41,15 +43,14 @@ namespace Tgstation.Server.Host.Security
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
public ValueTask DisposeAsync()
|
||||
{
|
||||
logger.LogTrace("Disposing...");
|
||||
foreach (var cachedIdentity in cachedIdentities.Select(x => x.Value).ToList())
|
||||
cachedIdentity.Dispose();
|
||||
return ValueTaskExtensions.WhenAll(cachedIdentities.Select(x => x.Value.DisposeAsync()));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void CacheSystemIdentity(User user, ISystemIdentity systemIdentity, DateTimeOffset expiry)
|
||||
public async ValueTask CacheSystemIdentity(User user, ISystemIdentity systemIdentity, DateTimeOffset expiry)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(user);
|
||||
ArgumentNullException.ThrowIfNull(systemIdentity);
|
||||
@@ -57,27 +58,35 @@ namespace Tgstation.Server.Host.Security
|
||||
var uid = user.Require(x => x.Id);
|
||||
var sysId = systemIdentity.Uid;
|
||||
|
||||
lock (cachedIdentities)
|
||||
ValueTask oldIdentityDisposal = ValueTask.CompletedTask;
|
||||
try
|
||||
{
|
||||
logger.LogDebug("Caching system identity {sysId} of user {uid}", sysId, uid);
|
||||
|
||||
if (cachedIdentities.TryGetValue(uid, out var identCache))
|
||||
lock (cachedIdentities)
|
||||
{
|
||||
logger.LogTrace("Expiring previously cached identity...");
|
||||
identCache.Dispose(); // also clears it out
|
||||
}
|
||||
logger.LogDebug("Caching system identity {sysId} of user {uid}", sysId, uid);
|
||||
|
||||
identCache = new IdentityCacheObject(
|
||||
systemIdentity.Clone(),
|
||||
asyncDelayer,
|
||||
() =>
|
||||
if (cachedIdentities.TryGetValue(uid, out var identCache))
|
||||
{
|
||||
logger.LogDebug("Expiring system identity cache for user {uid}", uid);
|
||||
lock (cachedIdentities)
|
||||
cachedIdentities.Remove(uid);
|
||||
},
|
||||
expiry);
|
||||
cachedIdentities.Add(uid, identCache);
|
||||
logger.LogTrace("Expiring previously cached identity...");
|
||||
oldIdentityDisposal = identCache.DisposeAsync(); // also clears it out
|
||||
}
|
||||
|
||||
identCache = new IdentityCacheObject(
|
||||
systemIdentity.Clone(),
|
||||
asyncDelayer,
|
||||
() =>
|
||||
{
|
||||
logger.LogDebug("Expiring system identity cache for user {uid}", uid);
|
||||
lock (cachedIdentities)
|
||||
cachedIdentities.Remove(uid);
|
||||
},
|
||||
expiry);
|
||||
cachedIdentities.Add(uid, identCache);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
await oldIdentityDisposal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Tgstation.Server.Host.Security
|
||||
/// <summary>
|
||||
/// For keeping a specific <see cref="ISystemIdentity"/> alive for a period of time.
|
||||
/// </summary>
|
||||
sealed class IdentityCacheObject : IDisposable
|
||||
sealed class IdentityCacheObject : IAsyncDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="ISystemIdentity"/> the <see cref="IdentityCache"/> manages.
|
||||
@@ -53,6 +53,9 @@ namespace Tgstation.Server.Host.Security
|
||||
{
|
||||
await asyncDelayer.Delay(expiry - now, cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
onExpiry();
|
||||
@@ -63,18 +66,11 @@ namespace Tgstation.Server.Host.Security
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
cancellationTokenSource.Cancel();
|
||||
try
|
||||
{
|
||||
task.GetAwaiter().GetResult();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
|
||||
cancellationTokenSource.Dispose();
|
||||
await task;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user