2021-09-30 02:30:20 +00:00
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
|
|
|
using PluralKit.Core;
|
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
namespace PluralKit.API;
|
|
|
|
|
|
|
|
[ApiController]
|
2022-01-20 00:25:04 +00:00
|
|
|
[Route("v2")]
|
2021-11-27 02:10:56 +00:00
|
|
|
public class MemberControllerV2: PKControllerBase
|
2021-09-30 02:30:20 +00:00
|
|
|
{
|
2021-11-27 02:10:56 +00:00
|
|
|
public MemberControllerV2(IServiceProvider svc) : base(svc) { }
|
2021-09-30 02:30:20 +00:00
|
|
|
|
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpGet("systems/{systemRef}/members")]
|
|
|
|
public async Task<IActionResult> GetSystemMembers(string systemRef)
|
|
|
|
{
|
|
|
|
var system = await ResolveSystem(systemRef);
|
|
|
|
if (system == null)
|
|
|
|
throw Errors.SystemNotFound;
|
2021-10-12 09:17:54 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var ctx = ContextFor(system);
|
2021-10-12 09:17:54 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
if (!system.MemberListPrivacy.CanAccess(ContextFor(system)))
|
|
|
|
throw Errors.UnauthorizedMemberList;
|
2021-10-12 09:17:54 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var members = _repo.GetSystemMembers(system.Id);
|
|
|
|
return Ok(await members
|
|
|
|
.Where(m => m.MemberVisibility.CanAccess(ctx))
|
|
|
|
.Select(m => m.ToJson(ctx, v: APIVersion.V2))
|
|
|
|
.ToListAsync());
|
|
|
|
}
|
2021-09-30 02:30:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpPost("members")]
|
|
|
|
public async Task<IActionResult> MemberCreate([FromBody] JObject data)
|
|
|
|
{
|
|
|
|
var system = await ResolveSystem("@me");
|
2021-11-30 02:35:21 +00:00
|
|
|
var config = await _repo.GetSystemConfig(system.Id);
|
2021-11-03 06:42:37 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var memberCount = await _repo.GetSystemMemberCount(system.Id);
|
2021-11-30 02:35:21 +00:00
|
|
|
var memberLimit = config.MemberLimitOverride ?? Limits.MaxMemberCount;
|
2021-11-27 02:10:56 +00:00
|
|
|
if (memberCount >= memberLimit)
|
|
|
|
throw Errors.MemberLimitReached;
|
2021-11-03 06:42:37 +00:00
|
|
|
|
2021-11-28 12:20:35 +00:00
|
|
|
var patch = MemberPatch.FromJSON(data, APIVersion.V2);
|
2021-11-27 02:10:56 +00:00
|
|
|
patch.AssertIsValid();
|
|
|
|
if (!patch.Name.IsPresent)
|
|
|
|
patch.Errors.Add(new ValidationError("name", "Key 'name' is required when creating new member."));
|
|
|
|
if (patch.Errors.Count > 0)
|
|
|
|
throw new ModelParseError(patch.Errors);
|
2021-10-14 13:35:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
using var conn = await _db.Obtain();
|
|
|
|
using var tx = await conn.BeginTransactionAsync();
|
2021-10-14 13:35:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var newMember = await _repo.CreateMember(system.Id, patch.Name.Value, conn);
|
|
|
|
newMember = await _repo.UpdateMember(newMember.Id, patch, conn);
|
2021-10-14 13:35:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
_ = _dispatch.Dispatch(newMember.Id, new()
|
|
|
|
{
|
|
|
|
Event = DispatchEvent.CREATE_MEMBER,
|
|
|
|
EventData = patch.ToJson(),
|
|
|
|
});
|
2021-11-25 20:33:02 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
await tx.CommitAsync();
|
2021-10-14 13:35:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
return Ok(newMember.ToJson(LookupContext.ByOwner, v: APIVersion.V2));
|
|
|
|
}
|
2021-09-30 02:30:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpGet("members/{memberRef}")]
|
|
|
|
public async Task<IActionResult> MemberGet(string memberRef)
|
|
|
|
{
|
|
|
|
var member = await ResolveMember(memberRef);
|
|
|
|
if (member == null)
|
|
|
|
throw Errors.MemberNotFound;
|
2021-10-12 09:17:54 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var system = await _repo.GetSystem(member.System);
|
2021-10-12 09:17:54 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
return Ok(member.ToJson(ContextFor(member), systemStr: system.Hid, v: APIVersion.V2));
|
|
|
|
}
|
2021-09-30 02:30:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpPatch("members/{memberRef}")]
|
|
|
|
public async Task<IActionResult> DoMemberPatch(string memberRef, [FromBody] JObject data)
|
|
|
|
{
|
|
|
|
var system = await ResolveSystem("@me");
|
|
|
|
var member = await ResolveMember(memberRef);
|
|
|
|
if (member == null)
|
|
|
|
throw Errors.MemberNotFound;
|
|
|
|
if (member.System != system.Id)
|
|
|
|
throw Errors.NotOwnMemberError;
|
2021-10-14 13:35:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var patch = MemberPatch.FromJSON(data, APIVersion.V2);
|
2021-10-14 13:35:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
patch.AssertIsValid();
|
|
|
|
if (patch.Errors.Count > 0)
|
|
|
|
throw new ModelParseError(patch.Errors);
|
2021-10-14 13:35:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var newMember = await _repo.UpdateMember(member.Id, patch);
|
|
|
|
return Ok(newMember.ToJson(LookupContext.ByOwner, v: APIVersion.V2));
|
|
|
|
}
|
2021-09-30 02:30:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpDelete("members/{memberRef}")]
|
|
|
|
public async Task<IActionResult> MemberDelete(string memberRef)
|
|
|
|
{
|
|
|
|
var member = await ResolveMember(memberRef);
|
|
|
|
if (member == null)
|
|
|
|
throw Errors.MemberNotFound;
|
2021-09-30 02:30:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var system = await ResolveSystem("@me");
|
|
|
|
if (system.Id != member.System)
|
|
|
|
throw Errors.NotOwnMemberError;
|
2021-09-30 02:30:20 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
await _repo.DeleteMember(member.Id);
|
2021-10-12 10:41:38 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
return NoContent();
|
2021-09-30 02:30:20 +00:00
|
|
|
}
|
|
|
|
}
|