[feat] Разделение банов по серверам.
# Conflicts: # Content.Client/Administration/UI/BanList/BanListLine.xaml.cs # Content.Client/Administration/UI/BanList/Bans/BanListHeader.xaml # Content.Client/Administration/UI/BanList/Bans/BanListLine.xaml # Content.Client/Administration/UI/Tabs/AdminTab/BanWindow.xaml # Content.Client/Administration/UI/Tabs/AdminTab/BanWindow.xaml.cs # Content.IntegrationTests/Tests/Commands/PardonCommand.cs # Content.Server/Administration/Commands/BanCommand.cs # Content.Server/Administration/Commands/DepartmentBanCommand.cs # Content.Server/Administration/Commands/RoleBanCommand.cs # Content.Server/Administration/Managers/RoleBanManager.cs # Content.Server/Database/ServerDbManager.cs # Content.Server/Database/ServerDbPostgres.cs # Content.Server/Database/ServerDbSqlite.cs
This commit is contained in:
@@ -5,7 +5,6 @@ using Content.Shared.Database;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Network;
|
||||
|
||||
|
||||
namespace Content.Server.Database
|
||||
{
|
||||
public sealed class ServerBanDef
|
||||
@@ -24,8 +23,9 @@ namespace Content.Server.Database
|
||||
public NetUserId? BanningAdmin { get; }
|
||||
public ServerUnbanDef? Unban { get; }
|
||||
|
||||
public ServerBanDef(
|
||||
int? id,
|
||||
public string ServerName { get; }
|
||||
|
||||
public ServerBanDef(int? id,
|
||||
NetUserId? userId,
|
||||
(IPAddress, int)? address,
|
||||
ImmutableArray<byte>? hwId,
|
||||
@@ -36,7 +36,8 @@ namespace Content.Server.Database
|
||||
string reason,
|
||||
NoteSeverity severity,
|
||||
NetUserId? banningAdmin,
|
||||
ServerUnbanDef? unban)
|
||||
ServerUnbanDef? unban,
|
||||
string serverName)
|
||||
{
|
||||
if (userId == null && address == null && hwId == null)
|
||||
{
|
||||
@@ -62,6 +63,7 @@ namespace Content.Server.Database
|
||||
Severity = severity;
|
||||
BanningAdmin = banningAdmin;
|
||||
Unban = unban;
|
||||
ServerName = serverName;
|
||||
}
|
||||
|
||||
public string FormatBanMessage(IConfigurationManager cfg, ILocalizationManager loc)
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace Content.Server.Database
|
||||
{
|
||||
public abstract class ServerDbBase
|
||||
{
|
||||
protected const string GlobalServerName = "unknown";
|
||||
private readonly ISawmill _opsLog;
|
||||
|
||||
/// <param name="opsLog">Sawmill to trace log database operations to.</param>
|
||||
@@ -337,7 +338,8 @@ namespace Content.Server.Database
|
||||
public abstract Task<ServerBanDef?> GetServerBanAsync(
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId);
|
||||
ImmutableArray<byte>? hwId,
|
||||
string serverName = GlobalServerName);
|
||||
|
||||
/// <summary>
|
||||
/// Looks up an user's ban history.
|
||||
@@ -353,7 +355,8 @@ namespace Content.Server.Database
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId,
|
||||
bool includeUnbanned);
|
||||
bool includeUnbanned,
|
||||
string serverName = GlobalServerName);
|
||||
|
||||
public abstract Task AddServerBanAsync(ServerBanDef serverBan);
|
||||
public abstract Task AddServerUnbanAsync(ServerUnbanDef serverUnban);
|
||||
@@ -445,7 +448,8 @@ namespace Content.Server.Database
|
||||
public abstract Task<List<ServerRoleBanDef>> GetServerRoleBansAsync(IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId,
|
||||
bool includeUnbanned);
|
||||
bool includeUnbanned,
|
||||
string serverName = GlobalServerName);
|
||||
|
||||
public abstract Task<ServerRoleBanDef> AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan);
|
||||
public abstract Task AddServerRoleUnbanAsync(ServerRoleUnbanDef serverRoleUnban);
|
||||
@@ -660,6 +664,7 @@ namespace Content.Server.Database
|
||||
existing.Flags = admin.Flags;
|
||||
existing.Title = admin.Title;
|
||||
existing.AdminRankId = admin.AdminRankId;
|
||||
existing.AdminServer = admin.AdminServer;
|
||||
|
||||
await db.DbContext.SaveChangesAsync(cancel);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Content.Server.Database
|
||||
{
|
||||
public interface IServerDbManager
|
||||
{
|
||||
const string GlobalServerName = "unknown";
|
||||
void Init();
|
||||
|
||||
void Shutdown();
|
||||
@@ -68,7 +69,8 @@ namespace Content.Server.Database
|
||||
Task<ServerBanDef?> GetServerBanAsync(
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId);
|
||||
ImmutableArray<byte>? hwId,
|
||||
string serverName = GlobalServerName);
|
||||
|
||||
/// <summary>
|
||||
/// Looks up an user's ban history.
|
||||
@@ -83,7 +85,8 @@ namespace Content.Server.Database
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId,
|
||||
bool includeUnbanned=true);
|
||||
bool includeUnbanned=true,
|
||||
string serverName = GlobalServerName);
|
||||
|
||||
Task AddServerBanAsync(ServerBanDef serverBan);
|
||||
Task AddServerUnbanAsync(ServerUnbanDef serverBan);
|
||||
@@ -137,7 +140,8 @@ namespace Content.Server.Database
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId,
|
||||
bool includeUnbanned = true);
|
||||
bool includeUnbanned = true,
|
||||
string serverName = GlobalServerName);
|
||||
|
||||
Task<ServerRoleBanDef> AddServerRoleBanAsync(ServerRoleBanDef serverBan);
|
||||
Task AddServerRoleUnbanAsync(ServerRoleUnbanDef serverBan);
|
||||
@@ -281,6 +285,8 @@ namespace Content.Server.Database
|
||||
|
||||
public sealed class ServerDbManager : IServerDbManager
|
||||
{
|
||||
private const string GlobalServerName = "unknown";
|
||||
|
||||
public static readonly Counter DbReadOpsMetric = Metrics.CreateCounter(
|
||||
"db_read_ops",
|
||||
"Amount of read operations processed by the database manager.");
|
||||
@@ -395,20 +401,22 @@ namespace Content.Server.Database
|
||||
public Task<ServerBanDef?> GetServerBanAsync(
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId)
|
||||
ImmutableArray<byte>? hwId,
|
||||
string serverName = GlobalServerName)
|
||||
{
|
||||
DbReadOpsMetric.Inc();
|
||||
return RunDbCommand(() => _db.GetServerBanAsync(address, userId, hwId));
|
||||
return RunDbCommand(() => _db.GetServerBanAsync(address, userId, hwId, serverName));
|
||||
}
|
||||
|
||||
public Task<List<ServerBanDef>> GetServerBansAsync(
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId,
|
||||
bool includeUnbanned=true)
|
||||
bool includeUnbanned=true,
|
||||
string serverName = GlobalServerName)
|
||||
{
|
||||
DbReadOpsMetric.Inc();
|
||||
return RunDbCommand(() => _db.GetServerBansAsync(address, userId, hwId, includeUnbanned));
|
||||
return RunDbCommand(() => _db.GetServerBansAsync(address, userId, hwId, includeUnbanned, serverName));
|
||||
}
|
||||
|
||||
public Task AddServerBanAsync(ServerBanDef serverBan)
|
||||
@@ -452,10 +460,11 @@ namespace Content.Server.Database
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId,
|
||||
bool includeUnbanned = true)
|
||||
bool includeUnbanned=true,
|
||||
string serverName = GlobalServerName)
|
||||
{
|
||||
DbReadOpsMetric.Inc();
|
||||
return RunDbCommand(() => _db.GetServerRoleBansAsync(address, userId, hwId, includeUnbanned));
|
||||
return RunDbCommand(() => _db.GetServerRoleBansAsync(address, userId, hwId, includeUnbanned, serverName));
|
||||
}
|
||||
|
||||
public Task<ServerRoleBanDef> AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan)
|
||||
|
||||
@@ -67,7 +67,8 @@ namespace Content.Server.Database
|
||||
public override async Task<ServerBanDef?> GetServerBanAsync(
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId)
|
||||
ImmutableArray<byte>? hwId,
|
||||
string serverName = GlobalServerName)
|
||||
{
|
||||
if (address == null && userId == null && hwId == null)
|
||||
{
|
||||
@@ -77,7 +78,7 @@ namespace Content.Server.Database
|
||||
await using var db = await GetDbImpl();
|
||||
|
||||
var exempt = await GetBanExemptionCore(db, userId);
|
||||
var query = MakeBanLookupQuery(address, userId, hwId, db, includeUnbanned: false, exempt)
|
||||
var query = MakeBanLookupQuery(address, userId, hwId, db, includeUnbanned: false, exempt, serverName)
|
||||
.OrderByDescending(b => b.BanTime);
|
||||
|
||||
var ban = await query.FirstOrDefaultAsync();
|
||||
@@ -87,7 +88,7 @@ namespace Content.Server.Database
|
||||
|
||||
public override async Task<List<ServerBanDef>> GetServerBansAsync(IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId, bool includeUnbanned)
|
||||
ImmutableArray<byte>? hwId, bool includeUnbanned, string serverName = GlobalServerName)
|
||||
{
|
||||
if (address == null && userId == null && hwId == null)
|
||||
{
|
||||
@@ -97,7 +98,7 @@ namespace Content.Server.Database
|
||||
await using var db = await GetDbImpl();
|
||||
|
||||
var exempt = await GetBanExemptionCore(db, userId);
|
||||
var query = MakeBanLookupQuery(address, userId, hwId, db, includeUnbanned, exempt);
|
||||
var query = MakeBanLookupQuery(address, userId, hwId, db, includeUnbanned, exempt, serverName);
|
||||
|
||||
var queryBans = await query.ToArrayAsync();
|
||||
var bans = new List<ServerBanDef>(queryBans.Length);
|
||||
@@ -121,7 +122,8 @@ namespace Content.Server.Database
|
||||
ImmutableArray<byte>? hwId,
|
||||
DbGuardImpl db,
|
||||
bool includeUnbanned,
|
||||
ServerBanExemptFlags? exemptFlags)
|
||||
ServerBanExemptFlags? exemptFlags,
|
||||
string serverName = GlobalServerName)
|
||||
{
|
||||
DebugTools.Assert(!(address == null && userId == null && hwId == null));
|
||||
|
||||
@@ -158,6 +160,9 @@ namespace Content.Server.Database
|
||||
query != null,
|
||||
"At least one filter item (IP/UserID/HWID) must have been given to make query not null.");
|
||||
|
||||
query = query.Where(p =>
|
||||
p.ServerName == serverName || p.ServerName == "unknown" || string.IsNullOrEmpty(p.ServerName) || serverName == GlobalServerName);
|
||||
|
||||
if (!includeUnbanned)
|
||||
{
|
||||
query = query.Where(p =>
|
||||
@@ -205,7 +210,8 @@ namespace Content.Server.Database
|
||||
ban.Reason,
|
||||
ban.Severity,
|
||||
aUid,
|
||||
unbanDef);
|
||||
unbanDef,
|
||||
ban.ServerName ??= "unknown");
|
||||
}
|
||||
|
||||
private static ServerUnbanDef? ConvertUnban(ServerUnban? unban)
|
||||
@@ -242,7 +248,8 @@ namespace Content.Server.Database
|
||||
ExpirationTime = serverBan.ExpirationTime?.UtcDateTime,
|
||||
RoundId = serverBan.RoundId,
|
||||
PlaytimeAtNote = serverBan.PlaytimeAtNote,
|
||||
PlayerUserId = serverBan.UserId?.UserId
|
||||
PlayerUserId = serverBan.UserId?.UserId,
|
||||
ServerName = serverBan.ServerName
|
||||
});
|
||||
|
||||
await db.PgDbContext.SaveChangesAsync();
|
||||
@@ -281,7 +288,8 @@ namespace Content.Server.Database
|
||||
public override async Task<List<ServerRoleBanDef>> GetServerRoleBansAsync(IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId,
|
||||
bool includeUnbanned)
|
||||
bool includeUnbanned,
|
||||
string serverName = GlobalServerName)
|
||||
{
|
||||
if (address == null && userId == null && hwId == null)
|
||||
{
|
||||
@@ -290,7 +298,7 @@ namespace Content.Server.Database
|
||||
|
||||
await using var db = await GetDbImpl();
|
||||
|
||||
var query = MakeRoleBanLookupQuery(address, userId, hwId, db, includeUnbanned)
|
||||
var query = MakeRoleBanLookupQuery(address, userId, hwId, db, includeUnbanned, serverName)
|
||||
.OrderByDescending(b => b.BanTime);
|
||||
|
||||
return await QueryRoleBans(query);
|
||||
@@ -319,7 +327,8 @@ namespace Content.Server.Database
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId,
|
||||
DbGuardImpl db,
|
||||
bool includeUnbanned)
|
||||
bool includeUnbanned,
|
||||
string serverName = GlobalServerName)
|
||||
{
|
||||
IQueryable<ServerRoleBan>? query = null;
|
||||
|
||||
@@ -350,6 +359,9 @@ namespace Content.Server.Database
|
||||
query = query == null ? newQ : query.Union(newQ);
|
||||
}
|
||||
|
||||
query = query?.Where(p =>
|
||||
p.ServerName == serverName || p.ServerName == "unknown" || string.IsNullOrEmpty(p.ServerName) || serverName == GlobalServerName);
|
||||
|
||||
if (!includeUnbanned)
|
||||
{
|
||||
query = query?.Where(p =>
|
||||
@@ -395,7 +407,8 @@ namespace Content.Server.Database
|
||||
ban.Severity,
|
||||
aUid,
|
||||
unbanDef,
|
||||
ban.RoleId);
|
||||
ban.RoleId,
|
||||
ban.ServerName ??= "unknown");
|
||||
}
|
||||
|
||||
private static ServerRoleUnbanDef? ConvertRoleUnban(ServerRoleUnban? unban)
|
||||
@@ -434,6 +447,7 @@ namespace Content.Server.Database
|
||||
PlaytimeAtNote = serverRoleBan.PlaytimeAtNote,
|
||||
PlayerUserId = serverRoleBan.UserId?.UserId,
|
||||
RoleId = serverRoleBan.Role,
|
||||
ServerName = serverRoleBan.ServerName
|
||||
};
|
||||
db.PgDbContext.RoleBan.Add(ban);
|
||||
|
||||
|
||||
@@ -79,7 +79,8 @@ namespace Content.Server.Database
|
||||
public override async Task<ServerBanDef?> GetServerBanAsync(
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId)
|
||||
ImmutableArray<byte>? hwId,
|
||||
string serverName = GlobalServerName)
|
||||
{
|
||||
await using var db = await GetDbImpl();
|
||||
|
||||
@@ -89,14 +90,14 @@ namespace Content.Server.Database
|
||||
// So just pull down the whole list into memory.
|
||||
var bans = await GetAllBans(db.SqliteDbContext, includeUnbanned: false, exempt);
|
||||
|
||||
return bans.FirstOrDefault(b => BanMatches(b, address, userId, hwId, exempt)) is { } foundBan
|
||||
return bans.FirstOrDefault(b => BanMatches(b, address, userId, hwId, exempt, serverName)) is { } foundBan
|
||||
? ConvertBan(foundBan)
|
||||
: null;
|
||||
}
|
||||
|
||||
public override async Task<List<ServerBanDef>> GetServerBansAsync(IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId, bool includeUnbanned)
|
||||
ImmutableArray<byte>? hwId, bool includeUnbanned, string serverName = GlobalServerName)
|
||||
{
|
||||
await using var db = await GetDbImpl();
|
||||
|
||||
@@ -107,7 +108,7 @@ namespace Content.Server.Database
|
||||
var queryBans = await GetAllBans(db.SqliteDbContext, includeUnbanned, exempt);
|
||||
|
||||
return queryBans
|
||||
.Where(b => BanMatches(b, address, userId, hwId, exempt))
|
||||
.Where(b => BanMatches(b, address, userId, hwId, exempt, serverName))
|
||||
.Select(ConvertBan)
|
||||
.ToList()!;
|
||||
}
|
||||
@@ -136,8 +137,14 @@ namespace Content.Server.Database
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId,
|
||||
ServerBanExemptFlags? exemptFlags)
|
||||
ServerBanExemptFlags? exemptFlags,
|
||||
string serverName = GlobalServerName)
|
||||
{
|
||||
if (serverName != GlobalServerName && ban.ServerName != GlobalServerName && serverName != ban.ServerName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!exemptFlags.GetValueOrDefault(ServerBanExemptFlags.None).HasFlag(ServerBanExemptFlags.IP)
|
||||
&& address != null && ban.Address is not null && address.IsInSubnet(ban.Address.Value))
|
||||
{
|
||||
@@ -167,7 +174,8 @@ namespace Content.Server.Database
|
||||
ExpirationTime = serverBan.ExpirationTime?.UtcDateTime,
|
||||
RoundId = serverBan.RoundId,
|
||||
PlaytimeAtNote = serverBan.PlaytimeAtNote,
|
||||
PlayerUserId = serverBan.UserId?.UserId
|
||||
PlayerUserId = serverBan.UserId?.UserId,
|
||||
ServerName = serverBan.ServerName
|
||||
});
|
||||
|
||||
await db.SqliteDbContext.SaveChangesAsync();
|
||||
@@ -205,7 +213,8 @@ namespace Content.Server.Database
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId,
|
||||
bool includeUnbanned)
|
||||
bool includeUnbanned,
|
||||
string serverName = GlobalServerName)
|
||||
{
|
||||
await using var db = await GetDbImpl();
|
||||
|
||||
@@ -214,7 +223,7 @@ namespace Content.Server.Database
|
||||
var queryBans = await GetAllRoleBans(db.SqliteDbContext, includeUnbanned);
|
||||
|
||||
return queryBans
|
||||
.Where(b => RoleBanMatches(b, address, userId, hwId))
|
||||
.Where(b => RoleBanMatches(b, address, userId, hwId, serverName))
|
||||
.Select(ConvertRoleBan)
|
||||
.ToList()!;
|
||||
}
|
||||
@@ -237,8 +246,14 @@ namespace Content.Server.Database
|
||||
ServerRoleBan ban,
|
||||
IPAddress? address,
|
||||
NetUserId? userId,
|
||||
ImmutableArray<byte>? hwId)
|
||||
ImmutableArray<byte>? hwId,
|
||||
string serverName)
|
||||
{
|
||||
if (serverName != GlobalServerName && ban.ServerName != GlobalServerName && serverName != ban.ServerName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (address != null && ban.Address is not null && address.IsInSubnet(ban.Address.Value))
|
||||
{
|
||||
return true;
|
||||
@@ -269,6 +284,7 @@ namespace Content.Server.Database
|
||||
PlaytimeAtNote = serverBan.PlaytimeAtNote,
|
||||
PlayerUserId = serverBan.UserId?.UserId,
|
||||
RoleId = serverBan.Role,
|
||||
ServerName = serverBan.ServerName
|
||||
};
|
||||
db.SqliteDbContext.RoleBan.Add(ban);
|
||||
|
||||
@@ -326,7 +342,8 @@ namespace Content.Server.Database
|
||||
ban.Severity,
|
||||
aUid,
|
||||
unban,
|
||||
ban.RoleId);
|
||||
ban.RoleId,
|
||||
ban.ServerName ??= GlobalServerName);
|
||||
}
|
||||
|
||||
private static ServerRoleUnbanDef? ConvertRoleUnban(ServerRoleUnban? unban)
|
||||
@@ -395,7 +412,8 @@ namespace Content.Server.Database
|
||||
ban.Reason,
|
||||
ban.Severity,
|
||||
aUid,
|
||||
unban);
|
||||
unban,
|
||||
ban.ServerName ??= GlobalServerName);
|
||||
}
|
||||
|
||||
private static ServerUnbanDef? ConvertUnban(ServerUnban? unban)
|
||||
|
||||
@@ -22,6 +22,8 @@ public sealed class ServerRoleBanDef
|
||||
public ServerRoleUnbanDef? Unban { get; }
|
||||
public string Role { get; }
|
||||
|
||||
public string? ServerName { get; }
|
||||
|
||||
public ServerRoleBanDef(
|
||||
int? id,
|
||||
NetUserId? userId,
|
||||
@@ -35,7 +37,8 @@ public sealed class ServerRoleBanDef
|
||||
NoteSeverity severity,
|
||||
NetUserId? banningAdmin,
|
||||
ServerRoleUnbanDef? unban,
|
||||
string role)
|
||||
string role,
|
||||
string serverName)
|
||||
{
|
||||
if (userId == null && address == null && hwId == null)
|
||||
{
|
||||
@@ -62,5 +65,6 @@ public sealed class ServerRoleBanDef
|
||||
BanningAdmin = banningAdmin;
|
||||
Unban = unban;
|
||||
Role = role;
|
||||
ServerName = serverName;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user