From 76745b094b2e8f5a45d785beebf0391ffa8c1859 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 9 Apr 2020 12:55:39 -0400 Subject: [PATCH] Fix the issue with ulong enums --- .../Rights/RightsHelper.cs | 15 +++++++ .../Database/DatabaseSeeder.cs | 41 ++++++++++++++++--- .../Database/IDatabaseSeeder.cs | 8 ++++ 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/Tgstation.Server.Api/Rights/RightsHelper.cs b/src/Tgstation.Server.Api/Rights/RightsHelper.cs index 52947aaa6d..f2a4772cb0 100644 --- a/src/Tgstation.Server.Api/Rights/RightsHelper.cs +++ b/src/Tgstation.Server.Api/Rights/RightsHelper.cs @@ -70,5 +70,20 @@ namespace Tgstation.Server.Api.Rights /// The to check /// if is an instance right, otherwise public static bool IsInstanceRight(RightsType rightsType) => !(rightsType == RightsType.Administration || rightsType == RightsType.InstanceManager); + + /// + /// Get all rights for a given . + /// + /// The . + /// All rights for the given . + public static TRight AllRights() where TRight : Enum + { + ulong rights = 0; + Type rightsType = typeof(TRight); + foreach (Enum J in Enum.GetValues(rightsType)) + rights = rights | Convert.ToUInt64(J, CultureInfo.InvariantCulture); + + return (TRight)Convert.ChangeType(rights, rightsType, CultureInfo.InvariantCulture); + } } } diff --git a/src/Tgstation.Server.Host/Database/DatabaseSeeder.cs b/src/Tgstation.Server.Host/Database/DatabaseSeeder.cs index 73f5128335..39b45e3255 100644 --- a/src/Tgstation.Server.Host/Database/DatabaseSeeder.cs +++ b/src/Tgstation.Server.Host/Database/DatabaseSeeder.cs @@ -34,9 +34,9 @@ namespace Tgstation.Server.Host.Database { var admin = new User { - AdministrationRights = ~AdministrationRights.None, + AdministrationRights = RightsHelper.AllRights(), CreatedAt = DateTimeOffset.Now, - InstanceManagerRights = ~InstanceManagerRights.None, + InstanceManagerRights = RightsHelper.AllRights(), Name = Api.Models.User.AdminName, CanonicalName = Api.Models.User.AdminName.ToUpperInvariant(), Enabled = true, @@ -52,13 +52,27 @@ namespace Tgstation.Server.Host.Database await databaseContext.Save(cancellationToken).ConfigureAwait(false); } + /// + public async Task SanitizeDatabase(IDatabaseContext databaseContext, CancellationToken cancellationToken) + { + var admin = await GetAdminUser(databaseContext, cancellationToken).ConfigureAwait(false); + if (admin != null) + { + // Fix the issue with ulong enums + // https://github.com/tgstation/tgstation-server/commit/db341d43b3dab74fe3681f5172ca9bfeaafa6b6d#diff-09f06ec4584665cf89bb77b97f5ccfb9R36-R39 + // https://github.com/JamesNK/Newtonsoft.Json/issues/2301 + admin.AdministrationRights = admin.AdministrationRights & RightsHelper.AllRights(); + admin.InstanceManagerRights = admin.InstanceManagerRights & RightsHelper.AllRights(); + } + + await databaseContext.Save(cancellationToken).ConfigureAwait(false); + } + /// public async Task ResetAdminPassword(IDatabaseContext databaseContext, CancellationToken cancellationToken) { - var admin = await databaseContext.Users.Where(x => x.CanonicalName == Api.Models.User.AdminName.ToUpperInvariant()).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false); - if (admin == default) - SeedAdminUser(databaseContext); - else + var admin = await GetAdminUser(databaseContext, cancellationToken).ConfigureAwait(false); + if (admin != null) { admin.Enabled = true; cryptographySuite.SetUserPassword(admin, Api.Models.User.DefaultAdminPassword, false); @@ -66,5 +80,20 @@ namespace Tgstation.Server.Host.Database await databaseContext.Save(cancellationToken).ConfigureAwait(false); } + + /// + /// Get or create the admin . + /// + /// The to use. + /// The for the operation. + /// A resulting in the admin or . If , must be called on . + async Task GetAdminUser(IDatabaseContext databaseContext, CancellationToken cancellationToken) + { + var admin = await databaseContext.Users.Where(x => x.CanonicalName == Api.Models.User.AdminName.ToUpperInvariant()).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false); + if (admin == default) + SeedAdminUser(databaseContext); + + return admin; + } } } diff --git a/src/Tgstation.Server.Host/Database/IDatabaseSeeder.cs b/src/Tgstation.Server.Host/Database/IDatabaseSeeder.cs index 18f9440418..7ff210979a 100644 --- a/src/Tgstation.Server.Host/Database/IDatabaseSeeder.cs +++ b/src/Tgstation.Server.Host/Database/IDatabaseSeeder.cs @@ -16,6 +16,14 @@ namespace Tgstation.Server.Host.Database /// A representing the running operation Task SeedDatabase(IDatabaseContext databaseContext, CancellationToken cancellationToken); + /// + /// Correct invalid database data caused by previous versions. + /// + /// The to sanitize. + /// The for the operation. + /// A representing the running operation. + Task SanitizeDatabase(IDatabaseContext databaseContext, CancellationToken cancellationToken); + /// /// Changes the admin password in back to it's default and enables the account ///