]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix role unbans not applying in real time (#20547)
authorDrSmugleaf <DrSmugleaf@users.noreply.github.com>
Thu, 28 Sep 2023 23:46:39 +0000 (16:46 -0700)
committerGitHub <noreply@github.com>
Thu, 28 Sep 2023 23:46:39 +0000 (16:46 -0700)
Content.Server/Administration/Commands/RoleUnbanCommand.cs
Content.Server/Administration/Managers/BanManager.cs
Content.Server/Administration/Managers/IBanManager.cs
Content.Server/Database/ServerDbBase.cs
Content.Server/Database/ServerDbManager.cs
Content.Server/Database/ServerDbPostgres.cs
Content.Server/Database/ServerDbSqlite.cs

index ba8ab61c5c114338429979801f32e64f8f0542d7..a49f1231bf45cae9e8fa6553bc6c9d5bc407080c 100644 (file)
@@ -1,7 +1,5 @@
-using System.Text;
-using Content.Server.Database;
+using Content.Server.Administration.Managers;
 using Content.Shared.Administration;
-using Robust.Server.Player;
 using Robust.Shared.Console;
 
 namespace Content.Server.Administration.Commands;
@@ -15,9 +13,6 @@ public sealed class RoleUnbanCommand : IConsoleCommand
 
     public async void Execute(IConsoleShell shell, string argStr, string[] args)
     {
-        var player = shell.Player as IPlayerSession;
-        var dbMan = IoCManager.Resolve<IServerDbManager>();
-
         if (args.Length != 1)
         {
             shell.WriteLine(Help);
@@ -30,32 +25,9 @@ public sealed class RoleUnbanCommand : IConsoleCommand
             return;
         }
 
-        var ban = await dbMan.GetServerRoleBanAsync(banId);
-
-        if (ban == null)
-        {
-            shell.WriteLine($"No ban found with id {banId}");
-            return;
-        }
-
-        if (ban.Unban != null)
-        {
-            var response = new StringBuilder("This ban has already been pardoned");
-
-            if (ban.Unban.UnbanningAdmin != null)
-            {
-                response.Append($" by {ban.Unban.UnbanningAdmin.Value}");
-            }
-
-            response.Append($" in {ban.Unban.UnbanTime}.");
-
-            shell.WriteLine(response.ToString());
-            return;
-        }
-
-        await dbMan.AddServerRoleUnbanAsync(new ServerRoleUnbanDef(banId, player?.UserId, DateTimeOffset.Now));
-
-        shell.WriteLine($"Pardoned ban with id {banId}");
+        var banManager = IoCManager.Resolve<IBanManager>();
+        var response = await banManager.PardonRoleBan(banId, shell.Player?.UserId, DateTimeOffset.Now);
+        shell.WriteLine(response);
     }
 
     public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
index 4640c63dbd236b572916c6c4a67e1d29204008e9..765df17b179fabc31bbaf86493c642239c826b15 100644 (file)
@@ -1,21 +1,22 @@
 using System.Collections.Immutable;
 using System.Linq;
 using System.Net;
+using System.Text;
 using System.Threading.Tasks;
 using Content.Server.Chat.Managers;
 using Content.Server.Database;
 using Content.Server.GameTicking;
+using Content.Shared.CCVar;
 using Content.Shared.Database;
 using Content.Shared.Players;
 using Content.Shared.Players.PlayTimeTracking;
 using Content.Shared.Roles;
-using Microsoft.CodeAnalysis;
-using Content.Shared.CCVar;
 using Robust.Server.Player;
 using Robust.Shared.Configuration;
 using Robust.Shared.Enums;
 using Robust.Shared.Network;
 using Robust.Shared.Prototypes;
+using Robust.Shared.Utility;
 
 namespace Content.Server.Administration.Managers;
 
@@ -47,28 +48,25 @@ public sealed class BanManager : IBanManager, IPostInjectInit
 
     private async void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e)
     {
-        if (e.NewStatus != SessionStatus.Connected
-            || _cachedRoleBans.ContainsKey(e.Session.UserId))
+        if (e.NewStatus != SessionStatus.Connected || _cachedRoleBans.ContainsKey(e.Session.UserId))
             return;
 
         var netChannel = e.Session.ConnectedClient;
-        await CacheDbRoleBans(e.Session.UserId, netChannel.RemoteEndPoint.Address, netChannel.UserData.HWId.Length == 0 ? null : netChannel.UserData.HWId);
+        ImmutableArray<byte>? hwId = netChannel.UserData.HWId.Length == 0 ? null : netChannel.UserData.HWId;
+        await CacheDbRoleBans(e.Session.UserId, netChannel.RemoteEndPoint.Address, hwId);
+
+        SendRoleBans(e.Session);
     }
 
     private async Task<bool> AddRoleBan(ServerRoleBanDef banDef)
     {
+        banDef = await _db.AddServerRoleBanAsync(banDef);
+
         if (banDef.UserId != null)
         {
-            if (!_cachedRoleBans.TryGetValue(banDef.UserId.Value, out var roleBans))
-            {
-                roleBans = new HashSet<ServerRoleBanDef>();
-                _cachedRoleBans.Add(banDef.UserId.Value, roleBans);
-            }
-            if (!roleBans.Contains(banDef))
-                roleBans.Add(banDef);
+            _cachedRoleBans.GetOrNew(banDef.UserId.Value).Add(banDef);
         }
 
-        await _db.AddServerRoleBanAsync(banDef);
         return true;
     }
 
@@ -231,6 +229,39 @@ public sealed class BanManager : IBanManager, IPostInjectInit
         }
     }
 
+    public async Task<string> PardonRoleBan(int banId, NetUserId? unbanningAdmin, DateTimeOffset unbanTime)
+    {
+        var ban = await _db.GetServerRoleBanAsync(banId);
+
+        if (ban == null)
+        {
+            return $"No ban found with id {banId}";
+        }
+
+        if (ban.Unban != null)
+        {
+            var response = new StringBuilder("This ban has already been pardoned");
+
+            if (ban.Unban.UnbanningAdmin != null)
+            {
+                response.Append($" by {ban.Unban.UnbanningAdmin.Value}");
+            }
+
+            response.Append($" in {ban.Unban.UnbanTime}.");
+            return response.ToString();
+        }
+
+        await _db.AddServerRoleUnbanAsync(new ServerRoleUnbanDef(banId, unbanningAdmin, DateTimeOffset.Now));
+
+        if (ban.UserId is { } player && _cachedRoleBans.TryGetValue(player, out var roleBans))
+        {
+            roleBans.RemoveWhere(roleBan => roleBan.Id == ban.Id);
+            SendRoleBans(player);
+        }
+
+        return $"Pardoned ban with id {banId}";
+    }
+
     public HashSet<string>? GetJobBans(NetUserId playerUserId)
     {
         if (!_cachedRoleBans.TryGetValue(playerUserId, out var roleBans))
@@ -254,12 +285,7 @@ public sealed class BanManager : IBanManager, IPostInjectInit
 
     public void SendRoleBans(IPlayerSession pSession)
     {
-        if (!_cachedRoleBans.TryGetValue(pSession.UserId, out var roleBans))
-        {
-            _sawmill.Error($"Tried to send rolebans for {pSession.Name} but none cached?");
-            return;
-        }
-
+        var roleBans = _cachedRoleBans.GetValueOrDefault(pSession.UserId) ?? new HashSet<ServerRoleBanDef>();
         var bans = new MsgRoleBans()
         {
             Bans = roleBans.Select(o => o.Role).ToList()
index 6d991c7576f325b4825d7ae0fa9821bb00fb28b6..8458feac8d0614293d5e83abbe8e6a91bb6fef13 100644 (file)
@@ -1,8 +1,9 @@
 using System.Collections.Immutable;
+using System.Net;
+using System.Threading.Tasks;
 using Content.Shared.Database;
 using Robust.Server.Player;
 using Robust.Shared.Network;
-using System.Net;
 
 namespace Content.Server.Administration.Managers;
 
@@ -24,18 +25,26 @@ public interface IBanManager
     public void CreateServerBan(NetUserId? target, string? targetUsername, NetUserId? banningAdmin, (IPAddress, int)? addressRange, ImmutableArray<byte>? hwid, uint? minutes, NoteSeverity severity, string reason);
     public HashSet<string>? GetRoleBans(NetUserId playerUserId);
     public HashSet<string>? GetJobBans(NetUserId playerUserId);
+
     /// <summary>
     /// Creates a job ban for the specified target, username or GUID
     /// </summary>
-    /// <param name="shell">Shell reference so we can write messages</param>
     /// <param name="target">Target user, username or GUID, null for none</param>
-    /// <param name="job">Job to be banned from</param>
+    /// <param name="role">Role to be banned from</param>
     /// <param name="severity">Severity of the resulting ban note</param>
     /// <param name="reason">Reason for the ban</param>
     /// <param name="minutes">Number of minutes to ban for. 0 and null mean permanent</param>
     /// <param name="timeOfBan">Time when the ban was applied, used for grouping role bans</param>
     public void CreateRoleBan(NetUserId? target, string? targetUsername, NetUserId? banningAdmin, (IPAddress, int)? addressRange, ImmutableArray<byte>? hwid, string role, uint? minutes, NoteSeverity severity, string reason, DateTimeOffset timeOfBan);
 
+    /// <summary>
+    /// Pardons a role ban for the specified target, username or GUID
+    /// </summary>
+    /// <param name="banId">The id of the role ban to pardon.</param>
+    /// <param name="unbanningAdmin">The admin, if any, that pardoned the role ban.</param>
+    /// <param name="unbanTime">The time at which this role ban was pardoned.</param>
+    public Task<string> PardonRoleBan(int banId, NetUserId? unbanningAdmin, DateTimeOffset unbanTime);
+
     /// <summary>
     /// Sends role bans to the target
     /// </summary>
index f90b938b791277c1c273a4d02281191ec73b5680..aeebc64f07b64d4daefe65a057b9a7abe583e421 100644 (file)
@@ -432,7 +432,7 @@ namespace Content.Server.Database
             ImmutableArray<byte>? hwId,
             bool includeUnbanned);
 
-        public abstract Task AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan);
+        public abstract Task<ServerRoleBanDef> AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan);
         public abstract Task AddServerRoleUnbanAsync(ServerRoleUnbanDef serverRoleUnban);
 
         public async Task EditServerRoleBan(int id, string reason, NoteSeverity severity, DateTime? expiration, Guid editedBy, DateTime editedAt)
index f345763f53d1b12e1e43d08d8f5c34a0f357b2ea..8d07a5ac5eae1dda8a5cbcc088e68437225bb6c1 100644 (file)
@@ -14,7 +14,6 @@ using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.Logging;
 using Npgsql;
 using Prometheus;
-using Robust.Shared.Asynchronous;
 using Robust.Shared.Configuration;
 using Robust.Shared.ContentPack;
 using Robust.Shared.Network;
@@ -140,7 +139,7 @@ namespace Content.Server.Database
             ImmutableArray<byte>? hwId,
             bool includeUnbanned = true);
 
-        Task AddServerRoleBanAsync(ServerRoleBanDef serverBan);
+        Task<ServerRoleBanDef> AddServerRoleBanAsync(ServerRoleBanDef serverBan);
         Task AddServerRoleUnbanAsync(ServerRoleUnbanDef serverBan);
 
         public Task EditServerRoleBan(
@@ -453,7 +452,7 @@ namespace Content.Server.Database
             return RunDbCommand(() => _db.GetServerRoleBansAsync(address, userId, hwId, includeUnbanned));
         }
 
-        public Task AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan)
+        public Task<ServerRoleBanDef> AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan)
         {
             DbWriteOpsMetric.Inc();
             return RunDbCommand(() => _db.AddServerRoleBanAsync(serverRoleBan));
index 40e9010cf78ec765add1077cf91a1906c41920a6..3548b1d1b3775e972d8ae542caf08ab1750b226b 100644 (file)
@@ -1,5 +1,6 @@
 using System.Collections.Immutable;
 using System.Data;
+using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using System.Net;
 using System.Threading;
@@ -350,6 +351,7 @@ namespace Content.Server.Database
             return query;
         }
 
+        [return: NotNullIfNotNull(nameof(ban))]
         private static ServerRoleBanDef? ConvertRoleBan(ServerRoleBan? ban)
         {
             if (ban == null)
@@ -406,11 +408,11 @@ namespace Content.Server.Database
                 unban.UnbanTime);
         }
 
-        public override async Task AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan)
+        public override async Task<ServerRoleBanDef> AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan)
         {
             await using var db = await GetDbImpl();
 
-            db.PgDbContext.RoleBan.Add(new ServerRoleBan
+            var ban = new ServerRoleBan
             {
                 Address = serverRoleBan.Address,
                 HWId = serverRoleBan.HWId?.ToArray(),
@@ -423,9 +425,11 @@ namespace Content.Server.Database
                 PlaytimeAtNote = serverRoleBan.PlaytimeAtNote,
                 PlayerUserId = serverRoleBan.UserId?.UserId,
                 RoleId = serverRoleBan.Role,
-            });
+            };
+            db.PgDbContext.RoleBan.Add(ban);
 
             await db.PgDbContext.SaveChangesAsync();
+            return ConvertRoleBan(ban);
         }
 
         public override async Task AddServerRoleUnbanAsync(ServerRoleUnbanDef serverRoleUnban)
index 35ee95f8d21b902b245e57534f966afb0efe3a2e..676081c54ed8cbf74ca0a947b33130ee49465a32 100644 (file)
@@ -1,4 +1,5 @@
 using System.Collections.Immutable;
+using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using System.Net;
 using System.Threading;
@@ -246,11 +247,11 @@ namespace Content.Server.Database
             return hwId is { Length: > 0 } hwIdVar && hwIdVar.AsSpan().SequenceEqual(ban.HWId);
         }
 
-        public override async Task AddServerRoleBanAsync(ServerRoleBanDef serverBan)
+        public override async Task<ServerRoleBanDef> AddServerRoleBanAsync(ServerRoleBanDef serverBan)
         {
             await using var db = await GetDbImpl();
 
-            db.SqliteDbContext.RoleBan.Add(new ServerRoleBan
+            var ban = new ServerRoleBan
             {
                 Address = serverBan.Address,
                 Reason = serverBan.Reason,
@@ -263,9 +264,11 @@ namespace Content.Server.Database
                 PlaytimeAtNote = serverBan.PlaytimeAtNote,
                 PlayerUserId = serverBan.UserId?.UserId,
                 RoleId = serverBan.Role,
-            });
+            };
+            db.SqliteDbContext.RoleBan.Add(ban);
 
             await db.SqliteDbContext.SaveChangesAsync();
+            return ConvertRoleBan(ban);
         }
 
         public override async Task AddServerRoleUnbanAsync(ServerRoleUnbanDef serverUnban)
@@ -282,6 +285,7 @@ namespace Content.Server.Database
             await db.SqliteDbContext.SaveChangesAsync();
         }
 
+        [return: NotNullIfNotNull(nameof(ban))]
         private static ServerRoleBanDef? ConvertRoleBan(ServerRoleBan? ban)
         {
             if (ban == null)