Code/SboxSuperuser/Engine/Admin/HostAdminQueries.cs

Server-side admin query handler for the host. It authenticates the requesting actor, checks policy and moderation availability and permissions, then returns activity logs, player search results, or moderation/state info (roles, allowed actions, history, restrictions) for a queried Steam ID.

File AccessNetworking
using SboxSuperuser.Engine.Audit;
using SboxSuperuser.Engine.Authority;
using SboxSuperuser.Engine.Moderation;

namespace SboxSuperuser.Engine.Admin;

internal sealed class HostAdminQueries
{
	private readonly HostPolicyService _policy;
	private readonly HostModerationService _moderation;
	private readonly HostAuditService _audit;
	private readonly Func<IReadOnlyList<CommandPlayer>> _players;
	private static readonly AdminAction[] AllActions = Enum.GetValues<AdminAction>();

	internal HostAdminQueries( HostPolicyService policy, HostModerationService moderation, HostAuditService audit,
		Func<IReadOnlyList<CommandPlayer>> players )
	{
		_policy = policy;
		_moderation = moderation;
		_audit = audit;
		_players = players;
	}

	internal async Task<AdminReply> QueryAsync( Func<ActorIdentity> authenticate, AdminQuery query, Guid id, CancellationToken cancellation )
	{
		var initial = authenticate();
		if ( initial is null ) return Failure( id, CommandStatus.Denied, "A live authenticated player is required." );
		await _policy.Initialization;
		await _moderation.Initialization;
		ActorIdentity Current()
		{
			var actor = authenticate();
			return actor?.Kind == initial.Kind && actor?.SubjectId == initial.SubjectId ? actor : null;
		}
		var actor = Current();
		if ( actor is null ) return Failure( id, CommandStatus.Denied, "The requesting connection is no longer valid." );
		if ( !_policy.IsUsable ) return Failure( id, CommandStatus.StorageUnavailable, "Authority data is unavailable." );
		bool Can( string permission ) => _policy.Explain( actor, permission ).IsAllowed;
		if ( query.Kind == AdminQueryKind.Activity )
		{
			var result = await _audit.QueryAsync( Current, who => _policy.Explain( who, "admin.audit.read" ).IsAllowed,
				who => _policy.Explain( who, "admin.results.own" ).IsAllowed, new AuditQuery( pageSize: 20 ), cancellation );
			return new AdminReply
			{
				RequestId = id, Status = result.Status, Message = result.Message,
				Activity = result.Entries.Select( row => new AdminActivityRow
				{
					RequestId = row.RequestId, Actor = row.ActorSubject, Command = row.Command,
					CreatedUtc = row.CreatedUtc, Outcome = row.Outcome
				} ).ToArray()
			};
		}
		var actions = AllActions.Where( action => Can( Permission( action ) ) ).ToArray();
		var history = Can( "admin.players.history" );
		if ( actions.Length == 0 && !history ) return Failure( id, CommandStatus.Denied, "Moderation permission is required to inspect players." );
		var online = _players();
		if ( online is null ) return Failure( id, CommandStatus.Unsupported, "The online player list is unavailable." );
		if ( query.Kind == AdminQueryKind.Players )
		{
			var selected = online.Where( player => player.SteamId.Contains( query.Search, StringComparison.Ordinal )
				|| player.DisplayName.Contains( query.Search, StringComparison.OrdinalIgnoreCase ) )
				.OrderBy( player => player.SteamId, StringComparer.Ordinal ).Skip( query.Page * 20 ).Take( 21 ).ToArray();
			return new AdminReply
			{
				RequestId = id, Status = CommandStatus.Success, Message = "Online players.", HasMore = selected.Length > 20,
				Players = selected.Take( 20 ).Select( player => new AdminPlayerRow { SteamId = player.SteamId, Name = player.DisplayName } ).ToArray()
			};
		}
		if ( !_moderation.IsUsable ) return Failure( id, CommandStatus.StorageUnavailable, "Moderation data is unavailable." );
		var isOnline = online.Any( player => player.SteamId == query.Search );
		var canTarget = _policy.CheckTarget( actor, query.Search ).IsAllowed;
		var rows = Array.Empty<AdminModerationRow>();
		var more = false;
		if ( history ) rows = _moderation.ReadView( query.Search, true, query.Page, true, true, out more );
		return new AdminReply
		{
			RequestId = id, Status = CommandStatus.Success, Message = isOnline ? "Connected player." : "Offline Steam ID.",
			SteamId = query.Search, Online = isOnline, Roles = _policy.ReadRoleLabels( query.Search ),
			Actions = actions.Where( action => (action is AdminAction.Unban or AdminAction.Unmute || canTarget)
				&& (action != AdminAction.Kick || isOnline) ).ToArray(),
			HistoryAllowed = history, History = rows, HasMore = more,
			Restrictions = _moderation.ReadView( query.Search, false, 0,
				history || actions.Contains( AdminAction.Ban ) || actions.Contains( AdminAction.Unban ),
				history || actions.Contains( AdminAction.Mute ) || actions.Contains( AdminAction.Unmute ), out _ )
		};
	}

	internal static string Permission( AdminAction action ) => "admin.players." + action.ToString().ToLowerInvariant();

	internal static AdminReply Failure( Guid id, CommandStatus status, string message ) => new()
	{
		RequestId = id, Status = status, Message = message
	};
}