ensure that demoted clients are logged out from the webfront
This commit is contained in:
parent
88af032736
commit
a7872aaffd
@ -21,6 +21,7 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static SharedLibraryCore.GameEvent;
|
||||
|
||||
namespace IW4MAdmin.Application
|
||||
{
|
||||
@ -31,8 +32,6 @@ namespace IW4MAdmin.Application
|
||||
public ILogger Logger => GetLogger(0);
|
||||
public bool Running { get; private set; }
|
||||
public bool IsInitialized { get; private set; }
|
||||
// define what the delagate function looks like
|
||||
public delegate void OnServerEventEventHandler(object sender, GameEventArgs e);
|
||||
// expose the event handler so we can execute the events
|
||||
public OnServerEventEventHandler OnServerEvent { get; set; }
|
||||
public DateTime StartTime { get; private set; }
|
||||
@ -53,7 +52,6 @@ namespace IW4MAdmin.Application
|
||||
public BaseConfigurationHandler<ApplicationConfiguration> ConfigHandler;
|
||||
GameEventHandler Handler;
|
||||
readonly IPageList PageList;
|
||||
readonly SemaphoreSlim ProcessingEvent = new SemaphoreSlim(1, 1);
|
||||
readonly Dictionary<long, ILogger> Loggers = new Dictionary<long, ILogger>();
|
||||
private readonly MetaService _metaService;
|
||||
private readonly TimeSpan _throttleTimeout = new TimeSpan(0, 1, 0);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Events;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -7,6 +8,9 @@ namespace SharedLibraryCore
|
||||
{
|
||||
public class GameEvent
|
||||
{
|
||||
// define what the delagate function looks like
|
||||
public delegate void OnServerEventEventHandler(object sender, GameEventArgs e);
|
||||
|
||||
public enum EventFailReason
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -5,6 +5,7 @@ using SharedLibraryCore.Configuration;
|
||||
using System.Reflection;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using System.Threading;
|
||||
using static SharedLibraryCore.GameEvent;
|
||||
|
||||
namespace SharedLibraryCore.Interfaces
|
||||
{
|
||||
@ -43,5 +44,6 @@ namespace SharedLibraryCore.Interfaces
|
||||
string ExternalIPAddress { get; }
|
||||
CancellationToken CancellationToken { get; }
|
||||
bool IsRestartRequested { get; }
|
||||
OnServerEventEventHandler OnServerEvent { get; set; }
|
||||
}
|
||||
}
|
||||
|
91
WebfrontCore/Middleware/ClaimsPermissionRemoval.cs
Normal file
91
WebfrontCore/Middleware/ClaimsPermissionRemoval.cs
Normal file
@ -0,0 +1,91 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using SharedLibraryCore.Events;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using static SharedLibraryCore.Database.Models.EFClient;
|
||||
using static SharedLibraryCore.GameEvent;
|
||||
|
||||
namespace WebfrontCore.Middleware
|
||||
{
|
||||
/// <summary>
|
||||
/// Facilitates the removal of identity claims when client is demoted
|
||||
/// </summary>
|
||||
internal class ClaimsPermissionRemoval
|
||||
{
|
||||
private readonly IManager _manager;
|
||||
private readonly List<int> _privilegedClientIds;
|
||||
private readonly RequestDelegate _nextRequest;
|
||||
|
||||
public ClaimsPermissionRemoval(RequestDelegate nextRequest, IManager manager)
|
||||
{
|
||||
_manager = manager;
|
||||
_manager.OnServerEvent += OnGameEvent;
|
||||
_privilegedClientIds = new List<int>();
|
||||
_nextRequest = nextRequest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for the game event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
private void OnGameEvent(object sender, GameEventArgs args)
|
||||
{
|
||||
if (args.Event.Type == EventType.ChangePermission &&
|
||||
args.Event.Extra is Permission perm)
|
||||
{
|
||||
// we want to remove the claims when the client is demoted
|
||||
if (perm < Permission.Trusted)
|
||||
{
|
||||
lock (_privilegedClientIds)
|
||||
{
|
||||
_privilegedClientIds.RemoveAll(id => id == args.Event.Target.ClientId);
|
||||
}
|
||||
}
|
||||
// and add if promoted
|
||||
else if (perm > Permission.Trusted &&
|
||||
!_privilegedClientIds.Contains(args.Event.Target.ClientId))
|
||||
{
|
||||
lock (_privilegedClientIds)
|
||||
{
|
||||
_privilegedClientIds.Add(args.Event.Target.ClientId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
// we want to load the initial list of privileged clients
|
||||
if (_privilegedClientIds.Count == 0)
|
||||
{
|
||||
var ids = (await _manager.GetClientService().GetPrivilegedClients())
|
||||
.Select(_client => _client.ClientId);
|
||||
|
||||
lock (_privilegedClientIds)
|
||||
{
|
||||
_privilegedClientIds.AddRange(ids);
|
||||
}
|
||||
}
|
||||
|
||||
// sid stores the clientId
|
||||
string claimsId = context.User.Claims.FirstOrDefault(_claim => _claim.Type == ClaimTypes.Sid)?.Value;
|
||||
|
||||
if (!string.IsNullOrEmpty(claimsId))
|
||||
{
|
||||
int clientId = int.Parse(claimsId);
|
||||
// they've been removed
|
||||
if (!_privilegedClientIds.Contains(clientId) && clientId != 1)
|
||||
{
|
||||
await context.SignOutAsync();
|
||||
}
|
||||
}
|
||||
|
||||
await _nextRequest.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
@ -113,6 +113,9 @@ namespace WebfrontCore
|
||||
app.UseAuthentication();
|
||||
app.UseCors("AllowAll");
|
||||
|
||||
// prevents banned/demoted users from keeping their claims
|
||||
app.UseMiddleware<ClaimsPermissionRemoval>(Program.Manager);
|
||||
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
|
Loading…
Reference in New Issue
Block a user