Major database refactor (again)
This commit is contained in:
@@ -13,18 +13,20 @@ namespace PluralKit.API
|
||||
[Route( "v{version:apiVersion}/a" )]
|
||||
public class AccountController: ControllerBase
|
||||
{
|
||||
private IDataStore _data;
|
||||
|
||||
public AccountController(IDataStore data)
|
||||
private readonly IDatabase _db;
|
||||
private readonly ModelRepository _repo;
|
||||
public AccountController(IDatabase db, ModelRepository repo)
|
||||
{
|
||||
_data = data;
|
||||
_db = db;
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
[HttpGet("{aid}")]
|
||||
public async Task<ActionResult<JObject>> GetSystemByAccount(ulong aid)
|
||||
{
|
||||
var system = await _data.GetSystemByAccount(aid);
|
||||
if (system == null) return NotFound("Account not found.");
|
||||
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)));
|
||||
}
|
||||
|
@@ -16,19 +16,21 @@ namespace PluralKit.API
|
||||
[Route( "v{version:apiVersion}/m" )]
|
||||
public class MemberController: ControllerBase
|
||||
{
|
||||
private IDatabase _db;
|
||||
private IAuthorizationService _auth;
|
||||
private readonly IDatabase _db;
|
||||
private readonly ModelRepository _repo;
|
||||
private readonly IAuthorizationService _auth;
|
||||
|
||||
public MemberController(IAuthorizationService auth, IDatabase db)
|
||||
public MemberController(IAuthorizationService auth, IDatabase db, ModelRepository repo)
|
||||
{
|
||||
_auth = auth;
|
||||
_db = db;
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
[HttpGet("{hid}")]
|
||||
public async Task<ActionResult<JObject>> GetMember(string hid)
|
||||
{
|
||||
var member = await _db.Execute(conn => conn.QueryMemberByHid(hid));
|
||||
var member = await _db.Execute(conn => _repo.GetMemberByHid(conn, hid));
|
||||
if (member == null) return NotFound("Member not found.");
|
||||
|
||||
return Ok(member.ToJson(User.ContextFor(member)));
|
||||
@@ -49,7 +51,7 @@ namespace PluralKit.API
|
||||
if (memberCount >= Limits.MaxMemberCount)
|
||||
return BadRequest($"Member limit reached ({memberCount} / {Limits.MaxMemberCount}).");
|
||||
|
||||
var member = await conn.CreateMember(system, properties.Value<string>("name"));
|
||||
var member = await _repo.CreateMember(conn, system, properties.Value<string>("name"));
|
||||
MemberPatch patch;
|
||||
try
|
||||
{
|
||||
@@ -60,7 +62,7 @@ namespace PluralKit.API
|
||||
return BadRequest(e.Message);
|
||||
}
|
||||
|
||||
member = await conn.UpdateMember(member.Id, patch);
|
||||
member = await _repo.UpdateMember(conn, member.Id, patch);
|
||||
return Ok(member.ToJson(User.ContextFor(member)));
|
||||
}
|
||||
|
||||
@@ -70,7 +72,7 @@ namespace PluralKit.API
|
||||
{
|
||||
await using var conn = await _db.Obtain();
|
||||
|
||||
var member = await conn.QueryMemberByHid(hid);
|
||||
var member = await _repo.GetMemberByHid(conn, hid);
|
||||
if (member == null) return NotFound("Member not found.");
|
||||
|
||||
var res = await _auth.AuthorizeAsync(User, member, "EditMember");
|
||||
@@ -86,7 +88,7 @@ namespace PluralKit.API
|
||||
return BadRequest(e.Message);
|
||||
}
|
||||
|
||||
var newMember = await conn.UpdateMember(member.Id, patch);
|
||||
var newMember = await _repo.UpdateMember(conn, member.Id, patch);
|
||||
return Ok(newMember.ToJson(User.ContextFor(newMember)));
|
||||
}
|
||||
|
||||
@@ -96,13 +98,13 @@ namespace PluralKit.API
|
||||
{
|
||||
await using var conn = await _db.Obtain();
|
||||
|
||||
var member = await conn.QueryMemberByHid(hid);
|
||||
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.");
|
||||
|
||||
await conn.DeleteMember(member.Id);
|
||||
await _repo.DeleteMember(conn, member.Id);
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
|
@@ -28,17 +28,19 @@ namespace PluralKit.API
|
||||
[Route( "v{version:apiVersion}/msg" )]
|
||||
public class MessageController: ControllerBase
|
||||
{
|
||||
private IDataStore _data;
|
||||
private readonly IDatabase _db;
|
||||
private readonly ModelRepository _repo;
|
||||
|
||||
public MessageController(IDataStore _data)
|
||||
public MessageController(ModelRepository repo, IDatabase db)
|
||||
{
|
||||
this._data = _data;
|
||||
_repo = repo;
|
||||
_db = db;
|
||||
}
|
||||
|
||||
[HttpGet("{mid}")]
|
||||
public async Task<ActionResult<MessageReturn>> GetMessage(ulong mid)
|
||||
{
|
||||
var msg = await _data.GetMessage(mid);
|
||||
var msg = await _db.Execute(c => _repo.GetMessage(c, mid));
|
||||
if (msg == null) return NotFound("Message not found.");
|
||||
|
||||
return new MessageReturn
|
||||
|
@@ -39,29 +39,29 @@ namespace PluralKit.API
|
||||
[Route( "v{version:apiVersion}/s" )]
|
||||
public class SystemController : ControllerBase
|
||||
{
|
||||
private IDataStore _data;
|
||||
private IDatabase _db;
|
||||
private IAuthorizationService _auth;
|
||||
private readonly IDatabase _db;
|
||||
private readonly ModelRepository _repo;
|
||||
private readonly IAuthorizationService _auth;
|
||||
|
||||
public SystemController(IDataStore data, IDatabase db, IAuthorizationService auth)
|
||||
public SystemController(IDatabase db, IAuthorizationService auth, ModelRepository repo)
|
||||
{
|
||||
_data = data;
|
||||
_db = db;
|
||||
_auth = auth;
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Authorize]
|
||||
public async Task<ActionResult<JObject>> GetOwnSystem()
|
||||
{
|
||||
var system = await _db.Execute(c => c.QuerySystem(User.CurrentSystem()));
|
||||
var system = await _db.Execute(c => _repo.GetSystem(c, User.CurrentSystem()));
|
||||
return system.ToJson(User.ContextFor(system));
|
||||
}
|
||||
|
||||
[HttpGet("{hid}")]
|
||||
public async Task<ActionResult<JObject>> GetSystem(string hid)
|
||||
{
|
||||
var system = await _data.GetSystemByHid(hid);
|
||||
var system = await _db.Execute(c => _repo.GetSystemByHid(c, hid));
|
||||
if (system == null) return NotFound("System not found.");
|
||||
return Ok(system.ToJson(User.ContextFor(system)));
|
||||
}
|
||||
@@ -69,13 +69,14 @@ namespace PluralKit.API
|
||||
[HttpGet("{hid}/members")]
|
||||
public async Task<ActionResult<IEnumerable<JObject>>> GetMembers(string hid)
|
||||
{
|
||||
var system = await _data.GetSystemByHid(hid);
|
||||
if (system == null) return NotFound("System not found.");
|
||||
var system = await _db.Execute(c => _repo.GetSystemByHid(c, hid));
|
||||
if (system == null)
|
||||
return NotFound("System not found.");
|
||||
|
||||
if (!system.MemberListPrivacy.CanAccess(User.ContextFor(system)))
|
||||
return StatusCode(StatusCodes.Status403Forbidden, "Unauthorized to view member list.");
|
||||
|
||||
var members = _data.GetSystemMembers(system);
|
||||
var members = _db.Execute(c => _repo.GetSystemMembers(c, system.Id));
|
||||
return Ok(await members
|
||||
.Where(m => m.MemberVisibility.CanAccess(User.ContextFor(system)))
|
||||
.Select(m => m.ToJson(User.ContextFor(system)))
|
||||
@@ -87,39 +88,40 @@ namespace PluralKit.API
|
||||
{
|
||||
if (before == null) before = SystemClock.Instance.GetCurrentInstant();
|
||||
|
||||
var system = await _data.GetSystemByHid(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, "ViewFrontHistory");
|
||||
if (!auth.Succeeded) return StatusCode(StatusCodes.Status403Forbidden, "Unauthorized to view front history.");
|
||||
|
||||
using (var conn = await _db.Obtain())
|
||||
{
|
||||
var res = await conn.QueryAsync<SwitchesReturn>(
|
||||
@"select *, array(
|
||||
var res = await conn.QueryAsync<SwitchesReturn>(
|
||||
@"select *, array(
|
||||
select members.hid from switch_members, members
|
||||
where switch_members.switch = switches.id and members.id = switch_members.member
|
||||
) 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});
|
||||
return Ok(res);
|
||||
}
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
[HttpGet("{hid}/fronters")]
|
||||
public async Task<ActionResult<FrontersReturn>> GetFronters(string hid)
|
||||
{
|
||||
var system = await _data.GetSystemByHid(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 _data.GetLatestSwitch(system.Id);
|
||||
var sw = await _repo.GetLatestSwitch(conn, system.Id);
|
||||
if (sw == null) return NotFound("System has no registered switches.");
|
||||
|
||||
var members = _data.GetSwitchMembers(sw);
|
||||
var members = _repo.GetSwitchMembers(conn, sw.Id);
|
||||
return Ok(new FrontersReturn
|
||||
{
|
||||
Timestamp = sw.Timestamp,
|
||||
@@ -131,7 +133,8 @@ namespace PluralKit.API
|
||||
[Authorize]
|
||||
public async Task<ActionResult<JObject>> EditSystem([FromBody] JObject changes)
|
||||
{
|
||||
var system = await _db.Execute(c => c.QuerySystem(User.CurrentSystem()));
|
||||
await using var conn = await _db.Obtain();
|
||||
var system = await _repo.GetSystem(conn, User.CurrentSystem());
|
||||
|
||||
SystemPatch patch;
|
||||
try
|
||||
@@ -143,7 +146,7 @@ namespace PluralKit.API
|
||||
return BadRequest(e.Message);
|
||||
}
|
||||
|
||||
await _db.Execute(conn => conn.UpdateSystem(system.Id, patch));
|
||||
await _repo.UpdateSystem(conn, system!.Id, patch);
|
||||
return Ok(system.ToJson(User.ContextFor(system)));
|
||||
}
|
||||
|
||||
@@ -154,11 +157,13 @@ 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
|
||||
var latestSwitch = await _data.GetLatestSwitch(User.CurrentSystem());
|
||||
var latestSwitch = await _repo.GetLatestSwitch(conn, User.CurrentSystem());
|
||||
if (latestSwitch != null)
|
||||
{
|
||||
var latestSwitchMembers = _data.GetSwitchMembers(latestSwitch);
|
||||
var latestSwitchMembers = _repo.GetSwitchMembers(conn, latestSwitch.Id);
|
||||
|
||||
// Bail if this switch is identical to the latest one
|
||||
if (await latestSwitchMembers.Select(m => m.Hid).SequenceEqualAsync(param.Members.ToAsyncEnumerable()))
|
||||
@@ -166,9 +171,7 @@ namespace PluralKit.API
|
||||
}
|
||||
|
||||
// Resolve member objects for all given IDs
|
||||
IEnumerable<PKMember> membersList;
|
||||
using (var conn = await _db.Obtain())
|
||||
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())
|
||||
@@ -182,12 +185,13 @@ namespace PluralKit.API
|
||||
// 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)) return BadRequest($"Member '{givenMemberId}' not found.");
|
||||
if (!membersDict.TryGetValue(givenMemberId, out var member))
|
||||
return BadRequest($"Member '{givenMemberId}' not found.");
|
||||
membersInOrder.Add(member);
|
||||
}
|
||||
|
||||
// Finally, log the switch (yay!)
|
||||
await _data.AddSwitch(User.CurrentSystem(), membersInOrder);
|
||||
await _repo.AddSwitch(conn, User.CurrentSystem(), membersInOrder.Select(m => m.Id).ToList());
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user