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
///