mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-22 12:37:24 +01:00
General code cleanup pass
This commit is contained in:
@@ -4,7 +4,6 @@ using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using Tgstation.Server.Api;
|
||||
|
||||
@@ -23,7 +23,6 @@ using System;
|
||||
using System.Globalization;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Api;
|
||||
using Tgstation.Server.Host.Components;
|
||||
@@ -57,6 +56,11 @@ namespace Tgstation.Server.Host.Core
|
||||
/// </summary>
|
||||
readonly IConfiguration configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IAssemblyInformationProvider"/> for the <see cref="Application"/>.
|
||||
/// </summary>
|
||||
readonly IAssemblyInformationProvider assemblyInformationProvider;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Microsoft.AspNetCore.Hosting.IHostingEnvironment"/> for the <see cref="Application"/>
|
||||
/// </summary>
|
||||
@@ -76,15 +80,20 @@ namespace Tgstation.Server.Host.Core
|
||||
/// Construct an <see cref="Application"/>
|
||||
/// </summary>
|
||||
/// <param name="configuration">The value of <see cref="configuration"/></param>
|
||||
/// <param name="assemblyInformationProvider">The <see cref="IAssemblyInformationProvider"/> for the <see cref="Application"/>.</param>
|
||||
/// <param name="hostingEnvironment">The value of <see cref="hostingEnvironment"/></param>
|
||||
public Application(IConfiguration configuration, Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment)
|
||||
public Application(
|
||||
IConfiguration configuration,
|
||||
IAssemblyInformationProvider assemblyInformationProvider,
|
||||
Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
this.configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
|
||||
this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider));
|
||||
this.hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment));
|
||||
|
||||
startupTcs = new TaskCompletionSource<object>();
|
||||
|
||||
Version = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
Version = assemblyInformationProvider.Name.Version;
|
||||
VersionString = String.Format(CultureInfo.InvariantCulture, "{0} v{1}", VersionPrefix, Version);
|
||||
}
|
||||
|
||||
@@ -258,7 +267,7 @@ namespace Tgstation.Server.Host.Core
|
||||
|
||||
// Important to do this before applying our own filters
|
||||
// Otherwise we'll get NullReferenceExceptions on parameters to be setup in our document filter
|
||||
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
|
||||
var assemblyLocation = assemblyInformationProvider.Path;
|
||||
var filePath = ioManager.ConcatPath(ioManager.GetDirectoryName(assemblyLocation), String.Concat(ioManager.GetFileNameWithoutExtension(assemblyLocation), ".xml"));
|
||||
c.IncludeXmlComments(filePath);
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace Tgstation.Server.Host.Core
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class AssemblyInformationProvider : IAssemblyInformationProvider
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Path { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public AssemblyName Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AssemblyInformationProvider"/> <see langword="class"/>.
|
||||
/// </summary>
|
||||
public AssemblyInformationProvider()
|
||||
{
|
||||
Assembly assembly = Assembly.GetExecutingAssembly();
|
||||
Path = assembly.Location;
|
||||
Name = assembly.GetName();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace Tgstation.Server.Host.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// For retrieving the <see cref="Assembly"/>'s location.
|
||||
/// </summary>
|
||||
interface IAssemblyInformationProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the path to the executing assembly.
|
||||
/// </summary>
|
||||
string Path { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="AssemblyName"/>.
|
||||
/// </summary>
|
||||
AssemblyName Name { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Tgstation.Server.Host.Configuration;
|
||||
using Tgstation.Server.Host.Core;
|
||||
using Tgstation.Server.Host.IO;
|
||||
|
||||
namespace Tgstation.Server.Host.Models.Migrations
|
||||
{
|
||||
@@ -28,7 +28,9 @@ namespace Tgstation.Server.Host.Models.Migrations
|
||||
public static IOptions<DatabaseConfiguration> GetDbContextOptions()
|
||||
{
|
||||
var builder = new ConfigurationBuilder();
|
||||
builder.SetBasePath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
|
||||
var assemblyInfoProvider = new AssemblyInformationProvider();
|
||||
var ioManager = new DefaultIOManager();
|
||||
builder.SetBasePath(ioManager.GetDirectoryName(assemblyInfoProvider.Path));
|
||||
builder.AddJsonFile(RootJson);
|
||||
builder.AddJsonFile(DevJson);
|
||||
var configuration = builder.Build();
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Tgstation.Server.Host
|
||||
/// The <see cref="IServerFactory"/> to use
|
||||
/// </summary>
|
||||
#pragma warning disable SA1401 // Fields must be private
|
||||
internal static IServerFactory ServerFactory = new ServerFactory();
|
||||
internal static IServerFactory ServerFactory = Host.ServerFactory.CreateDefault();
|
||||
#pragma warning restore SA1401 // Fields must be private
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Reflection;
|
||||
using System.Security.Claims;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -42,7 +41,11 @@ namespace Tgstation.Server.Host.Security
|
||||
/// </summary>
|
||||
/// <param name="asyncDelayer">The value of <see cref="asyncDelayer"/></param>
|
||||
/// <param name="cryptographySuite">The <see cref="ICryptographySuite"/> used for generating the <see cref="ValidationParameters"/></param>
|
||||
public TokenFactory(IAsyncDelayer asyncDelayer, ICryptographySuite cryptographySuite)
|
||||
/// <param name="assemblyInformationProvider">The <see cref="IAssemblyInformationProvider"/> used to generate the issuer name.</param>
|
||||
public TokenFactory(
|
||||
IAsyncDelayer asyncDelayer,
|
||||
ICryptographySuite cryptographySuite,
|
||||
IAssemblyInformationProvider assemblyInformationProvider)
|
||||
{
|
||||
ValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
@@ -50,7 +53,7 @@ namespace Tgstation.Server.Host.Security
|
||||
IssuerSigningKey = new SymmetricSecurityKey(cryptographySuite.GetSecureBytes(TokenSigningKeyByteAmount)),
|
||||
|
||||
ValidateIssuer = true,
|
||||
ValidIssuer = Assembly.GetExecutingAssembly().GetName().Name,
|
||||
ValidIssuer = assemblyInformationProvider.Name.Name,
|
||||
|
||||
ValidateLifetime = true,
|
||||
ValidateAudience = true,
|
||||
|
||||
@@ -30,6 +30,11 @@ namespace Tgstation.Server.Host
|
||||
/// </summary>
|
||||
readonly IWebHostBuilder webHostBuilder;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IIOManager"/> for the <see cref="Server"/>.
|
||||
/// </summary>
|
||||
readonly IIOManager ioManager;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IRestartHandler"/>s to run when the <see cref="Server"/> restarts
|
||||
/// </summary>
|
||||
@@ -69,10 +74,12 @@ namespace Tgstation.Server.Host
|
||||
/// Construct a <see cref="Server"/>
|
||||
/// </summary>
|
||||
/// <param name="webHostBuilder">The value of <see cref="webHostBuilder"/></param>
|
||||
/// <param name="ioManager">The value of <see cref="ioManager"/>.</param>
|
||||
/// <param name="updatePath">The value of <see cref="updatePath"/></param>
|
||||
public Server(IWebHostBuilder webHostBuilder, string updatePath)
|
||||
public Server(IWebHostBuilder webHostBuilder, IIOManager ioManager, string updatePath)
|
||||
{
|
||||
this.webHostBuilder = webHostBuilder ?? throw new ArgumentNullException(nameof(webHostBuilder));
|
||||
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
|
||||
this.updatePath = updatePath;
|
||||
|
||||
webHostBuilder.ConfigureServices(serviceCollection => serviceCollection.AddSingleton<IServerControl>(this));
|
||||
|
||||
@@ -1,29 +1,65 @@
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Tgstation.Server.Host.Core;
|
||||
using Tgstation.Server.Host.IO;
|
||||
|
||||
namespace Tgstation.Server.Host
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public sealed class ServerFactory : IServerFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IAssemblyInformationProvider"/> for the <see cref="ServerFactory"/>.
|
||||
/// </summary>
|
||||
readonly IAssemblyInformationProvider assemblyInformationProvider;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IIOManager"/> for the <see cref="ServerFactory"/>.
|
||||
/// </summary>
|
||||
readonly IIOManager ioManager;
|
||||
|
||||
/// <summary>
|
||||
/// Create the default <see cref="IServerFactory"/>.
|
||||
/// </summary>
|
||||
/// <returns>A new <see cref="IServerFactory"/> with the default settings.</returns>
|
||||
public static IServerFactory CreateDefault()
|
||||
=> new ServerFactory(
|
||||
new AssemblyInformationProvider(),
|
||||
new DefaultIOManager());
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServerFactory"/>.
|
||||
/// </summary>
|
||||
/// <param name="assemblyInformationProvider">The value of <see cref="assemblyInformationProvider"/>.</param>
|
||||
/// <param name="ioManager">The value of <see cref="ioManager"/>.</param>
|
||||
internal ServerFactory(IAssemblyInformationProvider assemblyInformationProvider, IIOManager ioManager)
|
||||
{
|
||||
this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider));
|
||||
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IServer CreateServer(string[] args, string updatePath)
|
||||
{
|
||||
var webHost = WebHost.CreateDefaultBuilder(args ?? throw new ArgumentNullException(nameof(args)))
|
||||
.ConfigureAppConfiguration((context, configurationBuilder) => configurationBuilder.SetBasePath(Directory.GetCurrentDirectory()))
|
||||
.ConfigureServices(serviceCollection =>
|
||||
{
|
||||
serviceCollection.AddSingleton(ioManager);
|
||||
serviceCollection.AddSingleton(assemblyInformationProvider);
|
||||
})
|
||||
.UseStartup<Application>()
|
||||
.SuppressStatusMessages(true)
|
||||
.UseShutdownTimeout(TimeSpan.FromMinutes(1));
|
||||
|
||||
if(updatePath != null)
|
||||
webHost.UseContentRoot(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
|
||||
webHost.UseContentRoot(Path.GetDirectoryName(assemblyInformationProvider.Path));
|
||||
|
||||
return new Server(webHost, updatePath);
|
||||
return new Server(webHost, ioManager, updatePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,13 +23,18 @@ namespace Tgstation.Server.Host.Core.Tests
|
||||
[TestMethod]
|
||||
public void TestMethodThrows()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new Application(null, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new Application(null, null, null));
|
||||
var mockConfiguration = new Mock<IConfiguration>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new Application(mockConfiguration.Object, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new Application(mockConfiguration.Object, null, null));
|
||||
|
||||
var mockAssemblyInfo = new Mock<IAssemblyInformationProvider>();
|
||||
mockAssemblyInfo.SetupGet(x => x.Name).Returns(typeof(Application).Assembly.GetName());
|
||||
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new Application(mockConfiguration.Object, mockAssemblyInfo.Object, null));
|
||||
|
||||
var mockHostingEnvironment = new Mock<IHostingEnvironment>();
|
||||
|
||||
var app = new Application(mockConfiguration.Object, mockHostingEnvironment.Object);
|
||||
var app = new Application(mockConfiguration.Object, mockAssemblyInfo.Object, mockHostingEnvironment.Object);
|
||||
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.ConfigureServices(null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => app.Configure(null, null, null, null, null));
|
||||
@@ -69,11 +74,11 @@ namespace Tgstation.Server.Host.Core.Tests
|
||||
public void TestConfigureServicesThrowsWhenSetupWizardConfigurationDemands()
|
||||
{
|
||||
var mockConfiguration = new Mock<IConfiguration>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new Application(mockConfiguration.Object, null));
|
||||
|
||||
var mockAssemblyInfo = new Mock<IAssemblyInformationProvider>();
|
||||
mockAssemblyInfo.SetupGet(x => x.Name).Returns(typeof(Application).Assembly.GetName());
|
||||
var mockHostingEnvironment = new Mock<IHostingEnvironment>();
|
||||
|
||||
var app = new Application(mockConfiguration.Object, mockHostingEnvironment.Object);
|
||||
var app = new Application(mockConfiguration.Object, mockAssemblyInfo.Object, mockHostingEnvironment.Object);
|
||||
|
||||
var mockOptions = new Mock<IOptions<GeneralConfiguration>>();
|
||||
mockOptions.SetupGet(x => x.Value).Returns(new GeneralConfiguration
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using System;
|
||||
using Tgstation.Server.Host.Core;
|
||||
using Tgstation.Server.Host.IO;
|
||||
|
||||
namespace Tgstation.Server.Host.Tests
|
||||
{
|
||||
@@ -9,10 +12,20 @@ namespace Tgstation.Server.Host.Tests
|
||||
[TestClass]
|
||||
public sealed class TestServerFactory
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestContructor()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new ServerFactory(null, null));
|
||||
IAssemblyInformationProvider assemblyInformationProvider = Mock.Of<IAssemblyInformationProvider>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new ServerFactory(assemblyInformationProvider, null));
|
||||
IIOManager ioManager = Mock.Of<IIOManager>();
|
||||
new ServerFactory(assemblyInformationProvider, ioManager);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestWorksWithoutUpdatePath()
|
||||
{
|
||||
var factory = new ServerFactory();
|
||||
var factory = ServerFactory.CreateDefault();
|
||||
|
||||
Assert.ThrowsException<ArgumentNullException>(() => factory.CreateServer(null, null));
|
||||
factory.CreateServer(Array.Empty<string>(), null);
|
||||
@@ -21,7 +34,7 @@ namespace Tgstation.Server.Host.Tests
|
||||
[TestMethod]
|
||||
public void TestWorksWithUpdatePath()
|
||||
{
|
||||
var factory = new ServerFactory();
|
||||
var factory = ServerFactory.CreateDefault();
|
||||
const string Path = "/test";
|
||||
|
||||
Assert.ThrowsException<ArgumentNullException>(() => factory.CreateServer(null, null));
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Tgstation.Server.Tests
|
||||
if (dumpOpenAPISpecpath)
|
||||
Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development");
|
||||
|
||||
realServer = new ServerFactory().CreateServer(args.ToArray(), updatePath);
|
||||
realServer = ServerFactory.CreateDefault().CreateServer(args.ToArray(), updatePath);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
Reference in New Issue
Block a user