run dotnet format
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
namespace PluralKit.API
|
||||
namespace PluralKit.API
|
||||
{
|
||||
public class ApiConfig
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
|
||||
using PluralKit.Core;
|
||||
@@ -11,12 +11,12 @@ namespace PluralKit.API
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace PluralKit.API
|
||||
namespace PluralKit.API
|
||||
{
|
||||
public class PKClaims
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Encodings.Web;
|
||||
@@ -17,8 +17,8 @@ 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)
|
||||
|
||||
public SystemTokenAuthenticationHandler(IOptionsMonitor<Opts> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IDatabase db) : base(options, logger, encoder, clock)
|
||||
{
|
||||
_db = db;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ namespace PluralKit.API
|
||||
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 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);
|
||||
@@ -43,7 +43,7 @@ namespace PluralKit.API
|
||||
|
||||
public class Opts: AuthenticationSchemeOptions
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
@@ -6,7 +6,8 @@ using PluralKit.Core;
|
||||
|
||||
namespace PluralKit.API
|
||||
{
|
||||
public class MemberOwnerHandler: AuthorizationHandler<OwnSystemRequirement, PKMember> {
|
||||
public class MemberOwnerHandler: AuthorizationHandler<OwnSystemRequirement, PKMember>
|
||||
{
|
||||
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
|
||||
OwnSystemRequirement requirement, PKMember resource)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace PluralKit.API
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace PluralKit.API
|
||||
public class PrivacyRequirement<T>: IAuthorizationRequirement
|
||||
{
|
||||
public readonly Func<T, PrivacyLevel> Mapper;
|
||||
|
||||
|
||||
public PrivacyRequirement(Func<T, PrivacyLevel> mapper)
|
||||
{
|
||||
Mapper = mapper;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace PluralKit.API
|
||||
OwnSystemRequirement requirement, PKSystem resource)
|
||||
{
|
||||
if (!context.User.Identity.IsAuthenticated) return Task.CompletedTask;
|
||||
if (resource.Id == context.User.CurrentSystem())
|
||||
if (resource.Id == context.User.CurrentSystem())
|
||||
context.Succeed(requirement);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace PluralKit.API
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route( "v{version:apiVersion}/a" )]
|
||||
[Route("v{version:apiVersion}/a")]
|
||||
public class AccountController: ControllerBase
|
||||
{
|
||||
private readonly IDatabase _db;
|
||||
@@ -27,7 +27,7 @@ namespace PluralKit.API
|
||||
var system = await _db.Execute(c => _repo.GetSystemByAccount(c, aid));
|
||||
if (system == null)
|
||||
return NotFound("Account not found.");
|
||||
|
||||
|
||||
return Ok(system.ToJson(User.ContextFor(system)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace PluralKit.API
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route( "v{version:apiVersion}/m" )]
|
||||
[Route("v{version:apiVersion}/m")]
|
||||
public class MemberController: ControllerBase
|
||||
{
|
||||
private readonly IDatabase _db;
|
||||
@@ -43,14 +43,14 @@ namespace PluralKit.API
|
||||
{
|
||||
if (!properties.ContainsKey("name"))
|
||||
return BadRequest("Member name must be specified.");
|
||||
|
||||
|
||||
var systemId = User.CurrentSystem();
|
||||
|
||||
await using var conn = await _db.Obtain();
|
||||
var systemData = await _repo.GetSystem(conn, systemId);
|
||||
|
||||
// Enforce per-system member limit
|
||||
var memberCount = await conn.QuerySingleAsync<int>("select count(*) from members where system = @System", new {System = systemId});
|
||||
var memberCount = await conn.QuerySingleAsync<int>("select count(*) from members where system = @System", new { System = systemId });
|
||||
var memberLimit = systemData?.MemberLimitOverride ?? Limits.MaxMemberCount;
|
||||
if (memberCount >= memberLimit)
|
||||
return BadRequest($"Member limit reached ({memberCount} / {memberLimit}).");
|
||||
@@ -74,7 +74,7 @@ namespace PluralKit.API
|
||||
await tx.RollbackAsync();
|
||||
return BadRequest($"Request field '{e.Message}' is invalid.");
|
||||
}
|
||||
|
||||
|
||||
member = await _repo.UpdateMember(conn, member.Id, patch, transaction: tx);
|
||||
await tx.CommitAsync();
|
||||
return Ok(member.ToJson(User.ContextFor(member), needsLegacyProxyTags: true));
|
||||
@@ -88,7 +88,7 @@ namespace PluralKit.API
|
||||
|
||||
var member = await _repo.GetMemberByHid(conn, hid);
|
||||
if (member == null) return NotFound("Member not found.");
|
||||
|
||||
|
||||
var res = await _auth.AuthorizeAsync(User, member, "EditMember");
|
||||
if (!res.Succeeded) return Unauthorized($"Member '{hid}' is not part of your system.");
|
||||
|
||||
@@ -106,11 +106,11 @@ namespace PluralKit.API
|
||||
{
|
||||
return BadRequest($"Request field '{e.Message}' is invalid.");
|
||||
}
|
||||
|
||||
|
||||
var newMember = await _repo.UpdateMember(conn, member.Id, patch);
|
||||
return Ok(newMember.ToJson(User.ContextFor(newMember), needsLegacyProxyTags: true));
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete("{hid}")]
|
||||
[Authorize]
|
||||
public async Task<ActionResult> DeleteMember(string hid)
|
||||
@@ -119,7 +119,7 @@ namespace PluralKit.API
|
||||
|
||||
var member = await _repo.GetMemberByHid(conn, hid);
|
||||
if (member == null) return NotFound("Member not found.");
|
||||
|
||||
|
||||
var res = await _auth.AuthorizeAsync(User, member, "EditMember");
|
||||
if (!res.Succeeded) return Unauthorized($"Member '{hid}' is not part of your system.");
|
||||
|
||||
@@ -127,4 +127,4 @@ namespace PluralKit.API
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,10 @@ namespace PluralKit.API
|
||||
[JsonProperty("system")] public JObject System;
|
||||
[JsonProperty("member")] public JObject Member;
|
||||
}
|
||||
|
||||
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route( "v{version:apiVersion}/msg" )]
|
||||
[Route("v{version:apiVersion}/msg")]
|
||||
public class MessageController: ControllerBase
|
||||
{
|
||||
private readonly IDatabase _db;
|
||||
@@ -45,7 +45,7 @@ namespace PluralKit.API
|
||||
|
||||
return new MessageReturn
|
||||
{
|
||||
Timestamp = Instant.FromUnixTimeMilliseconds((long) (msg.Message.Mid >> 22) + 1420070400000),
|
||||
Timestamp = Instant.FromUnixTimeMilliseconds((long)(msg.Message.Mid >> 22) + 1420070400000),
|
||||
Id = msg.Message.Mid.ToString(),
|
||||
Channel = msg.Message.Channel.ToString(),
|
||||
Sender = msg.Message.Sender.ToString(),
|
||||
@@ -53,6 +53,6 @@ namespace PluralKit.API
|
||||
System = msg.System.ToJson(User.ContextFor(msg.System)),
|
||||
Original = msg.Message.OriginalMid?.ToString()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,8 @@ namespace PluralKit.API
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route( "v{version:apiVersion}" )]
|
||||
public class MetaController : ControllerBase
|
||||
[Route("v{version:apiVersion}")]
|
||||
public class MetaController: ControllerBase
|
||||
{
|
||||
private readonly IDatabase _db;
|
||||
private readonly ModelRepository _repo;
|
||||
@@ -33,7 +33,7 @@ namespace PluralKit.API
|
||||
var o = new JObject();
|
||||
o.Add("shards", shards.ToJSON());
|
||||
o.Add("version", BuildInfoService.Version);
|
||||
|
||||
|
||||
return Ok(o);
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ namespace PluralKit.API
|
||||
s.Add("status", "down");
|
||||
else
|
||||
s.Add("status", "up");
|
||||
|
||||
|
||||
s.Add("ping", shard.Ping);
|
||||
s.Add("last_heartbeat", shard.LastHeartbeat.ToString());
|
||||
s.Add("last_connection", shard.LastConnection.ToString());
|
||||
|
||||
@@ -37,8 +37,8 @@ namespace PluralKit.API
|
||||
|
||||
[ApiController]
|
||||
[ApiVersion("1.0")]
|
||||
[Route( "v{version:apiVersion}/s" )]
|
||||
public class SystemController : ControllerBase
|
||||
[Route("v{version:apiVersion}/s")]
|
||||
public class SystemController: ControllerBase
|
||||
{
|
||||
private readonly IDatabase _db;
|
||||
private readonly ModelRepository _repo;
|
||||
@@ -88,9 +88,9 @@ namespace PluralKit.API
|
||||
public async Task<ActionResult<IEnumerable<SwitchesReturn>>> GetSwitches(string hid, [FromQuery(Name = "before")] Instant? before)
|
||||
{
|
||||
if (before == null) before = SystemClock.Instance.GetCurrentInstant();
|
||||
|
||||
|
||||
await using var conn = await _db.Obtain();
|
||||
|
||||
|
||||
var system = await _repo.GetSystemByHid(conn, hid);
|
||||
if (system == null) return NotFound("System not found.");
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace PluralKit.API
|
||||
) as members from switches
|
||||
where switches.system = @System and switches.timestamp < @Before
|
||||
order by switches.timestamp desc
|
||||
limit 100;", new {System = system.Id, Before = before});
|
||||
limit 100;", new { System = system.Id, Before = before });
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
@@ -112,16 +112,16 @@ namespace PluralKit.API
|
||||
public async Task<ActionResult<FrontersReturn>> GetFronters(string hid)
|
||||
{
|
||||
await using var conn = await _db.Obtain();
|
||||
|
||||
|
||||
var system = await _repo.GetSystemByHid(conn, hid);
|
||||
if (system == null) return NotFound("System not found.");
|
||||
|
||||
|
||||
var auth = await _auth.AuthorizeAsync(User, system, "ViewFront");
|
||||
if (!auth.Succeeded) return StatusCode(StatusCodes.Status403Forbidden, "Unauthorized to view fronter.");
|
||||
|
||||
|
||||
var sw = await _repo.GetLatestSwitch(conn, system.Id);
|
||||
if (sw == null) return NotFound("System has no registered switches.");
|
||||
|
||||
if (sw == null) return NotFound("System has no registered switches.");
|
||||
|
||||
var members = _repo.GetSwitchMembers(conn, sw.Id);
|
||||
return Ok(new FrontersReturn
|
||||
{
|
||||
@@ -162,7 +162,7 @@ namespace PluralKit.API
|
||||
{
|
||||
if (param.Members.Distinct().Count() != param.Members.Count)
|
||||
return BadRequest("Duplicate members in member list.");
|
||||
|
||||
|
||||
await using var conn = await _db.Obtain();
|
||||
|
||||
// We get the current switch, if it exists
|
||||
@@ -177,8 +177,8 @@ namespace PluralKit.API
|
||||
}
|
||||
|
||||
// Resolve member objects for all given IDs
|
||||
var membersList = (await conn.QueryAsync<PKMember>("select * from members where hid = any(@Hids)", new {Hids = param.Members})).ToList();
|
||||
|
||||
var membersList = (await conn.QueryAsync<PKMember>("select * from members where hid = any(@Hids)", new { Hids = param.Members })).ToList();
|
||||
|
||||
foreach (var member in membersList)
|
||||
if (member.System != User.CurrentSystem())
|
||||
return BadRequest($"Cannot switch to member '{member.Hid}' not in system.");
|
||||
@@ -186,12 +186,12 @@ namespace PluralKit.API
|
||||
// membersList is in DB order, and we want it in actual input order
|
||||
// so we go through a dict and map the original input appropriately
|
||||
var membersDict = membersList.ToDictionary(m => m.Hid);
|
||||
|
||||
|
||||
var membersInOrder = new List<PKMember>();
|
||||
// We do this without .Select() since we want to have the early return bail if it doesn't find the member
|
||||
foreach (var givenMemberId in param.Members)
|
||||
{
|
||||
if (!membersDict.TryGetValue(givenMemberId, out var member))
|
||||
if (!membersDict.TryGetValue(givenMemberId, out var member))
|
||||
return BadRequest($"Member '{givenMemberId}' not found.");
|
||||
membersInOrder.Add(member);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
|
||||
|
||||
@@ -34,12 +34,12 @@ namespace PluralKit.API
|
||||
services.AddCors();
|
||||
services.AddAuthentication("SystemToken")
|
||||
.AddScheme<SystemTokenAuthenticationHandler.Opts, SystemTokenAuthenticationHandler>("SystemToken", null);
|
||||
|
||||
|
||||
services.AddAuthorization(options =>
|
||||
{
|
||||
options.AddPolicy("EditSystem", p => p.RequireAuthenticatedUser().AddRequirements(new OwnSystemRequirement()));
|
||||
options.AddPolicy("EditMember", p => p.RequireAuthenticatedUser().AddRequirements(new OwnSystemRequirement()));
|
||||
|
||||
|
||||
options.AddPolicy("ViewMembers", p => p.AddRequirements(new PrivacyRequirement<PKSystem>(s => s.MemberListPrivacy)));
|
||||
options.AddPolicy("ViewFront", p => p.AddRequirements(new PrivacyRequirement<PKSystem>(s => s.FrontPrivacy)));
|
||||
options.AddPolicy("ViewFrontHistory", p => p.AddRequirements(new PrivacyRequirement<PKSystem>(s => s.FrontHistoryPrivacy)));
|
||||
@@ -48,35 +48,35 @@ namespace PluralKit.API
|
||||
services.AddSingleton<IAuthorizationHandler, MemberOwnerHandler>();
|
||||
services.AddSingleton<IAuthorizationHandler, SystemOwnerHandler>();
|
||||
services.AddSingleton<IAuthorizationHandler, SystemPrivacyHandler>();
|
||||
|
||||
|
||||
services.AddControllers()
|
||||
.SetCompatibilityVersion(CompatibilityVersion.Latest)
|
||||
.AddNewtonsoftJson(); // sorry MS, this just does *more*
|
||||
|
||||
services.AddApiVersioning();
|
||||
|
||||
|
||||
services.AddVersionedApiExplorer(c =>
|
||||
{
|
||||
c.GroupNameFormat = "'v'VV";
|
||||
c.ApiVersionParameterSource = new UrlSegmentApiVersionReader();
|
||||
c.SubstituteApiVersionInUrl = true;
|
||||
});
|
||||
|
||||
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1.0", new OpenApiInfo {Title = "PluralKit", Version = "1.0"});
|
||||
|
||||
c.SwaggerDoc("v1.0", new OpenApiInfo { Title = "PluralKit", Version = "1.0" });
|
||||
|
||||
c.EnableAnnotations();
|
||||
c.AddSecurityDefinition("TokenAuth",
|
||||
new OpenApiSecurityScheme {Name = "Authorization", Type = SecuritySchemeType.ApiKey});
|
||||
|
||||
new OpenApiSecurityScheme { Name = "Authorization", Type = SecuritySchemeType.ApiKey });
|
||||
|
||||
// Exclude routes without a version, then fall back to group name matching (default behavior)
|
||||
c.DocInclusionPredicate((docName, apiDesc) =>
|
||||
{
|
||||
if (!apiDesc.RelativePath.StartsWith("v1/")) return false;
|
||||
return apiDesc.GroupName == docName;
|
||||
});
|
||||
|
||||
|
||||
// Set the comments path for the Swagger JSON and UI.
|
||||
// https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-3.1&tabs=visual-studio#customize-and-extend
|
||||
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||
@@ -103,7 +103,7 @@ namespace PluralKit.API
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
|
||||
|
||||
// Only enable Swagger stuff when ASPNETCORE_ENVIRONMENT=Development (for now)
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(c =>
|
||||
@@ -119,7 +119,7 @@ namespace PluralKit.API
|
||||
|
||||
//app.UseHttpsRedirection();
|
||||
app.UseCors(opts => opts.AllowAnyMethod().AllowAnyOrigin().WithHeaders("Content-Type", "Authorization"));
|
||||
|
||||
|
||||
app.UseRouting();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
Reference in New Issue
Block a user