From 908c516cdfe1b8704def28dab60d97d61c19c5c3 Mon Sep 17 00:00:00 2001 From: Andrey Ushakov <10843461+Werzet@users.noreply.github.com> Date: Wed, 10 Apr 2024 07:04:54 +1000 Subject: [PATCH] New prime list (#900) * new prime list * remove old prime list * remove prime pgk --- Content.Packaging/ServerPackaging.cs | 1 - .../Connection/ConnectionManager.cs | 19 ++- Content.Server/Content.Server.csproj | 5 +- Content.Server/Entry/EntryPoint.cs | 2 - Content.Server/IoC/ServerContentIoC.cs | 2 - .../SS220/Discord/DiscordPlayerManager.cs | 35 ++++ .../SS220/Discord/PrimeListUserStatus.cs | 6 + .../SS220/PrimeWhitelist/WhitelistSystem.cs | 156 ------------------ Content.Shared/CCVar/CCVars.cs | 36 +--- 9 files changed, 59 insertions(+), 203 deletions(-) create mode 100644 Content.Server/SS220/Discord/PrimeListUserStatus.cs delete mode 100644 Content.Server/SS220/PrimeWhitelist/WhitelistSystem.cs diff --git a/Content.Packaging/ServerPackaging.cs b/Content.Packaging/ServerPackaging.cs index 02e902c0ec2e..ce7371be7c32 100644 --- a/Content.Packaging/ServerPackaging.cs +++ b/Content.Packaging/ServerPackaging.cs @@ -48,7 +48,6 @@ public static class ServerPackaging // SS220 extra assemblies begin "FFMpegCore", "MySqlConnector", - "Pomelo.EntityFrameworkCore.MySql", "Instances" // SS220 extra assemblies end }; diff --git a/Content.Server/Connection/ConnectionManager.cs b/Content.Server/Connection/ConnectionManager.cs index 63a92e585ab4..d0e55a1f5feb 100644 --- a/Content.Server/Connection/ConnectionManager.cs +++ b/Content.Server/Connection/ConnectionManager.cs @@ -1,11 +1,10 @@ using System.Collections.Immutable; -using System.Text.Json.Nodes; using System.Threading.Tasks; using Content.Server.Corvax.Sponsors; using Content.Server.Database; using Content.Server.GameTicking; using Content.Server.Preferences.Managers; -using Content.Server.SS220.PrimeWhitelist; +using Content.Server.SS220.Discord; using Content.Shared.CCVar; using Content.Shared.Corvax.CCCVars; using Content.Shared.GameTicking; @@ -35,8 +34,8 @@ public sealed class ConnectionManager : IConnectionManager [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly SponsorsManager _sponsorsManager = default!; // Corvax-Sponsors [Dependency] private readonly ILocalizationManager _loc = default!; - [Dependency] private readonly Primelist _primelist = default!; [Dependency] private readonly ServerDbEntryManager _serverDbEntry = default!; + [Dependency] private readonly DiscordPlayerManager _discordPlayerManager = default!; public void Initialize() { @@ -186,14 +185,22 @@ private async Task NetMgrOnConnecting(NetConnectingArgs e) return (ConnectionDenyReason.Ban, message, bans); } + // SS220 prime list restriction start if (_cfg.GetCVar(CCVars.PrimelistEnabled)) { - if (!await _primelist.IsPrimelisted(e.UserName.ToLower())) + var primeAccessStatus = await _discordPlayerManager.GetUserPrimeListStatus(userId); + + if (primeAccessStatus is null) { - var msg = Loc.GetString(_cfg.GetCVar(CCVars.WhitelistReason)); - return (ConnectionDenyReason.Whitelist, msg, null); + return (ConnectionDenyReason.Whitelist, "Статус доступа на prime не был получен. Попробуйте переподключиться к серверу.", null); + } + + if (!string.IsNullOrWhiteSpace(primeAccessStatus.PrimeAccessNotAvailableReason)) + { + return (ConnectionDenyReason.Whitelist, primeAccessStatus.PrimeAccessNotAvailableReason, null); } } + // SS220 prime list restriction end if (_cfg.GetCVar(CCVars.WhitelistEnabled)) { var min = _cfg.GetCVar(CCVars.WhitelistMinPlayers); diff --git a/Content.Server/Content.Server.csproj b/Content.Server/Content.Server.csproj index 95f4bb1e42cb..c5b18affbeb9 100644 --- a/Content.Server/Content.Server.csproj +++ b/Content.Server/Content.Server.csproj @@ -14,10 +14,9 @@ true - + - - + diff --git a/Content.Server/Entry/EntryPoint.cs b/Content.Server/Entry/EntryPoint.cs index dcd0d2e228da..98bbadd19bdf 100644 --- a/Content.Server/Entry/EntryPoint.cs +++ b/Content.Server/Entry/EntryPoint.cs @@ -23,7 +23,6 @@ using Content.Server.ServerInfo; using Content.Server.ServerUpdates; using Content.Server.SS220.Discord; -using Content.Server.SS220.PrimeWhitelist; using Content.Server.Voting.Managers; using Content.Shared.CCVar; using Content.Shared.Kitchen; @@ -113,7 +112,6 @@ public override void Init() IoCManager.Resolve().Initialize(); // Corvax-Queue IoCManager.Resolve().Initialize(); // Corvax-TTS IoCManager.Resolve().Initialize(); - IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); // SS220 discord player manager IoCManager.Resolve().Initialize(); // SS220 discord ban post manager IoCManager.Resolve().Initialize(); diff --git a/Content.Server/IoC/ServerContentIoC.cs b/Content.Server/IoC/ServerContentIoC.cs index a98992b856b4..abe2b90d2c26 100644 --- a/Content.Server/IoC/ServerContentIoC.cs +++ b/Content.Server/IoC/ServerContentIoC.cs @@ -23,7 +23,6 @@ using Content.Server.ServerUpdates; using Content.Server.SS220.BackEndApi; using Content.Server.SS220.Discord; -using Content.Server.SS220.PrimeWhitelist; using Content.Server.Voting.Managers; using Content.Server.Worldgen.Tools; using Content.Shared.Administration.Logs; @@ -67,7 +66,6 @@ public static void Register() IoCManager.Register(); // Corvax-DiscordAuth IoCManager.Register(); IoCManager.Register(); - IoCManager.Register(); IoCManager.Register(); // SS220 discord player manager IoCManager.Register(); // SS220 discord ban post manager IoCManager.Register(); diff --git a/Content.Server/SS220/Discord/DiscordPlayerManager.cs b/Content.Server/SS220/Discord/DiscordPlayerManager.cs index 8efcc3bd9323..2d9dd5085d1b 100644 --- a/Content.Server/SS220/Discord/DiscordPlayerManager.cs +++ b/Content.Server/SS220/Discord/DiscordPlayerManager.cs @@ -179,5 +179,40 @@ private static string CreateSecureRandomString(int count = 32) { return Convert.ToBase64String(RandomNumberGenerator.GetBytes(count)); } + + public async Task GetUserPrimeListStatus(Guid userId) + { + if (string.IsNullOrEmpty(_apiUrl)) + { + return null; + } + + try + { + var url = $"{_apiUrl}/checkPrimeAccess/{userId}"; + + var response = await _httpClient.GetAsync(url); + + if (response.StatusCode != HttpStatusCode.OK) + { + var errorText = await response.Content.ReadAsStringAsync(); + + _sawmill.Error( + "Failed to get user prime list status: [{StatusCode}] {Response}", + response.StatusCode, + errorText); + + return null; + } + + return await response.Content.ReadFromJsonAsync(GetJsonSerializerOptions()); + } + catch (Exception exc) + { + _sawmill.Error(exc.Message); + } + + return null; + } } diff --git a/Content.Server/SS220/Discord/PrimeListUserStatus.cs b/Content.Server/SS220/Discord/PrimeListUserStatus.cs new file mode 100644 index 000000000000..850b33e4ef57 --- /dev/null +++ b/Content.Server/SS220/Discord/PrimeListUserStatus.cs @@ -0,0 +1,6 @@ +namespace Content.Server.SS220.Discord; + +public sealed class PrimeListUserStatus +{ + public string? PrimeAccessNotAvailableReason { get; set; } +} diff --git a/Content.Server/SS220/PrimeWhitelist/WhitelistSystem.cs b/Content.Server/SS220/PrimeWhitelist/WhitelistSystem.cs deleted file mode 100644 index d15ea9a17083..000000000000 --- a/Content.Server/SS220/PrimeWhitelist/WhitelistSystem.cs +++ /dev/null @@ -1,156 +0,0 @@ -// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt - -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Threading.Tasks; -using Content.Shared.CCVar; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Diagnostics; -using MySqlConnector; -using Robust.Shared.Configuration; - -namespace Content.Server.SS220.PrimeWhitelist; - -internal sealed class PrimelistDb -{ - private readonly DbContextOptions _options; - private readonly ISawmill _sawmill = Logger.GetSawmill("prime"); - - public PrimelistDb(DbContextOptions options) - { - _options = options; - } - - private async Task GetDb() - { - return new DbGuard(new PrimelistDbContext(_options)); - } - - public async Task GetPrimelistRecord(string ckey) - { - await using var db = await GetDb(); - var query = db.PgDbContext.Whitelist - .Where(p =>p.Ckey==ckey&&p.IsValid).OrderByDescending(p=>p.Date); - try - { - var whitelist = await query.FirstOrDefaultAsync(); - return whitelist; - } - catch (Exception e) - { - _sawmill.Debug($"Exception occured: ${e}"); - return null; - } - } - - public sealed class PrimelistDbContext : DbContext - { - public PrimelistDbContext(DbContextOptions options) : base(options) - { - } - - public DbSet Whitelist { get; set; } = null!; - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity() - .HasIndex(p => p.Id) - .IsUnique(); - } - - protected override void OnConfiguring(DbContextOptionsBuilder options) - { - options.ConfigureWarnings(x => - { - x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning); -#if DEBUG - // for tests - x.Ignore(CoreEventId.SensitiveDataLoggingEnabledWarning); -#endif - }); - -#if DEBUG - options.EnableSensitiveDataLogging(); -#endif - } - } - - private sealed class DbGuard - { - public DbGuard(PrimelistDbContext dbC) - { - PgDbContext = dbC; - } - - public PrimelistDbContext PgDbContext { get; } - - public ValueTask DisposeAsync() - { - return PgDbContext.DisposeAsync(); - } - } - - - [Table("ckey_whitelist")] - public record PrimelistWhitelist - { - [Column("id")] public int Id { get; set; } - [Column("date")] public DateTime Date { get; set; } - [Column("ckey")] public string Ckey { get; set; } = null!; - [Column("adminwho")] public string AdminWho { get; set; } = null!; - [Column("port")] public uint Port { get; set; } - [Column("date_start")] public DateTime DateStart { get; set; } - [Column("date_end")] public DateTime? DateEnd { get; set; } - [Column("is_valid")] public bool IsValid { get; set; } - } -} - -public sealed class Primelist -{ - [Dependency] private readonly IConfigurationManager _cfg = default!; - - private PrimelistDb _db = default!; - - private ISawmill _sawmill = default!; - - public void Initialize() - { - _sawmill = Logger.GetSawmill("primelist"); - var host = _cfg.GetCVar(CCVars.PrimelistDatabaseIp); - var port = _cfg.GetCVar(CCVars.PrimelistDatabasePort); - var db = _cfg.GetCVar(CCVars.PrimelistDatabaseName); - var user = _cfg.GetCVar(CCVars.PrimelistDatabaseUsername); - var pass = _cfg.GetCVar(CCVars.PrimelistDatabasePassword); - - var builder = new DbContextOptionsBuilder(); - var connectionString = new MySqlConnectionStringBuilder() - { - Server = host, - Port = Convert.ToUInt32(port), - Database = db, - UserID = user, - Password = pass, - }.ConnectionString; - - _sawmill.Debug($"Using MySQL \"{host}:{port}/{db}\""); - builder.UseMySql(connectionString, new MariaDbServerVersion(new Version(10, 11 , 2))); - _db = new PrimelistDb(builder.Options); - } - - public async Task IsPrimelisted(string accountName) - { - var record = await _db.GetPrimelistRecord(accountName); - if (record == null) - { - _sawmill.Debug($"{accountName} is not in primelist"); - return false; - } - var now = DateTime.UtcNow; - record.DateEnd ??= DateTime.MaxValue; - var check = now >= record.DateStart && (now <= record.DateEnd || record.DateEnd == DateTime.MinValue); - if (check) - return true; - _sawmill.Debug($"{accountName} record is outdated, from {record.DateStart} to {record.DateEnd}"); - return false; - } -} diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 141b9348f0af..82883c2cf3f0 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -1091,9 +1091,9 @@ public static readonly CVarDef /// /// Whether monstermos explosive depressurization will rip tiles.. /// Needs and to be enabled to work. - /// WARNING: This cvar causes MAJOR contrast issues, and usually tends to make any spaced scene look very cluttered. - /// This not only usually looks strange, but can also reduce playability for people with impaired vision. Please think twice before enabling this on your server. - /// Also looks weird on slow spacing for unrelated reasons. If you do want to enable this, you should probably turn on instaspacing. + /// WARNING: This cvar causes MAJOR contrast issues, and usually tends to make any spaced scene look very cluttered. + /// This not only usually looks strange, but can also reduce playability for people with impaired vision. Please think twice before enabling this on your server. + /// Also looks weird on slow spacing for unrelated reasons. If you do want to enable this, you should probably turn on instaspacing. /// public static readonly CVarDef MonstermosRipTiles = CVarDef.Create("atmos.monstermos_rip_tiles", false, CVar.SERVERONLY); @@ -1296,36 +1296,6 @@ public static readonly CVarDef public static readonly CVarDef PrimelistEnabled = CVarDef.Create("primelist.enabled", false, CVar.SERVERONLY); - /// - /// IP address of the Prime database server - /// - public static readonly CVarDef PrimelistDatabaseIp = - CVarDef.Create("primelist.ip", string.Empty, CVar.SERVERONLY); - - /// - /// Port of the Prime database server - /// - public static readonly CVarDef PrimelistDatabasePort = - CVarDef.Create("primelist.port", 3306, CVar.SERVERONLY); - - /// - /// Name of the Prime database server - /// - public static readonly CVarDef PrimelistDatabaseName = - CVarDef.Create("primelist.database", string.Empty, CVar.SERVERONLY); - - /// - /// Username for the Prime database server - /// - public static readonly CVarDef PrimelistDatabaseUsername = - CVarDef.Create("primelist.username", string.Empty, CVar.SERVERONLY | CVar.CONFIDENTIAL); - - /// - /// Password for the Prime database server - /// - public static readonly CVarDef PrimelistDatabasePassword = - CVarDef.Create("primelist.password", string.Empty, CVar.SERVERONLY | CVar.CONFIDENTIAL); - /* * VOTE */