diff --git a/src/Tgstation.Server.Host/Configuration/ControlPanelConfiguration.cs b/src/Tgstation.Server.Host/Configuration/ControlPanelConfiguration.cs
index 6873f0d27f..51387d7c3c 100644
--- a/src/Tgstation.Server.Host/Configuration/ControlPanelConfiguration.cs
+++ b/src/Tgstation.Server.Host/Configuration/ControlPanelConfiguration.cs
@@ -5,7 +5,7 @@ namespace Tgstation.Server.Host.Configuration
///
/// Configuration options for the web control panel
///
- sealed class ControlPanelConfiguration
+ public sealed class ControlPanelConfiguration
{
///
/// The key for the the resides in
diff --git a/src/Tgstation.Server.Host/Controllers/ApiController.cs b/src/Tgstation.Server.Host/Controllers/ApiController.cs
index 3b26db1875..1d6318d89d 100644
--- a/src/Tgstation.Server.Host/Controllers/ApiController.cs
+++ b/src/Tgstation.Server.Host/Controllers/ApiController.cs
@@ -51,6 +51,11 @@ namespace Tgstation.Server.Host.Controllers
///
readonly bool requireInstance;
+ ///
+ /// If are required
+ ///
+ readonly bool requireHeaders;
+
///
/// Construct an
///
@@ -58,7 +63,8 @@ namespace Tgstation.Server.Host.Controllers
/// The for the
/// The value of
/// The value of
- public ApiController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, ILogger logger, bool requireInstance)
+ /// The value of
+ public ApiController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, ILogger logger, bool requireInstance, bool requireHeaders)
{
DatabaseContext = databaseContext ?? throw new ArgumentNullException(nameof(databaseContext));
if (authenticationContextFactory == null)
@@ -67,6 +73,7 @@ namespace Tgstation.Server.Host.Controllers
AuthenticationContext = authenticationContextFactory.CurrentAuthenticationContext;
Instance = AuthenticationContext?.InstanceUser?.Instance;
this.requireInstance = requireInstance;
+ this.requireHeaders = requireHeaders;
}
///
@@ -113,8 +120,11 @@ namespace Tgstation.Server.Host.Controllers
}
catch (InvalidOperationException e)
{
- await BadRequest(new ErrorMessage { Message = e.Message }).ExecuteResultAsync(context).ConfigureAwait(false);
- return;
+ if (requireHeaders)
+ {
+ await BadRequest(new ErrorMessage { Message = e.Message }).ExecuteResultAsync(context).ConfigureAwait(false);
+ return;
+ }
}
if (ModelState?.IsValid == false)
@@ -138,7 +148,8 @@ namespace Tgstation.Server.Host.Controllers
}
}
- Logger.LogDebug("Request made by User ID {0}. Api version: {1}. User-Agent: {2}. Type: {3}. Route {4}{5} to Instance {6}", AuthenticationContext?.User.Id.ToString(CultureInfo.InvariantCulture), ApiHeaders.ApiVersion, ApiHeaders.UserAgent, Request.Method, Request.Path, Request.QueryString, ApiHeaders.InstanceId);
+ if (ApiHeaders != null)
+ Logger.LogDebug("Request made by User ID {0}. Api version: {1}. User-Agent: {2}. Type: {3}. Route {4}{5} to Instance {6}", AuthenticationContext?.User.Id.ToString(CultureInfo.InvariantCulture), ApiHeaders.ApiVersion, ApiHeaders.UserAgent, Request.Method, Request.Path, Request.QueryString, ApiHeaders.InstanceId);
try
{
diff --git a/src/Tgstation.Server.Host/Controllers/HomeController.cs b/src/Tgstation.Server.Host/Controllers/HomeController.cs
index 5b914af991..56d7a59e5a 100644
--- a/src/Tgstation.Server.Host/Controllers/HomeController.cs
+++ b/src/Tgstation.Server.Host/Controllers/HomeController.cs
@@ -1,14 +1,19 @@
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
using System;
using System.Linq;
+using System.Net.Mime;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api;
+using Tgstation.Server.Host.Configuration;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.Security;
+using Wangkanai.Detection;
namespace Tgstation.Server.Host.Controllers
{
@@ -39,6 +44,16 @@ namespace Tgstation.Server.Host.Controllers
///
readonly IIdentityCache identityCache;
+ ///
+ /// The for the
+ ///
+ readonly IBrowserResolver browserResolver;
+
+ ///
+ /// The for the
+ ///
+ readonly ControlPanelConfiguration controlPanelConfiguration;
+
///
/// Construct a
///
@@ -49,27 +64,45 @@ namespace Tgstation.Server.Host.Controllers
/// The value of
/// The value of
/// The value of
+ /// The value of
+ /// The containing the value of
/// The for the
- public HomeController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, ITokenFactory tokenFactory, ISystemIdentityFactory systemIdentityFactory, ICryptographySuite cryptographySuite, IApplication application, IIdentityCache identityCache, ILogger logger) : base(databaseContext, authenticationContextFactory, logger, false)
+ public HomeController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, ITokenFactory tokenFactory, ISystemIdentityFactory systemIdentityFactory, ICryptographySuite cryptographySuite, IApplication application, IIdentityCache identityCache, IBrowserResolver browserResolver, IOptions controlPanelConfigurationOptions, ILogger logger) : base(databaseContext, authenticationContextFactory, logger, false, false)
{
this.tokenFactory = tokenFactory ?? throw new ArgumentNullException(nameof(tokenFactory));
this.systemIdentityFactory = systemIdentityFactory ?? throw new ArgumentNullException(nameof(systemIdentityFactory));
this.cryptographySuite = cryptographySuite ?? throw new ArgumentNullException(nameof(cryptographySuite));
this.application = application ?? throw new ArgumentNullException(nameof(application));
this.identityCache = identityCache ?? throw new ArgumentNullException(nameof(identityCache));
+ this.browserResolver = browserResolver ?? throw new ArgumentNullException(nameof(browserResolver));
+ controlPanelConfiguration = controlPanelConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(controlPanelConfigurationOptions));
}
///
- /// Returns the version of the
+ /// Main page of the
///
- ///
+ /// The of the if a properly authenticated API request, the web control panel if on a browser and enabled, otherwise
[TgsAuthorize]
+ [AllowAnonymous]
[HttpGet]
- public JsonResult Home() => Json(new Api.Models.ServerInformation
+ public IActionResult Home(CancellationToken cancellationToken)
{
- Version = application.Version,
- ApiVersion = ApiHeaders.Version
- });
+ if (AuthenticationContext != null)
+ return Json(new Api.Models.ServerInformation
+ {
+ Version = application.Version,
+ ApiVersion = ApiHeaders.Version
+ });
+
+ //if we are using a browser and the control panel, soft redirect to the app page
+ if (controlPanelConfiguration.Enable && browserResolver.Browser.Type != BrowserType.Generic)
+ {
+ Logger.LogDebug("Unauthorized browser request (User-Agent: \"{0}\"), loading control panel...", browserResolver.UserAgent);
+ return File("~/index.html", MediaTypeNames.Text.Html);
+ }
+
+ return Unauthorized();
+ }
///
/// Attempt to authenticate a using
@@ -79,6 +112,9 @@ namespace Tgstation.Server.Host.Controllers
[HttpPost]
public async Task CreateToken(CancellationToken cancellationToken)
{
+ if (ApiHeaders == null)
+ return BadRequest(new Api.Models.ErrorMessage { Message = "Missing API headers!" });
+
if (ApiHeaders.IsTokenAuthentication)
return BadRequest(new Api.Models.ErrorMessage { Message = "Cannot create a token using another token!" });
diff --git a/src/Tgstation.Server.Host/Controllers/ModelController.cs b/src/Tgstation.Server.Host/Controllers/ModelController.cs
index 4dc35d41c3..3434992040 100644
--- a/src/Tgstation.Server.Host/Controllers/ModelController.cs
+++ b/src/Tgstation.Server.Host/Controllers/ModelController.cs
@@ -20,7 +20,7 @@ namespace Tgstation.Server.Host.Controllers
/// The for the
/// The for the
/// If the requires an
- public ModelController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, ILogger logger, bool requireInstance) : base(databaseContext, authenticationContextFactory, logger, requireInstance) { }
+ public ModelController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, ILogger logger, bool requireInstance) : base(databaseContext, authenticationContextFactory, logger, requireInstance, true) { }
///
/// Attempt to create a
diff --git a/src/Tgstation.Server.Host/Core/Application.cs b/src/Tgstation.Server.Host/Core/Application.cs
index b3e3286712..57bfdf56d2 100644
--- a/src/Tgstation.Server.Host/Core/Application.cs
+++ b/src/Tgstation.Server.Host/Core/Application.cs
@@ -227,6 +227,9 @@ namespace Tgstation.Server.Host.Core
options.SerializerSettings.Converters = new[] { new VersionConverter() };
});
+ //enable browser detection
+ services.AddDetectionCore().AddBrowser();
+
//enable CORS if necessary
if (controlPanelConfiguration.AllowAnyOrigin || controlPanelConfiguration.AllowedOrigins?.Count > 0)
services.AddCors();
diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
index 34c5371901..4d79f98e84 100644
--- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
+++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
@@ -26,9 +26,7 @@
ClientApp/node_modules/.install-stamp
-
+
@@ -38,17 +36,11 @@
-
-
-
+
-
+
@@ -81,6 +73,7 @@
+
@@ -107,8 +100,6 @@
-
-