2021-10-02 01:50:01 +00:00
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
2021-10-12 09:17:54 +00:00
|
|
|
using PluralKit.Core;
|
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
namespace PluralKit.API;
|
2021-10-02 01:50:01 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[ApiController]
|
2022-01-20 00:25:04 +00:00
|
|
|
[Route("v2")]
|
2021-11-27 02:10:56 +00:00
|
|
|
public class GroupMemberControllerV2: PKControllerBase
|
|
|
|
{
|
|
|
|
public GroupMemberControllerV2(IServiceProvider svc) : base(svc) { }
|
2021-10-12 09:17:54 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpGet("groups/{groupRef}/members")]
|
|
|
|
public async Task<IActionResult> GetGroupMembers(string groupRef)
|
|
|
|
{
|
|
|
|
var group = await ResolveGroup(groupRef);
|
|
|
|
if (group == null)
|
|
|
|
throw Errors.GroupNotFound;
|
2021-10-12 09:17:54 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var ctx = ContextFor(group);
|
2021-10-12 09:17:54 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
if (!group.ListPrivacy.CanAccess(ctx))
|
|
|
|
throw Errors.UnauthorizedGroupMemberList;
|
2021-10-12 09:17:54 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var members = _repo.GetGroupMembers(group.Id).Where(m => m.MemberVisibility.CanAccess(ctx));
|
2021-10-02 01:50:01 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var o = new JArray();
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
await foreach (var member in members)
|
2022-04-20 16:20:03 +00:00
|
|
|
o.Add(member.ToJson(ctx));
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
return Ok(o);
|
|
|
|
}
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpPost("groups/{groupRef}/members/add")]
|
|
|
|
public async Task<IActionResult> AddGroupMembers(string groupRef, [FromBody] JArray memberRefs)
|
|
|
|
{
|
|
|
|
if (memberRefs.Count == 0)
|
|
|
|
throw Errors.GenericBadRequest;
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var system = await ResolveSystem("@me");
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var group = await ResolveGroup(groupRef);
|
|
|
|
if (group == null)
|
|
|
|
throw Errors.GroupNotFound;
|
|
|
|
if (group.System != system.Id)
|
|
|
|
throw Errors.NotOwnGroupError;
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var members = new List<MemberId>();
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
foreach (var JmemberRef in memberRefs)
|
|
|
|
{
|
|
|
|
var memberRef = JmemberRef.Value<string>();
|
2022-04-07 07:48:32 +00:00
|
|
|
var member = await ResolveMember(memberRef, cache: true);
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
// todo: have a list of these errors instead of immediately throwing
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
if (member == null)
|
|
|
|
throw Errors.MemberNotFoundWithRef(memberRef);
|
|
|
|
if (member.System != system.Id)
|
|
|
|
throw Errors.NotOwnMemberErrorWithRef(memberRef);
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
members.Add(member.Id);
|
2021-10-02 01:50:01 +00:00
|
|
|
}
|
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var existingMembers = await _repo.GetGroupMembers(group.Id).Select(x => x.Id).ToListAsync();
|
|
|
|
members = members.Where(x => !existingMembers.Contains(x)).ToList();
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
if (members.Count > 0)
|
|
|
|
await _repo.AddMembersToGroup(group.Id, members);
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
return NoContent();
|
|
|
|
}
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpPost("groups/{groupRef}/members/remove")]
|
|
|
|
public async Task<IActionResult> RemoveGroupMembers(string groupRef, [FromBody] JArray memberRefs)
|
|
|
|
{
|
|
|
|
if (memberRefs.Count == 0)
|
|
|
|
throw Errors.GenericBadRequest;
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var system = await ResolveSystem("@me");
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var group = await ResolveGroup(groupRef);
|
|
|
|
if (group == null)
|
|
|
|
throw Errors.GroupNotFound;
|
|
|
|
if (group.System != system.Id)
|
|
|
|
throw Errors.NotOwnGroupError;
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var members = new List<MemberId>();
|
|
|
|
|
|
|
|
foreach (var JmemberRef in memberRefs)
|
|
|
|
{
|
|
|
|
var memberRef = JmemberRef.Value<string>();
|
2022-04-07 07:48:32 +00:00
|
|
|
var member = await ResolveMember(memberRef, cache: true);
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
if (member == null)
|
|
|
|
throw Errors.MemberNotFoundWithRef(memberRef);
|
|
|
|
if (member.System != system.Id)
|
|
|
|
throw Errors.NotOwnMemberErrorWithRef(memberRef);
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
members.Add(member.Id);
|
2021-10-02 01:50:01 +00:00
|
|
|
}
|
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
await _repo.RemoveMembersFromGroup(group.Id, members);
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
return NoContent();
|
|
|
|
}
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpPost("groups/{groupRef}/members/overwrite")]
|
|
|
|
public async Task<IActionResult> OverwriteGroupMembers(string groupRef, [FromBody] JArray memberRefs)
|
|
|
|
{
|
|
|
|
var system = await ResolveSystem("@me");
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var group = await ResolveGroup(groupRef);
|
|
|
|
if (group == null)
|
|
|
|
throw Errors.GroupNotFound;
|
|
|
|
if (group.System != system.Id)
|
|
|
|
throw Errors.NotOwnGroupError;
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var members = new List<MemberId>();
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
foreach (var JmemberRef in memberRefs)
|
|
|
|
{
|
|
|
|
var memberRef = JmemberRef.Value<string>();
|
2022-04-07 07:48:32 +00:00
|
|
|
var member = await ResolveMember(memberRef, cache: true);
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
if (member == null)
|
|
|
|
throw Errors.MemberNotFoundWithRef(memberRef);
|
|
|
|
if (member.System != system.Id)
|
|
|
|
throw Errors.NotOwnMemberErrorWithRef(memberRef);
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
members.Add(member.Id);
|
2021-10-02 01:50:01 +00:00
|
|
|
}
|
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
await _repo.ClearGroupMembers(group.Id);
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
if (members.Count > 0)
|
|
|
|
await _repo.AddMembersToGroup(group.Id, members);
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
return NoContent();
|
|
|
|
}
|
2021-10-30 22:16:18 +00:00
|
|
|
|
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpGet("members/{memberRef}/groups")]
|
|
|
|
public async Task<IActionResult> GetMemberGroups(string memberRef)
|
|
|
|
{
|
|
|
|
var member = await ResolveMember(memberRef);
|
|
|
|
var ctx = ContextFor(member);
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var system = await _repo.GetSystem(member.System);
|
|
|
|
if (!system.GroupListPrivacy.CanAccess(ctx))
|
|
|
|
throw Errors.UnauthorizedGroupList;
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var groups = _repo.GetMemberGroups(member.Id).Where(g => g.Visibility.CanAccess(ctx));
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var o = new JArray();
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
await foreach (var group in groups)
|
|
|
|
o.Add(group.ToJson(ctx));
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
return Ok(o);
|
|
|
|
}
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpPost("members/{memberRef}/groups/add")]
|
|
|
|
public async Task<IActionResult> AddMemberGroups(string memberRef, [FromBody] JArray groupRefs)
|
|
|
|
{
|
|
|
|
if (groupRefs.Count == 0)
|
|
|
|
throw Errors.GenericBadRequest;
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var system = await ResolveSystem("@me");
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var member = await ResolveMember(memberRef);
|
|
|
|
if (member == null)
|
|
|
|
throw Errors.MemberNotFound;
|
|
|
|
if (member.System != system.Id)
|
|
|
|
throw Errors.NotOwnMemberError;
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var groups = new List<GroupId>();
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
foreach (var JgroupRef in groupRefs)
|
|
|
|
{
|
|
|
|
var groupRef = JgroupRef.Value<string>();
|
2022-04-07 07:48:32 +00:00
|
|
|
var group = await ResolveGroup(groupRef, cache: true);
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
if (group == null)
|
|
|
|
throw Errors.GroupNotFound;
|
|
|
|
if (group.System != system.Id)
|
|
|
|
throw Errors.NotOwnGroupErrorWithRef(groupRef);
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
groups.Add(group.Id);
|
2021-10-02 01:50:01 +00:00
|
|
|
}
|
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var existingGroups = await _repo.GetMemberGroups(member.Id).Select(x => x.Id).ToListAsync();
|
|
|
|
groups = groups.Where(x => !existingGroups.Contains(x)).ToList();
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
if (groups.Count > 0)
|
|
|
|
await _repo.AddGroupsToMember(member.Id, groups);
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
return NoContent();
|
|
|
|
}
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpPost("members/{memberRef}/groups/remove")]
|
|
|
|
public async Task<IActionResult> RemoveMemberGroups(string memberRef, [FromBody] JArray groupRefs)
|
|
|
|
{
|
|
|
|
if (groupRefs.Count == 0)
|
|
|
|
throw Errors.GenericBadRequest;
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var system = await ResolveSystem("@me");
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var member = await ResolveMember(memberRef);
|
|
|
|
if (member == null)
|
|
|
|
throw Errors.MemberNotFound;
|
|
|
|
if (member.System != system.Id)
|
|
|
|
throw Errors.NotOwnMemberError;
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var groups = new List<GroupId>();
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
foreach (var JgroupRef in groupRefs)
|
|
|
|
{
|
|
|
|
var groupRef = JgroupRef.Value<string>();
|
2022-04-07 07:48:32 +00:00
|
|
|
var group = await ResolveGroup(groupRef, cache: true);
|
2021-10-12 12:33:31 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
if (group == null)
|
|
|
|
throw Errors.GroupNotFoundWithRef(groupRef);
|
|
|
|
if (group.System != system.Id)
|
|
|
|
throw Errors.NotOwnGroupErrorWithRef(groupRef);
|
2021-10-02 01:50:01 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
groups.Add(group.Id);
|
|
|
|
}
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
await _repo.RemoveGroupsFromMember(member.Id, groups);
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
return NoContent();
|
|
|
|
}
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
[HttpPost("members/{memberRef}/groups/overwrite")]
|
|
|
|
public async Task<IActionResult> OverwriteMemberGroups(string memberRef, [FromBody] JArray groupRefs)
|
|
|
|
{
|
|
|
|
var system = await ResolveSystem("@me");
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var member = await ResolveMember(memberRef);
|
|
|
|
if (member == null)
|
|
|
|
throw Errors.MemberNotFound;
|
|
|
|
if (member.System != system.Id)
|
|
|
|
throw Errors.NotOwnMemberError;
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
var groups = new List<GroupId>();
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
foreach (var JgroupRef in groupRefs)
|
|
|
|
{
|
|
|
|
var groupRef = JgroupRef.Value<string>();
|
2022-04-07 07:48:32 +00:00
|
|
|
var group = await ResolveGroup(groupRef, cache: true);
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
if (group == null)
|
|
|
|
throw Errors.GroupNotFoundWithRef(groupRef);
|
|
|
|
if (group.System != system.Id)
|
|
|
|
throw Errors.NotOwnGroupErrorWithRef(groupRef);
|
2021-10-30 22:16:18 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
groups.Add(group.Id);
|
2021-10-30 22:16:18 +00:00
|
|
|
}
|
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
await _repo.ClearMemberGroups(member.Id);
|
|
|
|
|
|
|
|
if (groups.Count > 0)
|
|
|
|
await _repo.AddGroupsToMember(member.Id, groups);
|
|
|
|
|
|
|
|
return NoContent();
|
2021-10-02 01:50:01 +00:00
|
|
|
}
|
|
|
|
}
|