Fix the issue with ulong enums

This commit is contained in:
Jordan Brown
2020-04-09 12:55:39 -04:00
parent 637166d2cc
commit 76745b094b
3 changed files with 58 additions and 6 deletions
@@ -70,5 +70,20 @@ namespace Tgstation.Server.Api.Rights
/// <param name="rightsType">The <see cref="RightsType"/> to check</param>
/// <returns><see langword="true"/> if <paramref name="rightsType"/> is an instance right, <see langword="false"/> otherwise</returns>
public static bool IsInstanceRight(RightsType rightsType) => !(rightsType == RightsType.Administration || rightsType == RightsType.InstanceManager);
/// <summary>
/// Get all rights for a given <typeparamref name="TRight"/>.
/// </summary>
/// <typeparam name="TRight">The <see cref="RightsType"/>.</typeparam>
/// <returns>All rights for the given <typeparamref name="TRight"/>.</returns>
public static TRight AllRights<TRight>() 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);
}
}
}
@@ -34,9 +34,9 @@ namespace Tgstation.Server.Host.Database
{
var admin = new User
{
AdministrationRights = ~AdministrationRights.None,
AdministrationRights = RightsHelper.AllRights<AdministrationRights>(),
CreatedAt = DateTimeOffset.Now,
InstanceManagerRights = ~InstanceManagerRights.None,
InstanceManagerRights = RightsHelper.AllRights<InstanceManagerRights>(),
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);
}
/// <inheritdoc />
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<AdministrationRights>();
admin.InstanceManagerRights = admin.InstanceManagerRights & RightsHelper.AllRights<InstanceManagerRights>();
}
await databaseContext.Save(cancellationToken).ConfigureAwait(false);
}
/// <inheritdoc />
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);
}
/// <summary>
/// Get or create the admin <see cref="User"/>.
/// </summary>
/// <param name="databaseContext">The <see cref="IDatabaseContext"/> to use.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the admin <see cref="User"/> or <see langword="null"/>. If <see langword="null"/>, <see cref="IDatabaseContext.Save(CancellationToken)"/> must be called on <paramref name="databaseContext"/>.</returns>
async Task<User> 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;
}
}
}
@@ -16,6 +16,14 @@ namespace Tgstation.Server.Host.Database
/// <returns>A <see cref="Task"/> representing the running operation</returns>
Task SeedDatabase(IDatabaseContext databaseContext, CancellationToken cancellationToken);
/// <summary>
/// Correct invalid database data caused by previous versions.
/// </summary>
/// <param name="databaseContext">The <see cref="IDatabaseContext"/> to sanitize.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
Task SanitizeDatabase(IDatabaseContext databaseContext, CancellationToken cancellationToken);
/// <summary>
/// Changes the admin password in <see cref="IDatabaseContext"/> back to it's default and enables the account
/// </summary>