mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-26 22:48:20 +01:00
Where am I...
This commit is contained in:
@@ -15,10 +15,15 @@ namespace Tgstation.Server.Api
|
||||
/// </summary>
|
||||
public sealed class ApiHeaders
|
||||
{
|
||||
/// <summary>
|
||||
/// TODO: Remove this when https://github.com/dotnet/corefx/pull/26701 makes it into the sdk
|
||||
/// </summary>
|
||||
public const string ApplicationJson = "application/json";
|
||||
|
||||
/// <summary>
|
||||
/// The username header key
|
||||
/// </summary>
|
||||
const string usernameHeader = "Username";
|
||||
const string usernameHeader = "Username";
|
||||
|
||||
/// <summary>
|
||||
/// The JWT authentication header scheme
|
||||
@@ -30,11 +35,6 @@ namespace Tgstation.Server.Api
|
||||
/// </summary>
|
||||
const string passwordAuthenticationScheme = "Password";
|
||||
|
||||
/// <summary>
|
||||
/// TODO: Remove this when https://github.com/dotnet/corefx/pull/26701 makes it into the sdk
|
||||
/// </summary>
|
||||
const string applicationJson = "application/json";
|
||||
|
||||
/// <summary>
|
||||
/// The current <see cref="AssemblyName"/>
|
||||
/// </summary>
|
||||
@@ -105,9 +105,9 @@ namespace Tgstation.Server.Api
|
||||
/// <param name="requestHeaders">The <see cref="RequestHeaders"/> containing the <see cref="ApiHeaders"/></param>
|
||||
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
|
||||
|
||||
@@ -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<TModel> : 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<IActionResult> Create([FromBody]TModel model, CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound());
|
||||
|
||||
[HttpGet]
|
||||
public virtual Task<IActionResult> Read(CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound());
|
||||
|
||||
[HttpPost]
|
||||
public virtual Task<IActionResult> Update([FromBody]TModel model, CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound());
|
||||
|
||||
[HttpDelete]
|
||||
public virtual Task<IActionResult> Delete([FromBody]TModel model, CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound());
|
||||
|
||||
[HttpGet("/List")]
|
||||
public virtual Task<IActionResult> List(CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class ChatChannel : Api.Models.ChatChannel
|
||||
public sealed class ChatChannel : Api.Models.ChatChannel
|
||||
{
|
||||
/// <summary>
|
||||
/// The row Id
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations;
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class ChatSettings : Api.Models.Internal.ChatSettings
|
||||
public sealed class ChatSettings : Api.Models.Internal.ChatSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The row Id
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class CompileJob : Api.Models.Internal.CompileJob
|
||||
public sealed class CompileJob : Api.Models.Internal.CompileJob
|
||||
{
|
||||
/// <summary>
|
||||
/// See <see cref="Api.Models.CompileJob.TriggeredBy"/>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class DreamDaemonSettings : Api.Models.Internal.DreamDaemonSettings
|
||||
public sealed class DreamDaemonSettings : Api.Models.Internal.DreamDaemonSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The row Id
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class DreamMakerSettings : Api.Models.Internal.DreamMakerSettings
|
||||
public sealed class DreamMakerSettings : Api.Models.Internal.DreamMakerSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The row Id
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Tgstation.Server.Host.Models
|
||||
/// <summary>
|
||||
/// Represents the database
|
||||
/// </summary>
|
||||
interface IDatabaseContext
|
||||
public interface IDatabaseContext
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="User"/>s in the <see cref="IDatabaseContext"/>
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an <see cref="Api.Models.Instance"/> in the database
|
||||
/// </summary>
|
||||
sealed class Instance : Api.Models.Instance
|
||||
public sealed class Instance : Api.Models.Instance
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="Models.ChatSettings"/> for the <see cref="Instance"/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class InstanceUser : Api.Models.InstanceUser
|
||||
public sealed class InstanceUser : Api.Models.InstanceUser
|
||||
{
|
||||
/// <summary>
|
||||
/// The row Id
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class Job : Api.Models.Internal.Job
|
||||
public sealed class Job : Api.Models.Internal.Job
|
||||
{
|
||||
/// <summary>
|
||||
/// See <see cref="Api.Models.Job.StartedBy"/>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class RepositorySettings : Api.Models.Internal.RepositorySettings
|
||||
public sealed class RepositorySettings : Api.Models.Internal.RepositorySettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The row Id
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class RevisionInformation : Api.Models.Internal.RevisionInformation
|
||||
public sealed class RevisionInformation : Api.Models.Internal.RevisionInformation
|
||||
{
|
||||
/// <summary>
|
||||
/// The row Id
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class ServerSettings : Api.Models.Internal.ServerSettings
|
||||
public sealed class ServerSettings : Api.Models.Internal.ServerSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The row Id
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class TestMerge : Api.Models.Internal.TestMerge
|
||||
public sealed class TestMerge : Api.Models.Internal.TestMerge
|
||||
{
|
||||
/// <summary>
|
||||
/// See <see cref="Api.Models.TestMerge.MergedBy"/>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Tgstation.Server.Host.Models
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class User : Api.Models.Internal.User
|
||||
public sealed class User : Api.Models.Internal.User
|
||||
{
|
||||
/// <summary>
|
||||
/// The hash of the user's password
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Tgstation.Server.Host.Security
|
||||
/// <summary>
|
||||
/// Represents the currently authenticated <see cref="Api.Models.User"/>
|
||||
/// </summary>
|
||||
interface IAuthenticationContext : IDisposable
|
||||
public interface IAuthenticationContext : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The authenticated user
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Tgstation.Server.Host.Security
|
||||
/// <summary>
|
||||
/// Represents a user on the current <see cref="System.Runtime.InteropServices.OSPlatform"/>
|
||||
/// </summary>
|
||||
interface ISystemIdentity : IDisposable
|
||||
public interface ISystemIdentity : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// A unique identifier for the user
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Tgstation.Server.Host.Security
|
||||
/// <summary>
|
||||
/// For creating <see cref="Token"/>s
|
||||
/// </summary>
|
||||
interface ITokenFactory
|
||||
public interface ITokenFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a <see cref="Token"/> for a given <paramref name="user"/>
|
||||
@@ -15,5 +15,7 @@ namespace Tgstation.Server.Host.Security
|
||||
/// <param name="user">The <see cref="Models.User"/> to create the token for. Must have the <see cref="Api.Models.Internal.User.Id"/> and <see cref="Models.User.TokenSecret"/> fields available</param>
|
||||
/// <returns>A new <see cref="Token"/></returns>
|
||||
Token CreateToken(Models.User user);
|
||||
|
||||
Task<User> GetUser(Token token, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) };
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<User> GetUser(Token token, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<WarningsAsErrors />
|
||||
<DocumentationFile>bin\Release\netstandard2.0\Tgstation.Server.Host.xml</DocumentationFile>
|
||||
<NoWarn>1701;1702;1705;CA2227</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<LangVersion>latest</LangVersion>
|
||||
<NoWarn>1701;1702;1705;CA2227</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -62,8 +64,4 @@
|
||||
<ProjectReference Include="..\Tgstation.Server.Host.Startup\Tgstation.Server.Host.Startup.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Controllers\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user