diff --git a/src/Tgstation.Server.Api/ApiHeaders.cs b/src/Tgstation.Server.Api/ApiHeaders.cs index 9e7563e3cb..436ae6c412 100644 --- a/src/Tgstation.Server.Api/ApiHeaders.cs +++ b/src/Tgstation.Server.Api/ApiHeaders.cs @@ -15,10 +15,15 @@ namespace Tgstation.Server.Api /// public sealed class ApiHeaders { + /// + /// TODO: Remove this when https://github.com/dotnet/corefx/pull/26701 makes it into the sdk + /// + public const string ApplicationJson = "application/json"; + /// /// The username header key /// - const string usernameHeader = "Username"; + const string usernameHeader = "Username"; /// /// The JWT authentication header scheme @@ -30,11 +35,6 @@ namespace Tgstation.Server.Api /// const string passwordAuthenticationScheme = "Password"; - /// - /// TODO: Remove this when https://github.com/dotnet/corefx/pull/26701 makes it into the sdk - /// - const string applicationJson = "application/json"; - /// /// The current /// @@ -105,9 +105,9 @@ namespace Tgstation.Server.Api /// The containing the public ApiHeaders(RequestHeaders requestHeaders) { - var jsonAccept = new Microsoft.Net.Http.Headers.MediaTypeHeaderValue(applicationJson); + var jsonAccept = new Microsoft.Net.Http.Headers.MediaTypeHeaderValue(ApplicationJson); if (!requestHeaders.Accept.Any(x => x == jsonAccept)) - throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Client does not accept {0}!", applicationJson)); + throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Client does not accept {0}!", ApplicationJson)); if (!requestHeaders.Headers.TryGetValue(HeaderNames.UserAgent, out StringValues userAgentValues) || !ProductInfoHeaderValue.TryParse(userAgentValues.FirstOrDefault(), out ProductInfoHeaderValue clientUserAgent)) throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Missing {0} headers!", HeaderNames.UserAgent)); @@ -185,7 +185,7 @@ namespace Tgstation.Server.Api throw new ArgumentNullException(nameof(headers)); headers.Clear(); - headers.Accept.Add(new MediaTypeWithQualityHeaderValue(applicationJson)); + headers.Accept.Add(new MediaTypeWithQualityHeaderValue(ApplicationJson)); if (IsTokenAuthentication) headers.Authorization = new AuthenticationHeaderValue(jwtAuthenticationScheme, Token); else diff --git a/src/Tgstation.Server.Host/Controllers/ApiController.cs b/src/Tgstation.Server.Host/Controllers/ApiController.cs new file mode 100644 index 0000000000..b21f1edad4 --- /dev/null +++ b/src/Tgstation.Server.Host/Controllers/ApiController.cs @@ -0,0 +1,57 @@ +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Tgstation.Server.Api; +using Tgstation.Server.Host.Models; +using Tgstation.Server.Host.Security; + +namespace Tgstation.Server.Host.Controllers +{ + [Authorize] + [Produces(ApiHeaders.ApplicationJson)] + [Consumes(ApiHeaders.ApplicationJson)] + public abstract class ApiController : Controller + { + protected ModelAttribute ModelAttribute => (ModelAttribute)typeof(TModel).GetCustomAttributes(typeof(ModelAttribute), true).First(); + + protected ApiHeaders ApiHeaders { get; } + + protected IDatabaseContext DatabaseContext { get; } + + protected IAuthenticationContext AuthenticationContext { get; private set; } + + readonly ITokenFactory tokenManager; + + public ApiController(IDatabaseContext databaseContext, ITokenFactory tokenManager) + { + DatabaseContext = databaseContext ?? throw new ArgumentNullException(nameof(databaseContext)); + this.tokenManager = tokenManager ?? throw new ArgumentNullException(nameof(tokenManager)); + } + + public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) + { + User.Claims. + + await base.OnActionExecutionAsync(context, next).ConfigureAwait(false); + } + + [HttpPut] + public virtual Task Create([FromBody]TModel model, CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound()); + + [HttpGet] + public virtual Task Read(CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound()); + + [HttpPost] + public virtual Task Update([FromBody]TModel model, CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound()); + + [HttpDelete] + public virtual Task Delete([FromBody]TModel model, CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound()); + + [HttpGet("/List")] + public virtual Task List(CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound()); + } +} diff --git a/src/Tgstation.Server.Host/Controllers/HomeController.cs b/src/Tgstation.Server.Host/Controllers/HomeController.cs new file mode 100644 index 0000000000..6b4cdc87f5 --- /dev/null +++ b/src/Tgstation.Server.Host/Controllers/HomeController.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Mvc; +using System.Reflection; +using Tgstation.Server.Api; + +namespace Tgstation.Server.Host.Controllers +{ + [Route("/")] + [Produces(ApiHeaders.ApplicationJson)] + public sealed class HomeController : Controller + { + [HttpGet] + public JsonResult Home() => Json(Assembly.GetExecutingAssembly().GetName().Version); + } +} diff --git a/src/Tgstation.Server.Host/Models/ChatChannel.cs b/src/Tgstation.Server.Host/Models/ChatChannel.cs index e091361f49..8f57e1e885 100644 --- a/src/Tgstation.Server.Host/Models/ChatChannel.cs +++ b/src/Tgstation.Server.Host/Models/ChatChannel.cs @@ -1,7 +1,7 @@ namespace Tgstation.Server.Host.Models { /// - sealed class ChatChannel : Api.Models.ChatChannel + public sealed class ChatChannel : Api.Models.ChatChannel { /// /// The row Id diff --git a/src/Tgstation.Server.Host/Models/ChatSettings.cs b/src/Tgstation.Server.Host/Models/ChatSettings.cs index f81f562fa5..5d3df56af5 100644 --- a/src/Tgstation.Server.Host/Models/ChatSettings.cs +++ b/src/Tgstation.Server.Host/Models/ChatSettings.cs @@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations; namespace Tgstation.Server.Host.Models { /// - sealed class ChatSettings : Api.Models.Internal.ChatSettings + public sealed class ChatSettings : Api.Models.Internal.ChatSettings { /// /// The row Id diff --git a/src/Tgstation.Server.Host/Models/CompileJob.cs b/src/Tgstation.Server.Host/Models/CompileJob.cs index 2b8404da46..29bdac135c 100644 --- a/src/Tgstation.Server.Host/Models/CompileJob.cs +++ b/src/Tgstation.Server.Host/Models/CompileJob.cs @@ -3,7 +3,7 @@ namespace Tgstation.Server.Host.Models { /// - sealed class CompileJob : Api.Models.Internal.CompileJob + public sealed class CompileJob : Api.Models.Internal.CompileJob { /// /// See diff --git a/src/Tgstation.Server.Host/Models/DreamDaemonSettings.cs b/src/Tgstation.Server.Host/Models/DreamDaemonSettings.cs index 33d0246b77..6a1a550a42 100644 --- a/src/Tgstation.Server.Host/Models/DreamDaemonSettings.cs +++ b/src/Tgstation.Server.Host/Models/DreamDaemonSettings.cs @@ -3,7 +3,7 @@ namespace Tgstation.Server.Host.Models { /// - sealed class DreamDaemonSettings : Api.Models.Internal.DreamDaemonSettings + public sealed class DreamDaemonSettings : Api.Models.Internal.DreamDaemonSettings { /// /// The row Id diff --git a/src/Tgstation.Server.Host/Models/DreamMakerSettings.cs b/src/Tgstation.Server.Host/Models/DreamMakerSettings.cs index c6621a07f4..286be820a2 100644 --- a/src/Tgstation.Server.Host/Models/DreamMakerSettings.cs +++ b/src/Tgstation.Server.Host/Models/DreamMakerSettings.cs @@ -3,7 +3,7 @@ namespace Tgstation.Server.Host.Models { /// - sealed class DreamMakerSettings : Api.Models.Internal.DreamMakerSettings + public sealed class DreamMakerSettings : Api.Models.Internal.DreamMakerSettings { /// /// The row Id diff --git a/src/Tgstation.Server.Host/Models/IDatabaseContext.cs b/src/Tgstation.Server.Host/Models/IDatabaseContext.cs index 9330d3d175..9ed9acf3a4 100644 --- a/src/Tgstation.Server.Host/Models/IDatabaseContext.cs +++ b/src/Tgstation.Server.Host/Models/IDatabaseContext.cs @@ -7,7 +7,7 @@ namespace Tgstation.Server.Host.Models /// /// Represents the database /// - interface IDatabaseContext + public interface IDatabaseContext { /// /// The s in the diff --git a/src/Tgstation.Server.Host/Models/Instance.cs b/src/Tgstation.Server.Host/Models/Instance.cs index 59224b2edd..ca3a5bfad5 100644 --- a/src/Tgstation.Server.Host/Models/Instance.cs +++ b/src/Tgstation.Server.Host/Models/Instance.cs @@ -1,12 +1,11 @@ using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; namespace Tgstation.Server.Host.Models { /// /// Represents an in the database /// - sealed class Instance : Api.Models.Instance + public sealed class Instance : Api.Models.Instance { /// /// The for the diff --git a/src/Tgstation.Server.Host/Models/InstanceUser.cs b/src/Tgstation.Server.Host/Models/InstanceUser.cs index e2c343cbb1..7ccfc17ea0 100644 --- a/src/Tgstation.Server.Host/Models/InstanceUser.cs +++ b/src/Tgstation.Server.Host/Models/InstanceUser.cs @@ -1,7 +1,7 @@ namespace Tgstation.Server.Host.Models { /// - sealed class InstanceUser : Api.Models.InstanceUser + public sealed class InstanceUser : Api.Models.InstanceUser { /// /// The row Id diff --git a/src/Tgstation.Server.Host/Models/Job.cs b/src/Tgstation.Server.Host/Models/Job.cs index 005972d7d6..43d1fefba4 100644 --- a/src/Tgstation.Server.Host/Models/Job.cs +++ b/src/Tgstation.Server.Host/Models/Job.cs @@ -3,7 +3,7 @@ namespace Tgstation.Server.Host.Models { /// - sealed class Job : Api.Models.Internal.Job + public sealed class Job : Api.Models.Internal.Job { /// /// See diff --git a/src/Tgstation.Server.Host/Models/RepositorySettings.cs b/src/Tgstation.Server.Host/Models/RepositorySettings.cs index 5017df5343..77e529f2ec 100644 --- a/src/Tgstation.Server.Host/Models/RepositorySettings.cs +++ b/src/Tgstation.Server.Host/Models/RepositorySettings.cs @@ -3,7 +3,7 @@ namespace Tgstation.Server.Host.Models { /// - sealed class RepositorySettings : Api.Models.Internal.RepositorySettings + public sealed class RepositorySettings : Api.Models.Internal.RepositorySettings { /// /// The row Id diff --git a/src/Tgstation.Server.Host/Models/RevisionInformation.cs b/src/Tgstation.Server.Host/Models/RevisionInformation.cs index dddd11bb77..057cc7e680 100644 --- a/src/Tgstation.Server.Host/Models/RevisionInformation.cs +++ b/src/Tgstation.Server.Host/Models/RevisionInformation.cs @@ -3,7 +3,7 @@ namespace Tgstation.Server.Host.Models { /// - sealed class RevisionInformation : Api.Models.Internal.RevisionInformation + public sealed class RevisionInformation : Api.Models.Internal.RevisionInformation { /// /// The row Id diff --git a/src/Tgstation.Server.Host/Models/ServerSettings.cs b/src/Tgstation.Server.Host/Models/ServerSettings.cs index df05f75182..4326d9f563 100644 --- a/src/Tgstation.Server.Host/Models/ServerSettings.cs +++ b/src/Tgstation.Server.Host/Models/ServerSettings.cs @@ -1,7 +1,7 @@ namespace Tgstation.Server.Host.Models { /// - sealed class ServerSettings : Api.Models.Internal.ServerSettings + public sealed class ServerSettings : Api.Models.Internal.ServerSettings { /// /// The row Id diff --git a/src/Tgstation.Server.Host/Models/TestMerge.cs b/src/Tgstation.Server.Host/Models/TestMerge.cs index ad2eab8783..e72fc66e3c 100644 --- a/src/Tgstation.Server.Host/Models/TestMerge.cs +++ b/src/Tgstation.Server.Host/Models/TestMerge.cs @@ -3,7 +3,7 @@ namespace Tgstation.Server.Host.Models { /// - sealed class TestMerge : Api.Models.Internal.TestMerge + public sealed class TestMerge : Api.Models.Internal.TestMerge { /// /// See diff --git a/src/Tgstation.Server.Host/Models/User.cs b/src/Tgstation.Server.Host/Models/User.cs index edbd1ff2a5..dec14852f9 100644 --- a/src/Tgstation.Server.Host/Models/User.cs +++ b/src/Tgstation.Server.Host/Models/User.cs @@ -3,7 +3,7 @@ namespace Tgstation.Server.Host.Models { /// - sealed class User : Api.Models.Internal.User + public sealed class User : Api.Models.Internal.User { /// /// The hash of the user's password diff --git a/src/Tgstation.Server.Host/Security/IAuthenticationContext.cs b/src/Tgstation.Server.Host/Security/IAuthenticationContext.cs index 5766d51a44..e50a3c5467 100644 --- a/src/Tgstation.Server.Host/Security/IAuthenticationContext.cs +++ b/src/Tgstation.Server.Host/Security/IAuthenticationContext.cs @@ -6,7 +6,7 @@ namespace Tgstation.Server.Host.Security /// /// Represents the currently authenticated /// - interface IAuthenticationContext : IDisposable + public interface IAuthenticationContext : IDisposable { /// /// The authenticated user diff --git a/src/Tgstation.Server.Host/Security/ISystemIdentity.cs b/src/Tgstation.Server.Host/Security/ISystemIdentity.cs index 7d0196bdca..ff2dc3482c 100644 --- a/src/Tgstation.Server.Host/Security/ISystemIdentity.cs +++ b/src/Tgstation.Server.Host/Security/ISystemIdentity.cs @@ -8,7 +8,7 @@ namespace Tgstation.Server.Host.Security /// /// Represents a user on the current /// - interface ISystemIdentity : IDisposable + public interface ISystemIdentity : IDisposable { /// /// A unique identifier for the user diff --git a/src/Tgstation.Server.Host/Security/ITokenFactory.cs b/src/Tgstation.Server.Host/Security/ITokenFactory.cs index f7c05b6901..fdd8949ef6 100644 --- a/src/Tgstation.Server.Host/Security/ITokenFactory.cs +++ b/src/Tgstation.Server.Host/Security/ITokenFactory.cs @@ -7,7 +7,7 @@ namespace Tgstation.Server.Host.Security /// /// For creating s /// - interface ITokenFactory + public interface ITokenFactory { /// /// Create a for a given @@ -15,5 +15,7 @@ namespace Tgstation.Server.Host.Security /// The to create the token for. Must have the and fields available /// A new Token CreateToken(Models.User user); + + Task GetUser(Token token, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Security/TokenFactory.cs b/src/Tgstation.Server.Host/Security/TokenFactory.cs index 628c78cb5f..3db336e859 100644 --- a/src/Tgstation.Server.Host/Security/TokenFactory.cs +++ b/src/Tgstation.Server.Host/Security/TokenFactory.cs @@ -46,5 +46,11 @@ namespace Tgstation.Server.Host.Security var token = new JwtSecurityToken(new JwtHeader(new SigningCredentials(key, SecurityAlgorithms.HmacSha256)), new JwtPayload(claims)); return new Token { Value = new JwtSecurityTokenHandler().WriteToken(token) }; } + + /// + public Task GetUser(Token token, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } } } diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj index dfd05a5c72..a2125b38fb 100644 --- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj +++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj @@ -10,10 +10,12 @@ true bin\Release\netstandard2.0\Tgstation.Server.Host.xml + 1701;1702;1705;CA2227 latest + 1701;1702;1705;CA2227 @@ -62,8 +64,4 @@ - - - -