mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-07-18 03:23:07 +01:00
User fixes [TGSDeploy]
This commit is contained in:
@@ -534,7 +534,13 @@ namespace Tgstation.Server.Host.Controllers
|
||||
if (!AuthenticationContext.User.InstanceManagerRights.Value.HasFlag(InstanceManagerRights.List))
|
||||
query = query
|
||||
.Where(x => x.InstanceUsers.Any(y => y.UserId == AuthenticationContext.User.Id))
|
||||
.Where(x => x.InstanceUsers.Any(y => y.AnyRights));
|
||||
.Where(x => x.InstanceUsers.Any(instanceUser =>
|
||||
instanceUser.ByondRights != ByondRights.None ||
|
||||
instanceUser.ChatBotRights != ChatBotRights.None ||
|
||||
instanceUser.ConfigurationRights != ConfigurationRights.None ||
|
||||
instanceUser.DreamDaemonRights != DreamDaemonRights.None ||
|
||||
instanceUser.DreamMakerRights != DreamMakerRights.None ||
|
||||
instanceUser.InstanceUserRights != InstanceUserRights.None));
|
||||
|
||||
// Hack for EF IAsyncEnumerable BS
|
||||
return query.Select(x => x);
|
||||
@@ -589,7 +595,13 @@ namespace Tgstation.Server.Host.Controllers
|
||||
if (instance == null)
|
||||
return StatusCode((int)HttpStatusCode.Gone);
|
||||
|
||||
if (cantList && !instance.InstanceUsers.Any(x => x.UserId == AuthenticationContext.User.Id && x.AnyRights))
|
||||
if (cantList && !instance.InstanceUsers.Any(instanceUser => instanceUser.UserId == AuthenticationContext.User.Id &&
|
||||
(instanceUser.ByondRights != ByondRights.None ||
|
||||
instanceUser.ChatBotRights != ChatBotRights.None ||
|
||||
instanceUser.ConfigurationRights != ConfigurationRights.None ||
|
||||
instanceUser.DreamDaemonRights != DreamDaemonRights.None ||
|
||||
instanceUser.DreamMakerRights != DreamMakerRights.None ||
|
||||
instanceUser.InstanceUserRights != InstanceUserRights.None)))
|
||||
return Forbid();
|
||||
|
||||
var api = instance.ToApi();
|
||||
|
||||
@@ -34,11 +34,6 @@ namespace Tgstation.Server.Host.Controllers
|
||||
/// </summary>
|
||||
readonly ICryptographySuite cryptographySuite;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILogger"/> for the <see cref="UserController"/>
|
||||
/// </summary>
|
||||
readonly ILogger<UserController> logger;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="GeneralConfiguration"/> for the <see cref="UserController"/>
|
||||
/// </summary>
|
||||
@@ -51,11 +46,10 @@ namespace Tgstation.Server.Host.Controllers
|
||||
/// <param name="authenticationContextFactory">The <see cref="IAuthenticationContextFactory"/> for the <see cref="ApiController"/></param>
|
||||
/// <param name="systemIdentityFactory">The value of <see cref="systemIdentityFactory"/></param>
|
||||
/// <param name="cryptographySuite">The value of <see cref="cryptographySuite"/></param>
|
||||
/// <param name="logger">The value of <see cref="logger"/></param>
|
||||
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="ApiController"/>.</param>
|
||||
/// <param name="generalConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="generalConfiguration"/></param>
|
||||
public UserController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, ISystemIdentityFactory systemIdentityFactory, ICryptographySuite cryptographySuite, ILogger<UserController> logger, IOptions<GeneralConfiguration> generalConfigurationOptions) : base(databaseContext, authenticationContextFactory, logger, false, true)
|
||||
{
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
this.systemIdentityFactory = systemIdentityFactory ?? throw new ArgumentNullException(nameof(systemIdentityFactory));
|
||||
this.cryptographySuite = cryptographySuite ?? throw new ArgumentNullException(nameof(cryptographySuite));
|
||||
generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions));
|
||||
@@ -69,7 +63,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
/// <returns><see langword="null"/> if <paramref name="model"/> is valid, a <see cref="BadRequestObjectResult"/> otherwise.</returns>
|
||||
BadRequestObjectResult CheckValidName(UserUpdate model, bool newUser)
|
||||
{
|
||||
var userInvalidWithNullName = newUser && model.Name == null;
|
||||
var userInvalidWithNullName = newUser && model.Name == null && model.SystemIdentifier == null;
|
||||
if (userInvalidWithNullName || (model.Name != null && String.IsNullOrWhiteSpace(model.Name)))
|
||||
return BadRequest(new ErrorMessage(ErrorCode.UserMissingName));
|
||||
|
||||
@@ -88,7 +82,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
/// <returns><see langword="null"/> on success, <see cref="BadRequestObjectResult"/> if <paramref name="newPassword"/> is too short.</returns>
|
||||
BadRequestObjectResult TrySetPassword(Models.User dbUser, string newPassword, bool newUser)
|
||||
{
|
||||
newPassword = newPassword ?? String.Empty;
|
||||
newPassword ??= String.Empty;
|
||||
if (newPassword.Length < generalConfiguration.MinimumPasswordLength)
|
||||
return BadRequest(new ErrorMessage(ErrorCode.UserPasswordLength)
|
||||
{
|
||||
@@ -145,13 +139,11 @@ namespace Tgstation.Server.Host.Controllers
|
||||
if (model.SystemIdentifier != null)
|
||||
try
|
||||
{
|
||||
using (var sysIdentity = await systemIdentityFactory.CreateSystemIdentity(dbUser, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
if (sysIdentity == null)
|
||||
return StatusCode((int)HttpStatusCode.Gone);
|
||||
dbUser.Name = sysIdentity.Username;
|
||||
dbUser.SystemIdentifier = sysIdentity.Uid;
|
||||
}
|
||||
using var sysIdentity = await systemIdentityFactory.CreateSystemIdentity(dbUser, cancellationToken).ConfigureAwait(false);
|
||||
if (sysIdentity == null)
|
||||
return StatusCode((int)HttpStatusCode.Gone);
|
||||
dbUser.Name = sysIdentity.Username;
|
||||
dbUser.SystemIdentifier = sysIdentity.Uid;
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
|
||||
@@ -21,16 +21,6 @@ namespace Tgstation.Server.Host.Models
|
||||
[Required]
|
||||
public Instance Instance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="InstanceUser"/> has any instance rights
|
||||
/// </summary>
|
||||
public bool AnyRights => ByondRights != Api.Rights.ByondRights.None ||
|
||||
ChatBotRights != Api.Rights.ChatBotRights.None ||
|
||||
ConfigurationRights != Api.Rights.ConfigurationRights.None ||
|
||||
DreamDaemonRights != Api.Rights.DreamDaemonRights.None ||
|
||||
DreamMakerRights != Api.Rights.DreamMakerRights.None ||
|
||||
InstanceUserRights != Api.Rights.InstanceUserRights.None;
|
||||
|
||||
/// <summary>
|
||||
/// Convert the <see cref="InstanceUser"/> to it's API form
|
||||
/// </summary>
|
||||
|
||||
@@ -178,14 +178,12 @@ namespace Tgstation.Server.Host.Setup
|
||||
|| databaseConfiguration.DatabaseType == DatabaseType.MySql)
|
||||
{
|
||||
await console.WriteAsync("Checking MySQL/MariaDB version...", true, cancellationToken).ConfigureAwait(false);
|
||||
using (var command = testConnection.CreateCommand())
|
||||
{
|
||||
command.CommandText = "SELECT VERSION()";
|
||||
var fullVersion = (string)await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false);
|
||||
await console.WriteAsync(String.Format(CultureInfo.InvariantCulture, "Found {0}", fullVersion), true, cancellationToken).ConfigureAwait(false);
|
||||
var splits = fullVersion.Split('-');
|
||||
databaseConfiguration.MySqlServerVersion = splits.First();
|
||||
}
|
||||
using var command = testConnection.CreateCommand();
|
||||
command.CommandText = "SELECT VERSION()";
|
||||
var fullVersion = (string)await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false);
|
||||
await console.WriteAsync(String.Format(CultureInfo.InvariantCulture, "Found {0}", fullVersion), true, cancellationToken).ConfigureAwait(false);
|
||||
var splits = fullVersion.Split('-');
|
||||
databaseConfiguration.MySqlServerVersion = splits.First();
|
||||
}
|
||||
|
||||
if (!isSqliteDB && !dbExists)
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Tgstation.Server.Tests
|
||||
try
|
||||
{
|
||||
var updatePath = Path.Combine(updatePathRoot, Guid.NewGuid().ToString());
|
||||
var server = new TestingServer(clientFactory, updatePath);
|
||||
using var server = new TestingServer(clientFactory, updatePath);
|
||||
|
||||
if (server.DatabaseType == "Sqlite")
|
||||
Assert.Inconclusive("Cannot run this test on SQLite yet!");
|
||||
@@ -165,7 +165,7 @@ namespace Tgstation.Server.Tests
|
||||
public async Task TestFullStandardOperation()
|
||||
{
|
||||
RequireDiscordToken();
|
||||
var server = new TestingServer(clientFactory, null);
|
||||
using var server = new TestingServer(clientFactory, null);
|
||||
using var serverCts = new CancellationTokenSource();
|
||||
var cancellationToken = serverCts.Token;
|
||||
var serverTask = server.Run(cancellationToken);
|
||||
|
||||
@@ -15,7 +15,7 @@ using Tgstation.Server.Host.Core;
|
||||
|
||||
namespace Tgstation.Server.Tests
|
||||
{
|
||||
sealed class TestingServer : IServer
|
||||
sealed class TestingServer : IServer, IDisposable
|
||||
{
|
||||
public Uri Url { get; }
|
||||
|
||||
@@ -89,7 +89,16 @@ namespace Tgstation.Server.Tests
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
System.IO.Directory.Delete(Directory, true);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
try
|
||||
{
|
||||
System.IO.Directory.Delete(Directory, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
GC.Collect(Int32.MaxValue, GCCollectionMode.Forced, false);
|
||||
Thread.Sleep(3000);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Run(CancellationToken cancellationToken)
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Client;
|
||||
using Tgstation.Server.Host.System;
|
||||
|
||||
namespace Tgstation.Server.Tests
|
||||
{
|
||||
@@ -21,9 +22,10 @@ namespace Tgstation.Server.Tests
|
||||
public async Task Run(CancellationToken cancellationToken)
|
||||
{
|
||||
await TestRetrieveCurrentUser(cancellationToken).ConfigureAwait(false);
|
||||
await TestCreateSysUser(cancellationToken);
|
||||
await TestSpamCreation(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
async Task TestRetrieveCurrentUser(CancellationToken cancellationToken)
|
||||
{
|
||||
var user = await this.client.Read(cancellationToken).ConfigureAwait(false);
|
||||
@@ -33,6 +35,19 @@ namespace Tgstation.Server.Tests
|
||||
Assert.AreEqual(true, user.Enabled);
|
||||
}
|
||||
|
||||
async Task TestCreateSysUser(CancellationToken cancellationToken)
|
||||
{
|
||||
var sysId = Environment.UserName;
|
||||
var update = new UserUpdate
|
||||
{
|
||||
SystemIdentifier = sysId
|
||||
};
|
||||
if (new PlatformIdentifier().IsWindows)
|
||||
await client.Create(update, cancellationToken);
|
||||
else
|
||||
await ApiAssert.ThrowsException<MethodNotSupportedException>(() => client.Create(update, cancellationToken), ErrorCode.RequiresPosixSystemIdentity);
|
||||
}
|
||||
|
||||
async Task TestSpamCreation(CancellationToken cancellationToken)
|
||||
{
|
||||
ICollection<Task<User>> tasks = new List<Task<User>>();
|
||||
|
||||
Reference in New Issue
Block a user