Migrate API to ASP.NET Core Auth services + refactor
This commit is contained in:
32
PluralKit.API/Authentication/AuthExt.cs
Normal file
32
PluralKit.API/Authentication/AuthExt.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
|
||||
using PluralKit.Core;
|
||||
|
||||
namespace PluralKit.API
|
||||
{
|
||||
public static class AuthExt
|
||||
{
|
||||
public static SystemId CurrentSystem(this ClaimsPrincipal user)
|
||||
{
|
||||
var claim = user.FindFirst(PKClaims.SystemId);
|
||||
if (claim == null) throw new ArgumentException("User is unauthorized");
|
||||
|
||||
if (int.TryParse(claim.Value, out var id))
|
||||
return new SystemId(id);
|
||||
throw new ArgumentException("User has non-integer system ID claim");
|
||||
}
|
||||
|
||||
public static LookupContext ContextFor(this ClaimsPrincipal user, PKSystem system)
|
||||
{
|
||||
if (!user.Identity.IsAuthenticated) return LookupContext.API;
|
||||
return system.Id == user.CurrentSystem() ? LookupContext.ByOwner : LookupContext.API;
|
||||
}
|
||||
|
||||
public static LookupContext ContextFor(this ClaimsPrincipal user, PKMember member)
|
||||
{
|
||||
if (!user.Identity.IsAuthenticated) return LookupContext.API;
|
||||
return member.System == user.CurrentSystem() ? LookupContext.ByOwner : LookupContext.API;
|
||||
}
|
||||
}
|
||||
}
|
7
PluralKit.API/Authentication/PKClaims.cs
Normal file
7
PluralKit.API/Authentication/PKClaims.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace PluralKit.API
|
||||
{
|
||||
public class PKClaims
|
||||
{
|
||||
public const string SystemId = "PluralKit:SystemId";
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Dapper;
|
||||
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
using PluralKit.Core;
|
||||
|
||||
namespace PluralKit.API
|
||||
{
|
||||
public class SystemTokenAuthenticationHandler: AuthenticationHandler<SystemTokenAuthenticationHandler.Opts>
|
||||
{
|
||||
private readonly IDatabase _db;
|
||||
|
||||
public SystemTokenAuthenticationHandler(IOptionsMonitor<Opts> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IDatabase db): base(options, logger, encoder, clock)
|
||||
{
|
||||
_db = db;
|
||||
}
|
||||
|
||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
if (!Request.Headers.ContainsKey("Authorization"))
|
||||
return AuthenticateResult.NoResult();
|
||||
|
||||
var token = Request.Headers["Authorization"].FirstOrDefault();
|
||||
var systemId = await _db.Execute(c => c.QuerySingleOrDefaultAsync<SystemId?>("select id from systems where token = @token", new { token }));
|
||||
if (systemId == null) return AuthenticateResult.Fail("Invalid system token");
|
||||
|
||||
var claims = new[] {new Claim(PKClaims.SystemId, systemId.Value.Value.ToString())};
|
||||
var identity = new ClaimsIdentity(claims, Scheme.Name);
|
||||
var principal = new ClaimsPrincipal(identity);
|
||||
var ticket = new AuthenticationTicket(principal, Scheme.Name);
|
||||
ticket.Properties.IsPersistent = false;
|
||||
ticket.Properties.AllowRefresh = false;
|
||||
return AuthenticateResult.Success(ticket);
|
||||
}
|
||||
|
||||
public class Opts: AuthenticationSchemeOptions
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user