[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:
rhailrake
2023-04-30 14:27:27 +06:00
committed by Remuchi
parent 8bd6754472
commit 977e075086
42 changed files with 5825 additions and 328 deletions

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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)

View File

@@ -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;
}
}