diff --git a/build/analyzers.ruleset b/build/analyzers.ruleset
index 79627376f3..88adfbf857 100644
--- a/build/analyzers.ruleset
+++ b/build/analyzers.ruleset
@@ -16,7 +16,6 @@
-
@@ -744,10 +743,10 @@
-
-
-
-
+
+
+
+
@@ -968,7 +967,6 @@
-
@@ -1028,168 +1026,29 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Tgstation.Server.Host/Components/Byond/ByondExecutableLock.cs b/src/Tgstation.Server.Host/Components/Byond/ByondExecutableLock.cs
index a1a3535225..403b1bfa6a 100644
--- a/src/Tgstation.Server.Host/Components/Byond/ByondExecutableLock.cs
+++ b/src/Tgstation.Server.Host/Components/Byond/ByondExecutableLock.cs
@@ -27,8 +27,8 @@ namespace Tgstation.Server.Host.Components.Byond
DreamMakerPath = dreamMakerPath ?? throw new ArgumentNullException(nameof(dreamMakerPath));
}
- //at one point in design, byond versions were to delete themselves if they werent the active version
- //That changed at some point so these functions are intentioanlly left blank
+ // at one point in design, byond versions were to delete themselves if they weren't the active version
+ // That changed at some point so these functions are intentioanlly left blank
///
public void Dispose() { }
diff --git a/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs b/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs
index 8c597e7d23..73c458f7f0 100644
--- a/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs
+++ b/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs
@@ -24,6 +24,7 @@ namespace Tgstation.Server.Host.Components.Byond
/// The file in which we store the for installations
///
const string VersionFileName = "Version.txt";
+
///
/// The file in which we store the for the active installation
///
@@ -119,6 +120,7 @@ namespace Tgstation.Server.Host.Components.Byond
if (!installed)
installedVersions.Add(versionKey, ourTcs.Task);
}
+
if (installed)
using (cancellationToken.Register(() => ourTcs.SetCanceled()))
{
@@ -126,7 +128,8 @@ namespace Tgstation.Server.Host.Components.Byond
cancellationToken.ThrowIfCancellationRequested();
return;
}
- //okay up to us to install it then
+
+ // okay up to us to install it then
try
{
await eventConsumer.HandleEvent(EventType.ByondInstallStart, new List { versionKey }, cancellationToken).ConfigureAwait(false);
@@ -141,12 +144,12 @@ namespace Tgstation.Server.Host.Components.Byond
await ioManager.ZipToDirectory(versionKey, download, cancellationToken).ConfigureAwait(false);
await byondInstaller.InstallByond(ioManager.ResolvePath(versionKey), version, cancellationToken).ConfigureAwait(false);
- //make sure to do this last because this is what tells us we have a valid version in the future
+ // make sure to do this last because this is what tells us we have a valid version in the future
await ioManager.WriteAllBytes(ioManager.ConcatPath(versionKey, VersionFileName), Encoding.UTF8.GetBytes(version.ToString()), cancellationToken).ConfigureAwait(false);
}
catch (WebException e)
{
- //since the user can easily provide non-exitent version numbers, we'll turn this into a JobException
+ // since the user can easily provide non-exitent version numbers, we'll turn this into a JobException
throw new JobException(String.Format(CultureInfo.InvariantCulture, "Error downloading BYOND version: {0}", e.Message));
}
catch (OperationCanceledException)
@@ -205,9 +208,8 @@ namespace Tgstation.Server.Host.Components.Byond
{
async Task GetActiveVersion()
{
- if (!await ioManager.FileExists(ActiveVersionFileName, cancellationToken).ConfigureAwait(false))
- return null;
- return await ioManager.ReadAllBytes(ActiveVersionFileName, cancellationToken).ConfigureAwait(false);
+ var activeVersionFileExists = await ioManager.FileExists(ActiveVersionFileName, cancellationToken).ConfigureAwait(false);
+ return !activeVersionFileExists ? null : await ioManager.ReadAllBytes(ActiveVersionFileName, cancellationToken).ConfigureAwait(false);
}
var activeVersionBytesTask = GetActiveVersion();
@@ -221,9 +223,10 @@ namespace Tgstation.Server.Host.Components.Byond
if (!await ioManager.FileExists(versionFile, cancellationToken).ConfigureAwait(false))
{
logger.LogInformation("Cleaning unparsable version path: {0}", ioManager.ResolvePath(path));
- await ioManager.DeleteDirectory(path, cancellationToken).ConfigureAwait(false); //cleanup
+ await ioManager.DeleteDirectory(path, cancellationToken).ConfigureAwait(false); // cleanup
return;
}
+
var bytes = await ioManager.ReadAllBytes(versionFile, cancellationToken).ConfigureAwait(false);
var text = Encoding.UTF8.GetString(bytes);
if (Version.TryParse(text, out var version))
@@ -236,8 +239,9 @@ namespace Tgstation.Server.Host.Components.Byond
return;
}
}
+
await ioManager.DeleteDirectory(path, cancellationToken).ConfigureAwait(false);
- };
+ }
await Task.WhenAll(directories.Select(x => ReadVersion(x))).ConfigureAwait(false);
diff --git a/src/Tgstation.Server.Host/Components/Byond/PosixByondInstaller.cs b/src/Tgstation.Server.Host/Components/Byond/PosixByondInstaller.cs
index 3c25ac9175..6d741bb952 100644
--- a/src/Tgstation.Server.Host/Components/Byond/PosixByondInstaller.cs
+++ b/src/Tgstation.Server.Host/Components/Byond/PosixByondInstaller.cs
@@ -1,11 +1,9 @@
using Microsoft.Extensions.Logging;
using System;
using System.Globalization;
-using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.IO;
namespace Tgstation.Server.Host.Components.Byond
@@ -18,7 +16,8 @@ namespace Tgstation.Server.Host.Components.Byond
///
/// The URL format string for getting BYOND linux version {0}.{1} zipfile
///
- const string ByondRevisionsURL = "https://secure.byond.com/download/build/{0}/{0}.{1}_byond_linux.zip";
+ const string ByondRevisionsURLTemplate = "https://secure.byond.com/download/build/{0}/{0}.{1}_byond_linux.zip";
+
///
/// Path to the BYOND cache
///
@@ -85,7 +84,7 @@ namespace Tgstation.Server.Host.Components.Byond
if (version == null)
throw new ArgumentNullException(nameof(version));
- var url = String.Format(CultureInfo.InvariantCulture, ByondRevisionsURL, version.Major, version.Minor);
+ var url = String.Format(CultureInfo.InvariantCulture, ByondRevisionsURLTemplate, version.Major, version.Minor);
return await ioManager.DownloadFile(new Uri(url), cancellationToken).ConfigureAwait(false);
}
@@ -98,8 +97,8 @@ namespace Tgstation.Server.Host.Components.Byond
if (version == null)
throw new ArgumentNullException(nameof(version));
- //write the scripts for running the ting
- //need to add $ORIGIN to LD_LIBRARY_PATH
+ // write the scripts for running the ting
+ // need to add $ORIGIN to LD_LIBRARY_PATH
const string StandardScript = "#!/bin/sh\nexport LD_LIBRARY_PATH=\"\\$ORIGIN:$LD_LIBRARY_PATH\"\nBASEDIR=$(dirname \"$0\")\nexec \"$BASEDIR/{0}\" \"$@\"\n";
var dreamDaemonScript = String.Format(CultureInfo.InvariantCulture, StandardScript, DreamDaemonExecutableName);
diff --git a/src/Tgstation.Server.Host/Components/Byond/WindowsByondInstaller.cs b/src/Tgstation.Server.Host/Components/Byond/WindowsByondInstaller.cs
index c3f051fa60..e4b46e5384 100644
--- a/src/Tgstation.Server.Host/Components/Byond/WindowsByondInstaller.cs
+++ b/src/Tgstation.Server.Host/Components/Byond/WindowsByondInstaller.cs
@@ -17,19 +17,23 @@ namespace Tgstation.Server.Host.Components.Byond
///
/// The URL format string for getting BYOND windows version {0}.{1} zipfile
///
- const string ByondRevisionsURL = "https://secure.byond.com/download/build/{0}/{0}.{1}_byond.zip";
+ const string ByondRevisionsURLTemplate = "https://secure.byond.com/download/build/{0}/{0}.{1}_byond.zip";
+
///
/// Directory to byond installation configuration
///
const string ByondConfigDir = "byond/cfg";
+
///
/// BYOND's DreamDaemon config file
///
const string ByondDDConfig = "daemon.txt";
+
///
/// Setting to add to to suppress an invisible user prompt for running a trusted mode .dmb
///
const string ByondNoPromptTrustedMode = "trusted-check 0";
+
///
/// The directory that contains the BYOND directx redistributable
///
@@ -105,7 +109,7 @@ namespace Tgstation.Server.Host.Components.Byond
///
public Task DownloadVersion(Version version, CancellationToken cancellationToken)
{
- var url = String.Format(CultureInfo.InvariantCulture, ByondRevisionsURL, version.Major, version.Minor);
+ var url = String.Format(CultureInfo.InvariantCulture, ByondRevisionsURLTemplate, version.Major, version.Minor);
return ioManager.DownloadFile(new Uri(url), cancellationToken);
}
@@ -118,20 +122,21 @@ namespace Tgstation.Server.Host.Components.Byond
var configPath = ioManager.ConcatPath(path, ByondConfigDir);
await ioManager.CreateDirectory(configPath, cancellationToken).ConfigureAwait(false);
await ioManager.WriteAllBytes(ioManager.ConcatPath(configPath, ByondDDConfig), Encoding.UTF8.GetBytes(ByondNoPromptTrustedMode), cancellationToken).ConfigureAwait(false);
- };
+ }
var setNoPromptTrustedModeTask = SetNoPromptTrusted();
- //after this version lummox made DD depend of directx lol
- //but then he became amazing and not only fixed it but also gave us 30s compiles \[T]/
+ // after this version lummox made DD depend of directx lol
+ // but then he became amazing and not only fixed it but also gave us 30s compiles \[T]/
if (version.Major == 512 && version.Minor >= 1427 && version.Minor < 1452 && !installedDirectX)
using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false))
- //check again because race conditions
if (!installedDirectX)
{
- //always install it, it's pretty fast and will do better redundancy checking than us
+ // ^check again because race conditions
+ // always install it, it's pretty fast and will do better redundancy checking than us
var rbdx = ioManager.ConcatPath(path, ByondDXDir);
- //noShellExecute because we aren't doing runas shennanigans
+
+ // noShellExecute because we aren't doing runas shennanigans
IProcess directXInstaller;
try
{
@@ -141,6 +146,7 @@ namespace Tgstation.Server.Host.Components.Byond
{
throw new JobException("Unable to start DirectX installer process! Is the server running with admin privileges?", e);
}
+
using (directXInstaller)
{
int exitCode;
diff --git a/src/Tgstation.Server.Host/Components/Chat/Chat.cs b/src/Tgstation.Server.Host/Components/Chat/Chat.cs
index fc7321af84..7d44827d44 100644
--- a/src/Tgstation.Server.Host/Components/Chat/Chat.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/Chat.cs
@@ -177,6 +177,7 @@ namespace Tgstation.Server.Host.Components.Chat
else
task = Task.CompletedTask;
}
+
await task.ConfigureAwait(false);
return provider;
}
@@ -190,7 +191,7 @@ namespace Tgstation.Server.Host.Components.Chat
/// A representing the running operation
async Task ProcessMessage(IProvider provider, Message message, CancellationToken cancellationToken)
{
- //map the channel if it's private and we haven't seen it
+ // map the channel if it's private and we haven't seen it
lock (providers)
{
var providerId = providers.Where(x => x.Value == provider).Select(x => x.Key).First();
@@ -219,7 +220,7 @@ namespace Tgstation.Server.Host.Components.Chat
}
else
{
- //need to add tag and isAdminChannel
+ // need to add tag and isAdminChannel
var mapping = enumerable.First().Value;
message.User.Channel.Id = mapping.Channel.Id;
message.User.Channel.Tag = mapping.Channel.Tag;
@@ -236,8 +237,8 @@ namespace Tgstation.Server.Host.Components.Chat
var addressed = address == CommonMention.ToUpperInvariant() || address == provider.BotMention.ToUpperInvariant();
+ // no mention
if (!addressed && !message.User.Channel.IsPrivateChannel)
- //no mention
return;
logger.LogTrace("Chat command: {0}. User (True provider Id): {1}", message.Content, JsonConvert.SerializeObject(message.User));
@@ -247,7 +248,7 @@ namespace Tgstation.Server.Host.Components.Chat
if (splits.Count == 0)
{
- //just a mention
+ // just a mention
await SendMessage("Hi!", new List { message.User.Channel.RealId }, cancellationToken).ConfigureAwait(false);
return;
}
@@ -266,8 +267,9 @@ namespace Tgstation.Server.Host.Components.Chat
await Task.WhenAll(tasks).ConfigureAwait(false);
handler = tasks.SelectMany(x => x.Result).Where(x => x.Name.ToUpperInvariant() == commandName).FirstOrDefault();
}
+
return handler;
- };
+ }
const string UnknownCommandMessage = "Unknown command! Type '?' or 'help' for available commands.";
@@ -290,6 +292,7 @@ namespace Tgstation.Server.Host.Components.Chat
else
helpText = UnknownCommandMessage;
}
+
await SendMessage(helpText, new List { message.User.Channel.RealId }, cancellationToken).ConfigureAwait(false);
return;
}
@@ -318,7 +321,7 @@ namespace Tgstation.Server.Host.Components.Chat
}
catch (Exception e)
{
- //error bc custom commands should reply about why it failed
+ // error bc custom commands should reply about why it failed
logger.LogError("Error processing chat command: {0}", e);
await SendMessage("Internal error processing command!", new List { message.User.Channel.RealId }, cancellationToken).ConfigureAwait(false);
}
@@ -336,11 +339,11 @@ namespace Tgstation.Server.Host.Components.Chat
{
while (!cancellationToken.IsCancellationRequested)
{
- //prune disconnected providers
+ // prune disconnected providers
foreach (var I in messageTasks.Where(x => !x.Key.Connected).ToList())
messageTasks.Remove(I.Key);
- //add new ones
+ // add new ones
Task updatedTask;
lock (this)
updatedTask = connectionsUpdated.Task;
@@ -355,10 +358,10 @@ namespace Tgstation.Server.Host.Components.Chat
continue;
}
- //wait for a message
+ // wait for a message
await Task.WhenAny(updatedTask, Task.WhenAny(messageTasks.Select(x => x.Value))).ConfigureAwait(false);
- //process completed ones
+ // process completed ones
foreach (var I in messageTasks.Where(x => x.Value.IsCompleted).ToList())
{
var message = await I.Value.ConfigureAwait(false);
@@ -385,7 +388,7 @@ namespace Tgstation.Server.Host.Components.Chat
if (provider == null)
return;
var results = await provider.MapChannels(newChannels, cancellationToken).ConfigureAwait(false);
- if (results == null) //aborted
+ if (results == null) // aborted
return;
var mappings = Enumerable.Zip(newChannels, results, (x, y) => new ChannelMapping
{
@@ -407,7 +410,7 @@ namespace Tgstation.Server.Host.Components.Chat
lock (mappedChannels)
{
lock (providers)
- if (!providers.TryGetValue(connectionId, out IProvider verify) || verify != provider) //aborted again
+ if (!providers.TryGetValue(connectionId, out IProvider verify) || verify != provider) // aborted again
return;
foreach (var I in mappings)
{
@@ -419,6 +422,7 @@ namespace Tgstation.Server.Host.Components.Chat
lock (trackingContexts)
task = Task.WhenAll(trackingContexts.Select(x => x.SetChannels(mappedChannels.Select(y => y.Value.Channel), cancellationToken)));
}
+
await task.ConfigureAwait(false);
}
@@ -444,7 +448,7 @@ namespace Tgstation.Server.Host.Components.Chat
Task disconnectTask;
lock (providers)
{
- //raw settings changes forces a rebuild of the provider
+ // raw settings changes forces a rebuild of the provider
if (providers.TryGetValue(newSettings.Id, out provider))
{
providers.Remove(newSettings.Id);
@@ -471,7 +475,7 @@ namespace Tgstation.Server.Host.Components.Chat
await provider.Connect(cancellationToken).ConfigureAwait(false);
lock (this)
{
- //same thread shennanigans
+ // same thread shennanigans
var oldOne = connectionsUpdated;
connectionsUpdated = new TaskCompletionSource();
oldOne.SetResult(null);
@@ -506,7 +510,7 @@ namespace Tgstation.Server.Host.Components.Chat
{
List wdChannels;
message = String.Format(CultureInfo.InvariantCulture, "WD: {0}", message);
- lock (mappedChannels) //so it doesn't change while we're using it
+ lock (mappedChannels) // so it doesn't change while we're using it
wdChannels = mappedChannels.Where(x => x.Value.IsWatchdogChannel).Select(x => x.Key).ToList();
return SendMessage(message, wdChannels, cancellationToken);
}
@@ -516,7 +520,7 @@ namespace Tgstation.Server.Host.Components.Chat
{
List wdChannels;
message = String.Format(CultureInfo.InvariantCulture, "DM: {0}", message);
- lock (mappedChannels) //so it doesn't change while we're using it
+ lock (mappedChannels) // so it doesn't change while we're using it
wdChannels = mappedChannels.Where(x => x.Value.IsUpdatesChannel).Select(x => x.Key).ToList();
return SendMessage(message, wdChannels, cancellationToken);
}
@@ -547,11 +551,17 @@ namespace Tgstation.Server.Host.Components.Chat
if (customCommandHandler == null)
throw new InvalidOperationException("RegisterCommandHandler() hasn't been called!");
JsonTrackingContext context = null;
- context = new JsonTrackingContext(ioManager, customCommandHandler, loggerFactory.CreateLogger(), () =>
- {
- lock (trackingContexts)
- trackingContexts.Remove(context);
- }, ioManager.ConcatPath(basePath, commandsJsonName), ioManager.ConcatPath(basePath, channelsJsonName));
+ context = new JsonTrackingContext(
+ ioManager,
+ customCommandHandler,
+ loggerFactory.CreateLogger(),
+ () =>
+ {
+ lock (trackingContexts)
+ trackingContexts.Remove(context);
+ },
+ ioManager.ConcatPath(basePath, commandsJsonName),
+ ioManager.ConcatPath(basePath, channelsJsonName));
Task task;
lock (trackingContexts)
{
@@ -559,6 +569,7 @@ namespace Tgstation.Server.Host.Components.Chat
lock (mappedChannels)
task = context.SetChannels(mappedChannels.Select(y => y.Value.Channel), cancellationToken);
}
+
await task.ConfigureAwait(false);
return context;
}
@@ -598,7 +609,7 @@ namespace Tgstation.Server.Host.Components.Chat
{
var message = updateVersion == null ? "TGS: Restart requested..." : String.Format(CultureInfo.InvariantCulture, "TGS: Updating to version {0}...", updateVersion);
List wdChannels;
- lock (mappedChannels) //so it doesn't change while we're using it
+ lock (mappedChannels) // so it doesn't change while we're using it
wdChannels = mappedChannels.Select(x => x.Key).ToList();
return SendMessage(message, wdChannels, cancellationToken);
}
diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs
index 90db91a969..e619f6ffeb 100644
--- a/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs
@@ -73,6 +73,7 @@ namespace Tgstation.Server.Host.Components.Chat.Commands
return "Repository unavailable!";
head = repo.Head;
}
+
await databaseContextFactory.UseContext(async db => results = await db.RevisionInformations.Where(x => x.Instance.Id == instance.Id && x.CommitSha == head)
.SelectMany(x => x.ActiveTestMerges)
.Select(x => x.TestMerge)
@@ -89,10 +90,7 @@ namespace Tgstation.Server.Host.Components.Chat.Commands
results = watchdog.ActiveCompileJob?.RevisionInformation.ActiveTestMerges.Select(x => x.TestMerge).ToList() ?? new List();
}
- if (!results.Any())
- return "None!";
-
- return String.Join(", ", results.Select(x => String.Format(CultureInfo.InvariantCulture, "#{0} at {1}", x.Number, x.PullRequestRevision.Substring(0, 7))));
+ return !results.Any() ? "None!" : String.Join(", ", results.Select(x => String.Format(CultureInfo.InvariantCulture, "#{0} at {1}", x.Number, x.PullRequestRevision.Substring(0, 7))));
}
}
}
diff --git a/src/Tgstation.Server.Host/Components/Chat/JsonTrackingContext.cs b/src/Tgstation.Server.Host/Components/Chat/JsonTrackingContext.cs
index 1aee8b6ea7..00f8ade0a5 100644
--- a/src/Tgstation.Server.Host/Components/Chat/JsonTrackingContext.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/JsonTrackingContext.cs
@@ -90,6 +90,7 @@ namespace Tgstation.Server.Host.Components.Chat
{
logger.LogWarning("Error retrieving custom commands! Exception: {0}", e);
}
+
return new List();
}
diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs
index 50996ed74a..fcf6137f0e 100644
--- a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs
@@ -54,7 +54,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
///
/// The mention provided by the Discord library
/// The normalized mention
- static string NormalizeMention(string fromDiscord) => fromDiscord.Replace("!", "", StringComparison.Ordinal);
+ static string NormalizeMention(string fromDiscord) => fromDiscord.Replace("!", String.Empty, StringComparison.Ordinal);
///
/// Construct a
@@ -100,7 +100,8 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
IsPrivateChannel = pm,
ConnectionName = pm ? e.Author.Username : (e.Channel as ITextChannel)?.Guild.Name ?? "UNKNOWN",
FriendlyName = e.Channel.Name
- //isAdmin and Tag populated by manager
+
+ // isAdmin and Tag populated by manager
},
FriendlyName = e.Author.Username,
Mention = NormalizeMention(e.Author.Mention)
@@ -182,19 +183,19 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
if (!channel.DiscordChannelId.HasValue)
throw new InvalidOperationException("ChatChannel missing DiscordChannelId!");
- if (!(client.GetChannel(channel.DiscordChannelId.Value) is ITextChannel discordChannel))
- return null;
+ if (client.GetChannel(channel.DiscordChannelId.Value) is ITextChannel discordChannel)
+ return new Channel
+ {
+ RealId = discordChannel.Id,
+ IsAdminChannel = channel.IsAdminChannel == true,
+ ConnectionName = discordChannel.Guild.Name,
+ FriendlyName = discordChannel.Name,
+ IsPrivateChannel = false,
+ Tag = channel.Tag
+ };
- return new Channel
- {
- RealId = discordChannel.Id,
- IsAdminChannel = channel.IsAdminChannel == true,
- ConnectionName = discordChannel.Guild.Name,
- FriendlyName = discordChannel.Name,
- IsPrivateChannel = false,
- Tag = channel.Tag
- };
- };
+ return null;
+ }
var enumerator = channels.Select(x => GetChannelForChatChannel(x)).Where(x => x != null).ToList();
diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs
index 01fa89697e..8716ad3d0a 100644
--- a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs
@@ -44,18 +44,22 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
/// Address of the server to connect to
///
readonly string address;
+
///
/// Port of the server to connect to
///
readonly ushort port;
+
///
/// IRC nickname
///
readonly string nickname;
+
///
/// Password which will used for authentication
///
readonly string password;
+
///
/// The of
///
@@ -134,7 +138,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
UseSsl = useSsl
};
if (useSsl)
- client.ValidateServerCertificate = true; //dunno if it defaults to that or what
+ client.ValidateServerCertificate = true; // dunno if it defaults to that or what
client.OnChannelMessage += Client_OnChannelMessage;
client.OnQueryMessage += Client_OnQueryMessage;
@@ -151,7 +155,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
if (Connected)
{
disconnecting = true;
- client.Disconnect(); //just closes the socket
+ client.Disconnect(); // just closes the socket
}
}
@@ -184,8 +188,9 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
if (dicToCheck == queryChannelIdMap)
channelIdMap.Add(resultId.Value, null);
}
+
return resultId.Value;
- };
+ }
ulong userId, channelId;
lock (this)
@@ -205,7 +210,8 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
FriendlyName = isPrivate ? String.Format(CultureInfo.InvariantCulture, "PM: {0}", channelName) : channelName,
RealId = channelId,
IsPrivateChannel = isPrivate
- //isAdmin and Tag populated by manager
+
+ // isAdmin and Tag populated by manager
},
FriendlyName = username,
RealId = userId,
@@ -247,7 +253,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
{
if (passwordType == IrcPasswordType.Sasl)
{
- client.WriteLine("CAP REQ :sasl", Priority.Critical); //needs to be put in the buffer before anything else
+ client.WriteLine("CAP REQ :sasl", Priority.Critical); // needs to be put in the buffer before anything else
cancellationToken.ThrowIfCancellationRequested();
}
client.Login(nickname, nickname, 0, nickname);
@@ -260,7 +266,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
else if (passwordType == IrcPasswordType.Sasl)
{
- //wait for the sasl ack or timeout
+ // wait for the sasl ack or timeout
var recievedAck = false;
var recievedPlus = false;
client.OnReadLine += (sender, e) =>
@@ -285,7 +291,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
for (; !recievedPlus && DateTimeOffset.Now <= endTime; asyncDelayer.Delay(listenTimeSpan, cancellationToken).GetAwaiter().GetResult())
client.Listen(false);
- //Stolen! https://github.com/znc/znc/blob/1e697580155d5a38f8b5a377f3b1d94aaa979539/modules/sasl.cpp#L196
+ // Stolen! https://github.com/znc/znc/blob/1e697580155d5a38f8b5a377f3b1d94aaa979539/modules/sasl.cpp#L196
var authString = String.Format(CultureInfo.InvariantCulture, "{0}{1}{0}{1}{2}", nickname, '\0', password);
var b64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(authString));
var authLine = String.Format(CultureInfo.InvariantCulture, "AUTHENTICATE {0}", b64);
@@ -306,7 +312,8 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
if (disconnecting || !client.IsConnected)
break;
client.Listen(false);
- //ensure we have the correct nick
+
+ // ensure we have the correct nick
if (client.GetIrcUser(nickname) == null)
client.RfcNick(nickname);
}
@@ -336,7 +343,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
{
try
{
- client.RfcQuit("Mr. Stark, I don't feel so good...", Priority.Critical); //priocritical otherwise it wont go through
+ client.RfcQuit("Mr. Stark, I don't feel so good...", Priority.Critical); // priocritical otherwise it wont go through
}
catch (Exception e)
{
@@ -363,7 +370,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
throw new InvalidOperationException("ChatChannel missing IrcChannel!");
lock (this)
{
- var hs = new HashSet(); //for unique inserts
+ var hs = new HashSet(); // for unique inserts
foreach (var I in channels)
hs.Add(I.IrcChannel);
var toPart = new List();
diff --git a/src/Tgstation.Server.Host/Controllers/ApiController.cs b/src/Tgstation.Server.Host/Controllers/ApiController.cs
index 3b26db1875..b8d233a96c 100644
--- a/src/Tgstation.Server.Host/Controllers/ApiController.cs
+++ b/src/Tgstation.Server.Host/Controllers/ApiController.cs
@@ -72,17 +72,16 @@ namespace Tgstation.Server.Host.Controllers
///
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
- //ALL valid token and login requests that match a route go through this function
- //404 is returned before
-
+ // ALL valid token and login requests that match a route go through this function
+ // 404 is returned before
if (AuthenticationContext != null && AuthenticationContext.User == null)
{
- //valid token, expired password
+ // valid token, expired password
await Unauthorized().ExecuteResultAsync(context).ConfigureAwait(false);
return;
}
- //validate the headers
+ // validate the headers
try
{
ApiHeaders = new ApiHeaders(Request.GetTypedHeaders());
@@ -103,9 +102,10 @@ namespace Tgstation.Server.Host.Controllers
await BadRequest(new ErrorMessage { Message = "Missing Instance header!" }).ExecuteResultAsync(context).ConfigureAwait(false);
return;
}
+
if (AuthenticationContext.InstanceUser == null)
{
- //accessing an instance they don't have access to or one that's disabled
+ // accessing an instance they don't have access to or one that's disabled
await Forbid().ExecuteResultAsync(context).ConfigureAwait(false);
return;
}
@@ -120,8 +120,9 @@ namespace Tgstation.Server.Host.Controllers
if (ModelState?.IsValid == false)
{
var errorMessages = ModelState.SelectMany(x => x.Value.Errors).Select(x => x.ErrorMessage).ToList();
- //HACK
- //do some fuckery to remove RequiredAttribute errors
+
+ // HACK
+ // do some fuckery to remove RequiredAttribute errors
for (var I = 0; I < errorMessages.Count; ++I)
{
var message = errorMessages[I];
@@ -131,6 +132,7 @@ namespace Tgstation.Server.Host.Controllers
--I;
}
}
+
if (errorMessages.Count > 0)
{
await BadRequest(new ErrorMessage { Message = String.Join(Environment.NewLine, errorMessages) }).ExecuteResultAsync(context).ConfigureAwait(false);
diff --git a/src/Tgstation.Server.Host/Controllers/TgsAuthorizeAttribute.cs b/src/Tgstation.Server.Host/Controllers/TgsAuthorizeAttribute.cs
index d6eb1b25b6..0d52ac6ae1 100644
--- a/src/Tgstation.Server.Host/Controllers/TgsAuthorizeAttribute.cs
+++ b/src/Tgstation.Server.Host/Controllers/TgsAuthorizeAttribute.cs
@@ -7,6 +7,7 @@ namespace Tgstation.Server.Host.Controllers
///
/// Helper for using the with the system
///
+ #pragma warning disable CA1019
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
sealed class TgsAuthorizeAttribute : AuthorizeAttribute
{
@@ -19,54 +20,81 @@ namespace Tgstation.Server.Host.Controllers
/// Construct a for
///
/// The rights required
- public TgsAuthorizeAttribute(AdministrationRights requiredRights) => Roles = RightsHelper.RoleNames(requiredRights);
+ public TgsAuthorizeAttribute(AdministrationRights requiredRights)
+ {
+ Roles = RightsHelper.RoleNames(requiredRights);
+ }
///
/// Construct a for
///
/// The rights required
- public TgsAuthorizeAttribute(InstanceManagerRights requiredRights) => Roles = RightsHelper.RoleNames(requiredRights);
+ public TgsAuthorizeAttribute(InstanceManagerRights requiredRights)
+ {
+ Roles = RightsHelper.RoleNames(requiredRights);
+ }
///
/// Construct a for
///
/// The rights required
- public TgsAuthorizeAttribute(RepositoryRights requiredRights) => Roles = RightsHelper.RoleNames(requiredRights);
+ public TgsAuthorizeAttribute(RepositoryRights requiredRights)
+ {
+ Roles = RightsHelper.RoleNames(requiredRights);
+ }
///
/// Construct a for
///
/// The rights required
- public TgsAuthorizeAttribute(ByondRights requiredRights) => Roles = RightsHelper.RoleNames(requiredRights);
+ public TgsAuthorizeAttribute(ByondRights requiredRights)
+ {
+ Roles = RightsHelper.RoleNames(requiredRights);
+ }
///
/// Construct a for
///
/// The rights required
- public TgsAuthorizeAttribute(DreamMakerRights requiredRights) => Roles = RightsHelper.RoleNames(requiredRights);
+ public TgsAuthorizeAttribute(DreamMakerRights requiredRights)
+ {
+ Roles = RightsHelper.RoleNames(requiredRights);
+ }
///
/// Construct a for
///
/// The rights required
- public TgsAuthorizeAttribute(DreamDaemonRights requiredRights) => Roles = RightsHelper.RoleNames(requiredRights);
+ public TgsAuthorizeAttribute(DreamDaemonRights requiredRights)
+ {
+ Roles = RightsHelper.RoleNames(requiredRights);
+ }
///
/// Construct a for
///
/// The rights required
- public TgsAuthorizeAttribute(ChatBotRights requiredRights) => Roles = RightsHelper.RoleNames(requiredRights);
+ public TgsAuthorizeAttribute(ChatBotRights requiredRights)
+ {
+ Roles = RightsHelper.RoleNames(requiredRights);
+ }
///
/// Construct a for
///
/// The rights required
- public TgsAuthorizeAttribute(ConfigurationRights requiredRights) => Roles = RightsHelper.RoleNames(requiredRights);
+ public TgsAuthorizeAttribute(ConfigurationRights requiredRights)
+ {
+ Roles = RightsHelper.RoleNames(requiredRights);
+ }
///
/// Construct a for
///
/// The rights required
- public TgsAuthorizeAttribute(InstanceUserRights requiredRights) => Roles = RightsHelper.RoleNames(requiredRights);
+ public TgsAuthorizeAttribute(InstanceUserRights requiredRights)
+ {
+ Roles = RightsHelper.RoleNames(requiredRights);
+ }
}
}
diff --git a/src/Tgstation.Server.Host/Core/Application.cs b/src/Tgstation.Server.Host/Core/Application.cs
index 05b5234e0c..f8fe4f1536 100644
--- a/src/Tgstation.Server.Host/Core/Application.cs
+++ b/src/Tgstation.Server.Host/Core/Application.cs
@@ -19,7 +19,6 @@ using System;
using System.Globalization;
using System.IdentityModel.Tokens.Jwt;
using System.Reflection;
-using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Tgstation.Server.Host.Components;
using Tgstation.Server.Host.Components.Byond;
@@ -90,19 +89,19 @@ namespace Tgstation.Server.Host.Core
if (services == null)
throw new ArgumentNullException(nameof(services));
- //needful
+ // needful
services.AddSingleton(this);
- //configure configuration
+ // configure configuration
services.Configure(configuration.GetSection(UpdatesConfiguration.Section));
services.Configure(configuration.GetSection(DatabaseConfiguration.Section));
services.Configure(configuration.GetSection(GeneralConfiguration.Section));
services.Configure(configuration.GetSection(FileLoggingConfiguration.Section));
- //enable options which give us config reloading
+ // enable options which give us config reloading
services.AddOptions();
-
- //other stuff needed for for setup wizard and configuration
+
+ // other stuff needed for for setup wizard and configuration
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
@@ -116,24 +115,23 @@ namespace Tgstation.Server.Host.Core
IIOManager ioManager;
IPlatformIdentifier platformIdentifier;
- //temporarily build the service provider in it's current state
- //do it here so we can run the setup wizard if necessary
- //also allows us to get some options and other services we need for continued configuration
+ // temporarily build the service provider in it's current state
+ // do it here so we can run the setup wizard if necessary
+ // also allows us to get some options and other services we need for continued configuration
using (var provider = services.BuildServiceProvider())
{
- //run the wizard if necessary
+ // run the wizard if necessary
var setupWizard = provider.GetRequiredService();
var applicationLifetime = provider.GetRequiredService();
var setupWizardRan = setupWizard.CheckRunWizard(applicationLifetime.ApplicationStopping).GetAwaiter().GetResult();
- //load the configuration options we need
+ // load the configuration options we need
var generalOptions = provider.GetRequiredService>();
generalConfiguration = generalOptions.Value;
- //unless this is set, in which case, we leave
+ // unless this is set, in which case, we leave
if (setupWizardRan && generalConfiguration.SetupWizardMode == SetupWizardMode.Only)
- //we don't inject a logger in the constuctor to log this because it's not yet configured
- throw new OperationCanceledException("Exiting due to SetupWizardMode configuration!");
+ throw new OperationCanceledException("Exiting due to SetupWizardMode configuration!"); // we don't inject a logger in the constuctor to log this because it's not yet configured
var dbOptions = provider.GetRequiredService>();
databaseConfiguration = dbOptions.Value;
@@ -145,11 +143,11 @@ namespace Tgstation.Server.Host.Core
platformIdentifier = provider.GetRequiredService();
}
- //setup file logging via serilog
+ // setup file logging via serilog
if (!fileLoggingConfiguration.Disable)
services.AddLogging(builder =>
{
- //common app data is C:/ProgramData on windows, else /usr/shar
+ // common app data is C:/ProgramData on windows, else /usr/shar
var logPath = !String.IsNullOrEmpty(fileLoggingConfiguration.Directory) ? fileLoggingConfiguration.Directory : ioManager.ConcatPath(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), VersionPrefix, "Logs");
logPath = ioManager.ConcatPath(logPath, "tgs-{Date}.log");
@@ -175,7 +173,7 @@ namespace Tgstation.Server.Host.Core
default:
throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid log level {0}", logLevel));
}
- };
+ }
var logEventLevel = ConvertLogLevel(fileLoggingConfiguration.LogLevel);
var microsoftEventLevel = ConvertLogLevel(fileLoggingConfiguration.MicrosoftLogLevel);
@@ -195,23 +193,24 @@ namespace Tgstation.Server.Host.Core
builder.AddSerilog(configuration.CreateLogger(), true);
});
- //configure bearer token validation
+ // configure bearer token validation
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(jwtBearerOptions =>
{
- //this line isn't actually run until the first request is made
- //at that point tokenFactory will be populated
+ // this line isn't actually run until the first request is made
+ // at that point tokenFactory will be populated
jwtBearerOptions.TokenValidationParameters = tokenFactory.ValidationParameters;
jwtBearerOptions.Events = new JwtBearerEvents
{
- //Application is our composition root so this monstrosity of a line is okay
+ // Application is our composition root so this monstrosity of a line is okay
OnTokenValidated = ctx => ctx.HttpContext.RequestServices.GetRequiredService().InjectClaimsIntoContext(ctx, ctx.HttpContext.RequestAborted)
};
});
- //fucking converts 'sub' to M$ bs
- //can't be done in the above lambda, that's too late
+
+ // fucking prevents converting 'sub' to M$ bs
+ // can't be done in the above lambda, that's too late
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
- //add mvc, configure the json serializer settings
+ // add mvc, configure the json serializer settings
services.AddMvc().AddJsonOptions(options =>
{
options.AllowInputFormatterExceptionMessages = true;
@@ -232,7 +231,7 @@ namespace Tgstation.Server.Host.Core
services.AddScoped(x => x.GetRequiredService());
}
- //add the correct database context type
+ // add the correct database context type
var dbType = databaseConfiguration.DatabaseType;
switch (dbType)
{
@@ -247,11 +246,11 @@ namespace Tgstation.Server.Host.Core
throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid {0}: {1}!", nameof(DatabaseType), dbType));
}
- //configure other database services
+ // configure other database services
services.AddSingleton();
services.AddSingleton();
- //configure security services
+ // configure security services
services.AddScoped();
services.AddScoped();
services.AddSingleton();
@@ -259,7 +258,7 @@ namespace Tgstation.Server.Host.Core
services.AddSingleton();
services.AddSingleton, PasswordHasher>();
- //configure platform specific services
+ // configure platform specific services
if (platformIdentifier.IsWindows)
{
services.AddSingleton();
@@ -280,7 +279,7 @@ namespace Tgstation.Server.Host.Core
services.AddSingleton();
}
- //configure misc services
+ // configure misc services
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
@@ -290,14 +289,14 @@ namespace Tgstation.Server.Host.Core
SendTimeout = generalConfiguration.ByondTopicTimeout
});
- //configure component services
+ // configure component services
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
- //configure root services
+ // configure root services
services.AddSingleton();
services.AddSingleton(x => x.GetRequiredService());
services.AddSingleton(x => x.GetRequiredService());
@@ -326,38 +325,38 @@ namespace Tgstation.Server.Host.Core
logger.LogInformation(VersionString);
- //attempt to restart the server if the configuration changes
+ // attempt to restart the server if the configuration changes
if(serverControl.WatchdogPresent)
ChangeToken.OnChange(configuration.GetReloadToken, () => serverControl.Restart());
- //now setup the HTTP request pipeline
+ // setup the HTTP request pipeline
- //should anything after this throw an exception, catch it and display a detailed html page
- applicationBuilder.UseDeveloperExceptionPage(); //it is not worth it to limit this, you should only ever get it if you're an authorized user
-
- //suppress OperationCancelledExceptions, they are just aborted HTTP requests
+ // should anything after this throw an exception, catch it and display a detailed html page
+ applicationBuilder.UseDeveloperExceptionPage(); // it is not worth it to limit this, you should only ever get it if you're an authorized user
+
+ // suppress OperationCancelledExceptions, they are just aborted HTTP requests
applicationBuilder.UseCancelledRequestSuppression();
- //Do not service requests until Ready is called, this will return 503 until that point
+ // Do not service requests until Ready is called, this will return 503 until that point
applicationBuilder.UseAsyncInitialization(async cancellationToken =>
{
using (cancellationToken.Register(() => startupTcs.SetCanceled()))
await startupTcs.Task.ConfigureAwait(false);
});
- //authenticate JWT tokens using our security pipeline if present, returns 401 if bad
+ // authenticate JWT tokens using our security pipeline if present, returns 401 if bad
applicationBuilder.UseAuthentication();
- //suppress and log database exceptions
+ // suppress and log database exceptions
applicationBuilder.UseDbConflictHandling();
- //majority of handling is done in the controllers
+ // majority of handling is done in the controllers
applicationBuilder.UseMvc();
- //404 anything that gets this far
+ // 404 anything that gets this far
}
- ///
+ ///
public void Ready(Exception initializationError)
{
lock (startupTcs)
diff --git a/src/Tgstation.Server.Host/Core/JobHandler.cs b/src/Tgstation.Server.Host/Core/JobHandler.cs
index c57c7bdc1f..e09f574581 100644
--- a/src/Tgstation.Server.Host/Core/JobHandler.cs
+++ b/src/Tgstation.Server.Host/Core/JobHandler.cs
@@ -13,6 +13,7 @@ namespace Tgstation.Server.Host.Core
/// The for
///
readonly CancellationTokenSource cancellationTokenSource;
+
///
/// The being run
///
@@ -30,7 +31,7 @@ namespace Tgstation.Server.Host.Core
task = job(cancellationTokenSource.Token);
}
- ///
+ ///
public void Dispose() => cancellationTokenSource.Dispose();
///
diff --git a/src/Tgstation.Server.Host/Core/JobManager.cs b/src/Tgstation.Server.Host/Core/JobManager.cs
index b3aeac331d..bd4d233f9d 100644
--- a/src/Tgstation.Server.Host/Core/JobManager.cs
+++ b/src/Tgstation.Server.Host/Core/JobManager.cs
@@ -69,14 +69,14 @@ namespace Tgstation.Server.Host.Core
/// The for the operation
/// A representing the running operation
async Task RunJob(Job job, Func operation, CancellationToken cancellationToken)
- {
+ {
try
{
await databaseContextFactory.UseContext(async databaseContext =>
{
async Task HandleExceptions(Task task)
{
- void LogRegularException() => logger.LogDebug("Job {0} exited with error! Exception: {1}", job.Id, job.ExceptionDetails);
+ void LogRegularException() => logger.LogDebug("Job {0} exited with error! Exception: {1}", job.Id, job.ExceptionDetails);
try
{
await task.ConfigureAwait(false);
@@ -113,7 +113,7 @@ namespace Tgstation.Server.Host.Core
await operation(job, databaseContext, cancellationToken).ConfigureAwait(false);
logger.LogDebug("Job {0} completed!", job.Id);
- };
+ }
await HandleExceptions(RunJobInternal()).ConfigureAwait(false);
@@ -121,7 +121,7 @@ namespace Tgstation.Server.Host.Core
bool JobErroredOrCancelled() => job.ExceptionDetails != null || job.Cancelled == true;
- //ok so, now it's time for the post commit step if it exists
+ // ok so, now it's time for the post commit step if it exists
if (!JobErroredOrCancelled() && job.PostComplete != null)
{
await HandleExceptions(job.PostComplete(cancellationToken)).ConfigureAwait(false);
@@ -186,7 +186,7 @@ namespace Tgstation.Server.Host.Core
logger.LogTrace("Starting job manager...");
await databaseContextFactory.UseContext(async databaseContext =>
{
- //mark all jobs as cancelled
+ // mark all jobs as cancelled
var badJobs = await databaseContext.Jobs.Where(y => !y.StoppedAt.HasValue).Select(y => y.Id).ToListAsync(cancellationToken).ConfigureAwait(false);
if (badJobs.Count > 0)
{
@@ -229,10 +229,11 @@ namespace Tgstation.Server.Host.Core
}
catch (InvalidOperationException)
{
- //this is fine
+ // this is fine
return false;
}
- handler.Cancel(); //this will ensure the db update is only done once
+
+ handler.Cancel(); // this will ensure the db update is only done once
await databaseContextFactory.UseContext(async databaseContext =>
{
job = new Job { Id = job.Id };
@@ -240,7 +241,8 @@ namespace Tgstation.Server.Host.Core
user = new User { Id = user.Id };
databaseContext.Users.Attach(user);
job.CancelledBy = user;
- //let either startup or cancellation set job.cancelled
+
+ // let either startup or cancellation set job.cancelled
await databaseContext.Save(cancellationToken).ConfigureAwait(false);
}).ConfigureAwait(false);
if (blocking)
@@ -274,6 +276,7 @@ namespace Tgstation.Server.Host.Core
if (!jobs.TryGetValue(job.Id, out handler))
return;
}
+
Task cancelTask = null;
using (jobCancellationToken.Register(() => cancelTask = CancelJob(job, canceller, true, cancellationToken)))
await handler.Wait(cancellationToken).ConfigureAwait(false);
diff --git a/src/Tgstation.Server.Host/Core/ProcessExecutor.cs b/src/Tgstation.Server.Host/Core/ProcessExecutor.cs
index 2786af6c83..7c1d5274eb 100644
--- a/src/Tgstation.Server.Host/Core/ProcessExecutor.cs
+++ b/src/Tgstation.Server.Host/Core/ProcessExecutor.cs
@@ -38,6 +38,7 @@ namespace Tgstation.Server.Host.Core
{
return;
}
+
tcs.SetResult(exitCode);
};
return tcs.Task;
@@ -68,6 +69,7 @@ namespace Tgstation.Server.Host.Core
logger.LogDebug("Unable to get process {0}! Exception: {1}", id, e);
return null;
}
+
try
{
return new Process(handle, AttachExitHandler(handle), null, null, null, loggerFactory.CreateLogger(), true);
@@ -108,6 +110,7 @@ namespace Tgstation.Server.Host.Core
outputStringBuilder.Append(e.Data);
};
}
+
if (readError)
{
errorStringBuilder = new StringBuilder();
diff --git a/src/Tgstation.Server.Host/Core/SemaphoreSlimContext.cs b/src/Tgstation.Server.Host/Core/SemaphoreSlimContext.cs
index d16b7ae628..8c78b4570f 100644
--- a/src/Tgstation.Server.Host/Core/SemaphoreSlimContext.cs
+++ b/src/Tgstation.Server.Host/Core/SemaphoreSlimContext.cs
@@ -38,10 +38,13 @@ namespace Tgstation.Server.Host.Core
/// Construct a
///
/// The value of
- SemaphoreSlimContext(SemaphoreSlim lockedSemaphore) => this.lockedSemaphore = lockedSemaphore;
+ SemaphoreSlimContext(SemaphoreSlim lockedSemaphore)
+ {
+ this.lockedSemaphore = lockedSemaphore;
+ }
///
- /// Finalize the
+ /// Finalizes an instance of the class.
///
#pragma warning disable CA1821 // Remove empty Finalizers //TODO remove this when https://github.com/dotnet/roslyn-analyzers/issues/1241 is fixed
~SemaphoreSlimContext() => Dispose();
@@ -58,6 +61,7 @@ namespace Tgstation.Server.Host.Core
return;
disposed = true;
}
+
GC.SuppressFinalize(this);
lockedSemaphore.Release();
}
diff --git a/src/Tgstation.Server.Host/Core/SetupWizard.cs b/src/Tgstation.Server.Host/Core/SetupWizard.cs
index 83b6456fe3..df7df8e590 100644
--- a/src/Tgstation.Server.Host/Core/SetupWizard.cs
+++ b/src/Tgstation.Server.Host/Core/SetupWizard.cs
@@ -8,7 +8,6 @@ using System.Collections.Generic;
using System.Data.Common;
using System.Data.SqlClient;
using System.Globalization;
-using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -158,6 +157,7 @@ namespace Tgstation.Server.Host.Core
databaseConfiguration.DatabaseType = databaseType;
break;
}
+
await console.WriteAsync("Invalid database type!", true, cancellationToken).ConfigureAwait(false);
}
while (true);
@@ -171,7 +171,6 @@ namespace Tgstation.Server.Host.Core
await console.WriteAsync(null, true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync("Enter the database name (Can be from previous installation. Otherwise, should not exist): ", false, cancellationToken).ConfigureAwait(false);
string databaseName;
-
do
{
databaseName = await console.ReadLineAsync(false, cancellationToken).ConfigureAwait(false);
@@ -206,6 +205,7 @@ namespace Tgstation.Server.Host.Core
await console.WriteAsync("The account it uses in MSSQL is usually \"NT AUTHORITY\\SYSTEM\" and the role it needs is usually \"dbcreator\".", true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync("We'll run a sanity test here, but it won't be indicative of the service's permissions if that is the case", true, cancellationToken).ConfigureAwait(false);
}
+
await console.WriteAsync(null, true, cancellationToken).ConfigureAwait(false);
DbConnection testConnection;
@@ -261,7 +261,7 @@ namespace Tgstation.Server.Host.Core
using (var command = testConnection.CreateCommand())
{
command.CommandText = "SELECT VERSION()";
- var fullVersion = (string)(await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false));
+ 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[0];
@@ -276,6 +276,7 @@ namespace Tgstation.Server.Host.Core
command.CommandText = String.Format(CultureInfo.InvariantCulture, "CREATE DATABASE {0}", databaseName);
await command.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
}
+
await console.WriteAsync("Success!", true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync("Dropping test database...", true, cancellationToken).ConfigureAwait(false);
using (var command = testConnection.CreateCommand())
@@ -313,7 +314,8 @@ namespace Tgstation.Server.Host.Core
await console.WriteAsync(null, true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync("Retrying database configuration...", true, cancellationToken).ConfigureAwait(false);
}
- } while (true);
+ }
+ while (true);
}
///
@@ -339,6 +341,7 @@ namespace Tgstation.Server.Host.Core
newGeneralConfiguration.MinimumPasswordLength = passwordLength;
break;
}
+
await console.WriteAsync("Please enter a positive integer!", true, cancellationToken).ConfigureAwait(false);
}
while (true);
@@ -355,6 +358,7 @@ namespace Tgstation.Server.Host.Core
newGeneralConfiguration.ByondTopicTimeout = topicTimeout;
break;
}
+
await console.WriteAsync("Please enter a positive integer!", true, cancellationToken).ConfigureAwait(false);
}
while (true);
@@ -390,7 +394,8 @@ namespace Tgstation.Server.Host.Core
fileLoggingConfiguration.Directory = null;
break;
}
- //test a write of it
+
+ // test a write of it
await console.WriteAsync(null, true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync("Testing directory access...", true, cancellationToken).ConfigureAwait(false);
try
@@ -412,6 +417,7 @@ namespace Tgstation.Server.Host.Core
await console.WriteAsync(e.Message, true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync(null, true, cancellationToken).ConfigureAwait(false);
}
+
break;
}
catch (OperationCanceledException)
@@ -424,7 +430,8 @@ namespace Tgstation.Server.Host.Core
await console.WriteAsync(null, true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync("Please verify the path is valid and you have access to it!", true, cancellationToken).ConfigureAwait(false);
}
- } while (true);
+ }
+ while (true);
async Task PromptLogLevel(string question)
{
@@ -432,19 +439,21 @@ namespace Tgstation.Server.Host.Core
{
await console.WriteAsync(null, true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync(question, true, cancellationToken).ConfigureAwait(false);
- await console.WriteAsync(String.Format(CultureInfo.InvariantCulture, "Enter one of {0}/{1}/{2}/{3}/{4}/{5} (leave blank for default): ",nameof(LogLevel.Trace), nameof(LogLevel.Debug), nameof(LogLevel.Information), nameof(LogLevel.Warning), nameof(LogLevel.Error), nameof(LogLevel.Critical)), false, cancellationToken).ConfigureAwait(false);
+ await console.WriteAsync(String.Format(CultureInfo.InvariantCulture, "Enter one of {0}/{1}/{2}/{3}/{4}/{5} (leave blank for default): ", nameof(LogLevel.Trace), nameof(LogLevel.Debug), nameof(LogLevel.Information), nameof(LogLevel.Warning), nameof(LogLevel.Error), nameof(LogLevel.Critical)), false, cancellationToken).ConfigureAwait(false);
var responseString = await console.ReadLineAsync(false, cancellationToken).ConfigureAwait(false);
if (String.IsNullOrWhiteSpace(responseString))
return null;
if (Enum.TryParse(responseString, out var logLevel) && logLevel != LogLevel.None)
return logLevel;
await console.WriteAsync("Invalid log level!", true, cancellationToken).ConfigureAwait(false);
- } while (true);
+ }
+ while (true);
}
fileLoggingConfiguration.LogLevel = await PromptLogLevel(String.Format(CultureInfo.InvariantCulture, "Enter the level limit for normal logs (default {0}).", fileLoggingConfiguration.LogLevel)).ConfigureAwait(false) ?? fileLoggingConfiguration.LogLevel;
fileLoggingConfiguration.MicrosoftLogLevel = await PromptLogLevel(String.Format(CultureInfo.InvariantCulture, "Enter the level limit for Microsoft logs (VERY verbose, default {0}).", fileLoggingConfiguration.MicrosoftLogLevel)).ConfigureAwait(false) ?? fileLoggingConfiguration.MicrosoftLogLevel;
}
+
return fileLoggingConfiguration;
}
@@ -507,7 +516,7 @@ namespace Tgstation.Server.Host.Core
await console.WriteAsync("Waiting for configuration changes to reload...", true, cancellationToken).ConfigureAwait(false);
- //we need to wait for the configuration's file system watcher to read and reload the changes
+ // we need to wait for the configuration's file system watcher to read and reload the changes
await asyncDelayer.Delay(TimeSpan.FromSeconds(5), cancellationToken).ConfigureAwait(false);
}
@@ -519,7 +528,7 @@ namespace Tgstation.Server.Host.Core
/// A representing the running operation
async Task RunWizard(string userConfigFileName, CancellationToken cancellationToken)
{
- //welcome message
+ // welcome message
await console.WriteAsync(null, true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync("Welcome to tgstation-server 4!", true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync("This wizard will help you configure your server.", true, cancellationToken).ConfigureAwait(false);
@@ -576,7 +585,6 @@ namespace Tgstation.Server.Host.Core
logger.LogTrace("No configuration json detected");
}
-
if (!shouldRunBasedOnAutodetect)
{
if (forceRun)
@@ -586,11 +594,12 @@ namespace Tgstation.Server.Host.Core
forceRun = await PromptYesNo("Continue running setup wizard? (y/n): ", cancellationToken).ConfigureAwait(false);
}
- if (!forceRun)
+
+ if (!forceRun)
return false;
}
- //flush the logs to prevent console conflicts
+ // flush the logs to prevent console conflicts
await asyncDelayer.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
await RunWizard(userConfigFileName, cancellationToken).ConfigureAwait(false);
diff --git a/src/Tgstation.Server.Host/IO/Console.cs b/src/Tgstation.Server.Host/IO/Console.cs
index 35d3b1e135..9f1fceba80 100644
--- a/src/Tgstation.Server.Host/IO/Console.cs
+++ b/src/Tgstation.Server.Host/IO/Console.cs
@@ -27,7 +27,7 @@ namespace Tgstation.Server.Host.IO
///
public Task ReadLineAsync(bool usePasswordChar, CancellationToken cancellationToken) => Task.Factory.StartNew(() =>
{
- //TODO Make this better: https://stackoverflow.com/questions/9479573/how-to-interrupt-console-readline
+ // TODO: Make this better: https://stackoverflow.com/questions/9479573/how-to-interrupt-console-readline
CheckAvailable();
if (!usePasswordChar)
return System.Console.ReadLine();
@@ -46,13 +46,15 @@ namespace Tgstation.Server.Host.IO
System.Console.Write("\b \b");
}
}
- else if (keyDescription.KeyChar != '\u0000') // KeyChar == '\u0000' if the key pressed does not correspond to a printable character, e.g. F1, Pause-Break, etc
+ else if (keyDescription.KeyChar != '\u0000')
{
+ // KeyChar == '\u0000' if the key pressed does not correspond to a printable character, e.g. F1, Pause-Break, etc
passwordBuilder.Append(keyDescription.KeyChar);
System.Console.Write('*');
}
}
while (!cancellationToken.IsCancellationRequested);
+
cancellationToken.ThrowIfCancellationRequested();
System.Console.WriteLine();
return passwordBuilder.ToString();
diff --git a/src/Tgstation.Server.Host/IO/DefaultIOManager.cs b/src/Tgstation.Server.Host/IO/DefaultIOManager.cs
index d6cae80fde..6318a7b02a 100644
--- a/src/Tgstation.Server.Host/IO/DefaultIOManager.cs
+++ b/src/Tgstation.Server.Host/IO/DefaultIOManager.cs
@@ -5,7 +5,6 @@ using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -34,18 +33,21 @@ namespace Tgstation.Server.Host.IO
foreach (var subDir in dir.EnumerateDirectories())
{
cancellationToken.ThrowIfCancellationRequested();
+
+ // if below succeeds this is probably a symlink
if (!subDir.Attributes.HasFlag(FileAttributes.Directory) || subDir.Attributes.HasFlag(FileAttributes.ReparsePoint))
- //this is probably a symlink
subDir.Delete();
else
tasks.Add(NormalizeAndDelete(subDir, cancellationToken));
}
+
foreach (var file in dir.EnumerateFiles())
{
cancellationToken.ThrowIfCancellationRequested();
file.Attributes = FileAttributes.Normal;
file.Delete();
}
+
await Task.WhenAll(tasks).ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
dir.Delete(true);
@@ -84,19 +86,19 @@ namespace Tgstation.Server.Host.IO
async Task CopyThisDirectory()
{
if (!atLeastOneSubDir)
- await CreateDirectory(dest, cancellationToken).ConfigureAwait(false); //save on createdir calls
+ await CreateDirectory(dest, cancellationToken).ConfigureAwait(false); // save on createdir calls
var tasks = new List();
- await dir.EnumerateFiles().ToAsyncEnumerable().ForEachAsync(I =>
+ await dir.EnumerateFiles().ToAsyncEnumerable().ForEachAsync(fileInfo =>
{
- if (ignore != null && ignore.Contains(I.Name))
+ if (ignore != null && ignore.Contains(fileInfo.Name))
return;
- tasks.Add(CopyFile(I.FullName, Path.Combine(dest, I.Name), cancellationToken));
+ tasks.Add(CopyFile(fileInfo.FullName, Path.Combine(dest, fileInfo.Name), cancellationToken));
}).ConfigureAwait(false);
await Task.WhenAll(tasks).ConfigureAwait(false);
- };
+ }
yield return CopyThisDirectory();
}
@@ -115,18 +117,6 @@ namespace Tgstation.Server.Host.IO
await directoryCopy.ConfigureAwait(false);
}
- ///
- public async Task AppendAllText(string path, string additional_contents, CancellationToken cancellationToken)
- {
- if (additional_contents == null)
- throw new ArgumentNullException(nameof(additional_contents));
- using (var destStream = new FileStream(ResolvePath(path), FileMode.Append, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete, DefaultBufferSize, true))
- {
- var buf = Encoding.UTF8.GetBytes(additional_contents);
- await destStream.WriteAsync(buf, 0, buf.Length, cancellationToken).ConfigureAwait(false);
- }
- }
-
///
public string ConcatPath(params string[] paths)
{
@@ -265,18 +255,10 @@ namespace Tgstation.Server.Host.IO
return (IReadOnlyList)results;
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
- ///
- public Task CreateSymlink(string target, string link, CancellationToken cancellationToken) => Task.Factory.StartNew(() =>
- {
- target = ResolvePath(target);
- link = ResolvePath(link);
-
- }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
-
///
public async Task DownloadFile(Uri url, CancellationToken cancellationToken)
{
- //DownloadDataTaskAsync can't be cancelled and is shittily written, don't use it
+ // DownloadDataTaskAsync can't be cancelled and is shittily written, don't use it
using (var wc = new WebClient())
{
var tcs = new TaskCompletionSource();
diff --git a/src/Tgstation.Server.Host/IO/ISynchronousIOManager.cs b/src/Tgstation.Server.Host/IO/ISynchronousIOManager.cs
index 5b457fd840..69f80050b5 100644
--- a/src/Tgstation.Server.Host/IO/ISynchronousIOManager.cs
+++ b/src/Tgstation.Server.Host/IO/ISynchronousIOManager.cs
@@ -47,7 +47,7 @@ namespace Tgstation.Server.Host.IO
bool DeleteDirectory(string path);
///
- /// Write to a file at a given .
+ /// Write to a file at a given
///
/// The path to the file to write
/// The new contents of the file
diff --git a/src/Tgstation.Server.Host/IO/PosixPostWriteHandler.cs b/src/Tgstation.Server.Host/IO/PosixPostWriteHandler.cs
index 75eaa24bcd..2c9b6b74cf 100644
--- a/src/Tgstation.Server.Host/IO/PosixPostWriteHandler.cs
+++ b/src/Tgstation.Server.Host/IO/PosixPostWriteHandler.cs
@@ -15,7 +15,7 @@ namespace Tgstation.Server.Host.IO
if (filePath == null)
throw new ArgumentNullException(nameof(filePath));
- //set executable bit every time, don't want people calling me when their uploaded "sl" binary doesn't work
+ // set executable bit every time, don't want people calling me when their uploaded "sl" binary doesn't work
if (Syscall.stat(filePath, out var stat) != 0)
throw new UnixIOException(Stdlib.GetLastError());
diff --git a/src/Tgstation.Server.Host/IO/ResolvingIOManager.cs b/src/Tgstation.Server.Host/IO/ResolvingIOManager.cs
index b00ee71b98..e06b5d98d3 100644
--- a/src/Tgstation.Server.Host/IO/ResolvingIOManager.cs
+++ b/src/Tgstation.Server.Host/IO/ResolvingIOManager.cs
@@ -17,15 +17,15 @@ namespace Tgstation.Server.Host.IO
/// Construct a
///
/// The that resolves to the directory to work out of
- /// The value of
- public ResolvingIOManager(IIOManager parent, string _subdirectory)
+ /// The value of
+ public ResolvingIOManager(IIOManager parent, string subdirectory)
{
if (parent == null)
throw new ArgumentNullException(nameof(parent));
- if (_subdirectory == null)
- throw new ArgumentNullException(nameof(_subdirectory));
+ if (subdirectory == null)
+ throw new ArgumentNullException(nameof(subdirectory));
- subdirectory = ConcatPath(parent.ResolvePath("."), _subdirectory);
+ this.subdirectory = ConcatPath(parent.ResolvePath("."), subdirectory);
}
///
diff --git a/src/Tgstation.Server.Host/IO/SynchronousIOManager.cs b/src/Tgstation.Server.Host/IO/SynchronousIOManager.cs
index c3937d5a9c..2a6530faa0 100644
--- a/src/Tgstation.Server.Host/IO/SynchronousIOManager.cs
+++ b/src/Tgstation.Server.Host/IO/SynchronousIOManager.cs
@@ -86,8 +86,8 @@ namespace Tgstation.Server.Host.IO
{
cancellationToken.ThrowIfCancellationRequested();
- //as nice as it would be to not have to arrayify the memory stream, we have to
- //because, oddly enough sha1(memorystream) != sha1(memorystream.ToArray())
+ // as nice as it would be to not have to arrayify the memory stream, we have to
+ // because, oddly enough sha1(memorystream) != sha1(memorystream.ToArray())
// vOv
byte[] originalBytes;
using (var readMs = new MemoryStream())
@@ -95,24 +95,27 @@ namespace Tgstation.Server.Host.IO
file.CopyTo(readMs);
originalBytes = readMs.ToArray();
}
+
+ // no sha1? no write
if (originalBytes.Length != 0 && sha1InOut == null)
- //no sha1? no write
return false;
- //suppressed due to only using for consistency checks
+ // suppressed due to only using for consistency checks
#pragma warning disable CA5350 // Do not use insecure cryptographic algorithm SHA1.
using (var sha1 = new SHA1Managed())
#pragma warning restore CA5350 // Do not use insecure cryptographic algorithm SHA1.
{
- string GetSha1(byte[] dataToHash) => dataToHash != null && dataToHash.Length != 0 ? String.Join("", sha1.ComputeHash(dataToHash).Select(b => b.ToString("x2", CultureInfo.InvariantCulture))) : null;
+ string GetSha1(byte[] dataToHash) => dataToHash != null && dataToHash.Length != 0 ? String.Join(String.Empty, sha1.ComputeHash(dataToHash).Select(b => b.ToString("x2", CultureInfo.InvariantCulture))) : null;
var originalSha1 = GetSha1(originalBytes);
if (originalSha1 != sha1InOut)
{
sha1InOut = originalSha1;
return false;
}
+
sha1InOut = GetSha1(data);
}
+
cancellationToken.ThrowIfCancellationRequested();
if (data != null)
@@ -124,6 +127,7 @@ namespace Tgstation.Server.Host.IO
file.Write(data, 0, data.Length);
}
}
+
if (data == null)
File.Delete(path);
return true;
diff --git a/src/Tgstation.Server.Host/IO/WindowsSymlinkFactory.cs b/src/Tgstation.Server.Host/IO/WindowsSymlinkFactory.cs
index 761d37a574..b3a22fdaf0 100644
--- a/src/Tgstation.Server.Host/IO/WindowsSymlinkFactory.cs
+++ b/src/Tgstation.Server.Host/IO/WindowsSymlinkFactory.cs
@@ -19,17 +19,20 @@ namespace Tgstation.Server.Host.IO
if (linkPath == null)
throw new ArgumentNullException(nameof(linkPath));
- //check if its not a file
+ // check if its not a file
var flags = File.Exists(targetPath) ? NativeMethods.CreateSymbolicLinkFlags.None : NativeMethods.CreateSymbolicLinkFlags.Directory;
- //no don't fucking use this
- //sure it works in SOME cases
- //i.e. win10 1803+ and IN DEVELOPER MODE
- //other times it throws ERROR_INVALID_PARAMETER
- //but the fucking worst is there is some configuration of windows that accept the argument and allow the function to succeed
- //BUT IT DOESN'T CREATE THE FUCKING LINK
- //I AM NOT DEBUGGING THAT SHIT AGAIN AHHH
- //flags |= NativeMethods.CreateSymbolicLinkFlags.AllowUnprivilegedCreate;
+ /*
+ * no don't fucking use this
+ * sure it works in SOME cases
+ * i.e. win10 1803+ and IN DEVELOPER MODE
+ * other times it throws ERROR_INVALID_PARAMETER
+ * but the fucking worst is there is some configuration of windows that accept the argument and allow the function to succeed
+ * BUT IT DOESN'T CREATE THE FUCKING LINK
+ * I AM NOT DEBUGGING THAT SHIT AGAIN AHHH
+
+ flags |= NativeMethods.CreateSymbolicLinkFlags.AllowUnprivilegedCreate;
+ */
cancellationToken.ThrowIfCancellationRequested();
if (!NativeMethods.CreateSymbolicLink(linkPath, targetPath, flags))
diff --git a/src/Tgstation.Server.Host/Models/DatabaseContext.cs b/src/Tgstation.Server.Host/Models/DatabaseContext.cs
index e113f1d999..c80e94d95d 100644
--- a/src/Tgstation.Server.Host/Models/DatabaseContext.cs
+++ b/src/Tgstation.Server.Host/Models/DatabaseContext.cs
@@ -190,10 +190,10 @@ namespace Tgstation.Server.Host.Models
string targetMigration = null;
- //Update this with new migrations as they are made
- //Always use the MS class
+ // Update this with new migrations as they are made
+ // Always use the MS class
- //TODO: Uncomment once #816 is merged
+ // TODO: Uncomment once #816 is merged
/*
if (version < new Version(4, 0, 2))
targetMigration = nameof(MSReattachCompileJobRequired);
@@ -205,7 +205,7 @@ namespace Tgstation.Server.Host.Models
if (UseMySQLMigrations())
targetMigration = String.Format(CultureInfo.InvariantCulture, "MY" + targetMigration.Substring(2));
- //even though it clearly implements it in the DatabaseFacade definition this won't work without casting (╯ಠ益ಠ)╯︵ ┻━┻
+ // even though it clearly implements it in the DatabaseFacade definition this won't work without casting (╯ಠ益ಠ)╯︵ ┻━┻
var dbServiceProvider = ((IInfrastructure)Database).Instance;
var migrator = dbServiceProvider.GetRequiredService();
diff --git a/src/Tgstation.Server.Host/Models/Instance.cs b/src/Tgstation.Server.Host/Models/Instance.cs
index d7a1c285c3..eaf2c50bde 100644
--- a/src/Tgstation.Server.Host/Models/Instance.cs
+++ b/src/Tgstation.Server.Host/Models/Instance.cs
@@ -7,7 +7,6 @@ namespace Tgstation.Server.Host.Models
///
public sealed class Instance : Api.Models.Instance
{
-
///
/// The for the
///
@@ -34,7 +33,7 @@ namespace Tgstation.Server.Host.Models
public List InstanceUsers { get; set; }
///
- /// The s for the
+ /// The s for the
///
public List ChatSettings { get; set; }
diff --git a/src/Tgstation.Server.Host/Models/Migrations/DesignTimeDbContextFactoryHelpers.cs b/src/Tgstation.Server.Host/Models/Migrations/DesignTimeDbContextFactoryHelpers.cs
index b4b4d13ef2..98af100f86 100644
--- a/src/Tgstation.Server.Host/Models/Migrations/DesignTimeDbContextFactoryHelpers.cs
+++ b/src/Tgstation.Server.Host/Models/Migrations/DesignTimeDbContextFactoryHelpers.cs
@@ -15,12 +15,16 @@ namespace Tgstation.Server.Host.Models.Migrations
/// Path to the json file to use for migrations configuration
///
const string RootJson = "appsettings.json";
+
///
/// Path to the development json file to use for migrations configuration
///
const string DevJson = "appsettings.Development.json";
- ///
+ ///
+ /// Get the for the
+ ///
+ /// The for the
public static IOptions GetDbContextOptions()
{
var builder = new ConfigurationBuilder();
diff --git a/src/Tgstation.Server.Host/Models/RepositorySettings.cs b/src/Tgstation.Server.Host/Models/RepositorySettings.cs
index 969e1ebb69..4c11820499 100644
--- a/src/Tgstation.Server.Host/Models/RepositorySettings.cs
+++ b/src/Tgstation.Server.Host/Models/RepositorySettings.cs
@@ -1,5 +1,4 @@
-using System;
-using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations;
using Tgstation.Server.Api.Models;
namespace Tgstation.Server.Host.Models
@@ -26,10 +25,10 @@ namespace Tgstation.Server.Host.Models
///
/// Convert the to it's API form
///
- /// A new
+ /// A new
public Repository ToApi() => new Repository
{
- //AccessToken = AccessToken, //never show this
+ // AccessToken = AccessToken, //never show this
AccessUser = AccessUser,
AutoUpdatesKeepTestMerges = AutoUpdatesKeepTestMerges,
AutoUpdatesSynchronize = AutoUpdatesSynchronize,
@@ -37,7 +36,8 @@ namespace Tgstation.Server.Host.Models
CommitterName = CommitterName,
PushTestMergeCommits = PushTestMergeCommits,
ShowTestMergeCommitters = ShowTestMergeCommitters
- //revision information and the rest retrieved by controller
+
+ // revision information and the rest retrieved by controller
};
}
}
diff --git a/src/Tgstation.Server.Host/Models/RevisionInformation.cs b/src/Tgstation.Server.Host/Models/RevisionInformation.cs
index 896615150f..654f55ef1b 100644
--- a/src/Tgstation.Server.Host/Models/RevisionInformation.cs
+++ b/src/Tgstation.Server.Host/Models/RevisionInformation.cs
@@ -45,7 +45,7 @@ namespace Tgstation.Server.Host.Models
ActiveTestMerges = ActiveTestMerges.Select(x => x.TestMerge.ToApi()).ToList(),
CompileJobs = CompileJobs.Select(x => new Api.Models.CompileJob
{
- Id = x.Id //anti recursion measure
+ Id = x.Id // anti recursion measure
}).ToList()
};
}
diff --git a/src/Tgstation.Server.Host/Models/User.cs b/src/Tgstation.Server.Host/Models/User.cs
index c8682b4e7f..bcbe8c23bf 100644
--- a/src/Tgstation.Server.Host/Models/User.cs
+++ b/src/Tgstation.Server.Host/Models/User.cs
@@ -62,7 +62,7 @@ namespace Tgstation.Server.Host.Models
};
///
- /// Convert the to it's API form
+ /// Convert the to it's API form
///
/// If rights and system identifier should be shown
/// A new
diff --git a/src/Tgstation.Server.Host/Program.cs b/src/Tgstation.Server.Host/Program.cs
index d7c28a061f..83895df62b 100644
--- a/src/Tgstation.Server.Host/Program.cs
+++ b/src/Tgstation.Server.Host/Program.cs
@@ -15,7 +15,9 @@ namespace Tgstation.Server.Host
///
/// The to use
///
- internal static IServerFactory serverFactory = new ServerFactory();
+#pragma warning disable SA1401 // Fields must be private
+ internal static IServerFactory ServerFactory = new ServerFactory();
+#pragma warning restore SA1401 // Fields must be private
///
/// Entrypoint for the
@@ -25,7 +27,8 @@ namespace Tgstation.Server.Host
public static async Task Main(string[] args)
{
var listArgs = new List(args);
- //first arg is 100% always the update path, starting it otherwise is solely for debugging purposes
+
+ // first arg is 100% always the update path, starting it otherwise is solely for debugging purposes
string updatePath;
if (listArgs.Count > 0)
{
@@ -38,7 +41,7 @@ namespace Tgstation.Server.Host
updatePath = null;
try
{
- var server = serverFactory.CreateServer(listArgs.ToArray(), updatePath);
+ var server = ServerFactory.CreateServer(listArgs.ToArray(), updatePath);
try
{
using (var cts = new CancellationTokenSource())
@@ -70,6 +73,7 @@ namespace Tgstation.Server.Host
File.WriteAllText(updatePath, e.ToString());
return 2;
}
+
throw;
}
}
diff --git a/src/Tgstation.Server.Host/Security/AuthenticationContext.cs b/src/Tgstation.Server.Host/Security/AuthenticationContext.cs
index 1ef6364651..b621a41c04 100644
--- a/src/Tgstation.Server.Host/Security/AuthenticationContext.cs
+++ b/src/Tgstation.Server.Host/Security/AuthenticationContext.cs
@@ -53,6 +53,7 @@ namespace Tgstation.Server.Host.Security
if (isInstance && InstanceUser == null)
return 0;
var rightsEnum = RightsHelper.RightToType(rightsType);
+
// use the api versions because they're the ones that contain the actual properties
var typeToCheck = isInstance ? typeof(InstanceUser) : typeof(User);
diff --git a/src/Tgstation.Server.Host/Security/AuthenticationContextFactory.cs b/src/Tgstation.Server.Host/Security/AuthenticationContextFactory.cs
index 087a6d33dc..bfe70be61d 100644
--- a/src/Tgstation.Server.Host/Security/AuthenticationContextFactory.cs
+++ b/src/Tgstation.Server.Host/Security/AuthenticationContextFactory.cs
@@ -76,6 +76,7 @@ namespace Tgstation.Server.Host.Security
CurrentAuthenticationContext = new AuthenticationContext();
return;
}
+
systemIdentity = null;
}
diff --git a/src/Tgstation.Server.Host/Security/ClaimsInjector.cs b/src/Tgstation.Server.Host/Security/ClaimsInjector.cs
index 3e7f202b2e..c3b67cb489 100644
--- a/src/Tgstation.Server.Host/Security/ClaimsInjector.cs
+++ b/src/Tgstation.Server.Host/Security/ClaimsInjector.cs
@@ -43,7 +43,7 @@ namespace Tgstation.Server.Host.Security
if (tokenValidatedContext == null)
throw new ArgumentNullException(nameof(tokenValidatedContext));
- //Find the user id in the token
+ // Find the user id in the token
var userIdClaim = tokenValidatedContext.Principal.FindFirst(JwtRegisteredClaimNames.Sub);
if (userIdClaim == default)
throw new InvalidOperationException("Missing required claim!");
@@ -65,11 +65,11 @@ namespace Tgstation.Server.Host.Security
}
catch (InvalidOperationException)
{
- //we are not responsible for handling header validation issues
+ // we are not responsible for handling header validation issues
return;
}
- //This populates the CurrentAuthenticationContext field for use by us and subsequent controllers
+ // This populates the CurrentAuthenticationContext field for use by us and subsequent controllers
await authenticationContextFactory.CreateAuthenticationContext(userId, apiHeaders.InstanceId, tokenValidatedContext.SecurityToken.ValidFrom, cancellationToken).ConfigureAwait(false);
var authenticationContext = authenticationContextFactory.CurrentAuthenticationContext;
@@ -78,9 +78,9 @@ namespace Tgstation.Server.Host.Security
var claims = new List();
foreach (RightsType I in enumerator)
{
- //if there's no instance user, do a weird thing and add all the instance roles
- //we need it so we can get to OnActionExecutionAsync where we can properly decide between BadRequest and Forbid
- //if user is null that means they got the token with an expired password
+ // if there's no instance user, do a weird thing and add all the instance roles
+ // we need it so we can get to OnActionExecutionAsync where we can properly decide between BadRequest and Forbid
+ // if user is null that means they got the token with an expired password
var rightInt = authenticationContext.User == null || (RightsHelper.IsInstanceRight(I) && authenticationContext.InstanceUser == null) ? ~0U : authenticationContext.GetRight(I);
var rightEnum = RightsHelper.RightToType(I);
var right = (Enum)Enum.ToObject(rightEnum, rightInt);
diff --git a/src/Tgstation.Server.Host/Security/CryptographySuite.cs b/src/Tgstation.Server.Host/Security/CryptographySuite.cs
index 4cdd6be43a..77ab55db94 100644
--- a/src/Tgstation.Server.Host/Security/CryptographySuite.cs
+++ b/src/Tgstation.Server.Host/Security/CryptographySuite.cs
@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Identity;
using System;
+using System.Globalization;
using System.Security.Cryptography;
using Tgstation.Server.Host.Models;
@@ -53,14 +54,20 @@ namespace Tgstation.Server.Host.Security
///
public bool CheckUserPassword(User user, string password)
{
- switch (passwordHasher.VerifyHashedPassword(user, user.PasswordHash, password))
+ var result = passwordHasher.VerifyHashedPassword(user, user.PasswordHash, password);
+ switch (result)
{
case PasswordVerificationResult.Failed:
return false;
case PasswordVerificationResult.SuccessRehashNeeded:
SetUserPassword(user, password, false);
break;
+ case PasswordVerificationResult.Success:
+ break;
+ default:
+ throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Password hasher return unknown PasswordVerificationResult: {0}", result));
}
+
return true;
}
diff --git a/src/Tgstation.Server.Host/Security/IdentityCache.cs b/src/Tgstation.Server.Host/Security/IdentityCache.cs
index 43a2b84302..2b4e751b08 100644
--- a/src/Tgstation.Server.Host/Security/IdentityCache.cs
+++ b/src/Tgstation.Server.Host/Security/IdentityCache.cs
@@ -61,8 +61,9 @@ namespace Tgstation.Server.Host.Security
if (cachedIdentities.TryGetValue(user.Id, out var identCache))
{
logger.LogTrace("Expiring previously cached identity...");
- identCache.Dispose(); //also clears it out
+ identCache.Dispose(); // also clears it out
}
+
identCache = new IdentityCacheObject(systemIdentity.Clone(), asyncDelayer, () =>
{
logger.LogDebug("Expiring system identity cache for user {1}", uid, user.Id);
diff --git a/src/Tgstation.Server.Host/Security/TokenFactory.cs b/src/Tgstation.Server.Host/Security/TokenFactory.cs
index 661f52f91a..2974f6d3b1 100644
--- a/src/Tgstation.Server.Host/Security/TokenFactory.cs
+++ b/src/Tgstation.Server.Host/Security/TokenFactory.cs
@@ -73,13 +73,13 @@ namespace Tgstation.Server.Host.Security
throw new ArgumentNullException(nameof(user));
var now = DateTimeOffset.Now;
-
var nowUnix = now.ToUnixTimeSeconds();
- //this prevents validation conflicts down the line
- //tldr we can (theoretically) send a token the same second we receive it
- //since unix time rounds down, it looks like it came from before the user changed their password
- //this happens occasionally in unit tests
- //just delay a second so we can force a round up
+
+ // this prevents validation conflicts down the line
+ // tldr we can (theoretically) send a token the same second we receive it
+ // since unix time rounds down, it looks like it came from before the user changed their password
+ // this happens occasionally in unit tests
+ // just delay a second so we can force a round up
var lpuUnix = user.LastPasswordUpdate?.ToUnixTimeSeconds();
if (nowUnix == lpuUnix)
await asyncDelayer.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
diff --git a/src/Tgstation.Server.Host/Security/WindowsSystemIdentity.cs b/src/Tgstation.Server.Host/Security/WindowsSystemIdentity.cs
index 43065b1b5b..c71544cc35 100644
--- a/src/Tgstation.Server.Host/Security/WindowsSystemIdentity.cs
+++ b/src/Tgstation.Server.Host/Security/WindowsSystemIdentity.cs
@@ -63,13 +63,13 @@ namespace Tgstation.Server.Host.Security
{
if (identity != null)
{
- //var newIdentity = (WindowsIdentity)identity.Clone(); //doesn't work because of https://github.com/dotnet/corefx/issues/31841
-
- var newIdentity = new WindowsIdentity(identity.Token); //the handle is cloned internally
+ // var newIdentity = (WindowsIdentity)identity.Clone(); //doesn't work because of https://github.com/dotnet/corefx/issues/31841
+ var newIdentity = new WindowsIdentity(identity.Token); // the handle is cloned internally
return new WindowsSystemIdentity(newIdentity);
}
- //can't clone a UP, shouldn't be trying to anyway, cloning is for impersonation
+
+ // can't clone a UP, shouldn't be trying to anyway, cloning is for impersonation
throw new InvalidOperationException("Cannot clone a UserPrincipal based WindowsSystemIdentity!");
}
diff --git a/src/Tgstation.Server.Host/Security/WindowsSystemIdentityFactory.cs b/src/Tgstation.Server.Host/Security/WindowsSystemIdentityFactory.cs
index e1deb301f0..aec9d8c463 100644
--- a/src/Tgstation.Server.Host/Security/WindowsSystemIdentityFactory.cs
+++ b/src/Tgstation.Server.Host/Security/WindowsSystemIdentityFactory.cs
@@ -78,12 +78,13 @@ namespace Tgstation.Server.Host.Security
}
}
return principal != null;
- };
-
+ }
+
if (!TryGetPrincipalFromContextType(ContextType.Machine) && !TryGetPrincipalFromContextType(ContextType.Domain))
return null;
return (ISystemIdentity)new WindowsSystemIdentity(principal);
- }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
+ },
+ cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
///
public Task CreateSystemIdentity(string username, string password, CancellationToken cancellationToken) => Task.Factory.StartNew(() =>
@@ -105,8 +106,8 @@ namespace Tgstation.Server.Host.Security
logger.LogTrace("Successfully logged in username {0}!", originalUsername);
- using (var handle = new SafeAccessTokenHandle(token)) //checked internally, windows identity always duplicates the handle when constructed with a userToken
- return (ISystemIdentity)new WindowsSystemIdentity(new WindowsIdentity(handle.DangerousGetHandle())); //https://github.com/dotnet/corefx/blob/6ed61acebe3214fcf79b4274f2bb9b55c0604a4d/src/System.Security.Principal.Windows/src/System/Security/Principal/WindowsIdentity.cs#L271
+ using (var handle = new SafeAccessTokenHandle(token)) // checked internally, windows identity always duplicates the handle when constructed with a userToken
+ return (ISystemIdentity)new WindowsSystemIdentity(new WindowsIdentity(handle.DangerousGetHandle())); // https://github.com/dotnet/corefx/blob/6ed61acebe3214fcf79b4274f2bb9b55c0604a4d/src/System.Security.Principal.Windows/src/System/Security/Principal/WindowsIdentity.cs#L271
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
}
}
diff --git a/src/Tgstation.Server.Host/Server.cs b/src/Tgstation.Server.Host/Server.cs
index 1786fd6a19..1fa566b503 100644
--- a/src/Tgstation.Server.Host/Server.cs
+++ b/src/Tgstation.Server.Host/Server.cs
@@ -94,11 +94,11 @@ namespace Tgstation.Server.Host
};
fsWatcher.EnableRaisingEvents = true;
}
+
using (var webHost = webHostBuilder
.UseStartup()
.ConfigureServices(serviceCollection => serviceCollection.AddSingleton(this))
- .Build()
- )
+ .Build())
{
logger = webHost.Services.GetRequiredService>();
await webHost.RunAsync(cancellationTokenSource.Token).ConfigureAwait(false);
@@ -127,6 +127,7 @@ namespace Tgstation.Server.Host
logger.LogTrace("Aborted due to concurrency conflict!");
return false;
}
+
updating = true;
}
@@ -153,13 +154,14 @@ namespace Tgstation.Server.Host
updating = false;
try
{
- //important to not leave this directory around if possible
+ // important to not leave this directory around if possible
await ioManager.DeleteDirectory(updatePath, default).ConfigureAwait(false);
}
catch (Exception e2)
{
throw new AggregateException(e, e2);
}
+
throw;
}
@@ -203,6 +205,7 @@ namespace Tgstation.Server.Host
restartHandlers.Remove(handler);
});
}
+
return new RestartRegistration(() => { });
}
@@ -213,7 +216,7 @@ namespace Tgstation.Server.Host
/// Implements
///
/// The of any potential updates being applied
- ///
+ /// A representing the running operation
async Task Restart(Version newVersion)
{
CheckSanity(true);
@@ -227,6 +230,7 @@ namespace Tgstation.Server.Host
logger.LogTrace("Aborted due to concurrency conflict!");
return;
}
+
RestartRequested = true;
}
@@ -237,7 +241,8 @@ namespace Tgstation.Server.Host
logger.LogTrace("Running restart handlers...");
var cancellationToken = cts.Token;
var eventsTask = Task.WhenAll(restartHandlers.Select(x => x.HandleRestart(newVersion, cancellationToken)).ToList());
- //YA GOT 10 SECONDS
+
+ // YA GOT 10 SECONDS
var expiryTask = Task.Delay(TimeSpan.FromSeconds(10));
await Task.WhenAny(eventsTask, expiryTask).ConfigureAwait(false);
logger.LogTrace("Joining restart handlers...");