diff --git a/PluralKit.API/Controllers/PKControllerBase.cs b/PluralKit.API/Controllers/PKControllerBase.cs index 10f18c16..a3cec128 100644 --- a/PluralKit.API/Controllers/PKControllerBase.cs +++ b/PluralKit.API/Controllers/PKControllerBase.cs @@ -12,6 +12,9 @@ public class PKControllerBase: ControllerBase private readonly Regex _shortIdRegex = new("^[a-z]{5}$"); private readonly Regex _snowflakeRegex = new("^[0-9]{17,19}$"); + private List? _memberLookupCache { get; set; } + private List? _groupLookupCache { get; set; } + protected readonly ApiConfig _config; protected readonly IDatabase _db; protected readonly ModelRepository _repo; @@ -47,26 +50,54 @@ public class PKControllerBase: ControllerBase return Task.FromResult(null); } - protected Task ResolveMember(string memberRef) + protected async Task ResolveMember(string memberRef, bool cache = false) { + if (cache) + { + if (_memberLookupCache == null) + { + HttpContext.Items.TryGetValue("SystemId", out var systemId); + if (systemId == null) + throw new Exception("Authenticated user must not be null to use lookup cache!"); + + _memberLookupCache = await _repo.GetSystemMembers((SystemId)systemId).ToListAsync(); + } + + return _memberLookupCache.FirstOrDefault(x => x.Hid == memberRef || x.Uuid.ToString() == memberRef); + } + if (Guid.TryParse(memberRef, out var guid)) - return _repo.GetMemberByGuid(guid); + return await _repo.GetMemberByGuid(guid); if (_shortIdRegex.IsMatch(memberRef)) - return _repo.GetMemberByHid(memberRef); + return await _repo.GetMemberByHid(memberRef); - return Task.FromResult(null); + return null; } - protected Task ResolveGroup(string groupRef) + protected async Task ResolveGroup(string groupRef, bool cache = true) { + if (cache) + { + if (_groupLookupCache == null) + { + HttpContext.Items.TryGetValue("SystemId", out var systemId); + if (systemId == null) + throw new Exception("Authenticated user must not be null to use lookup cache!"); + + _groupLookupCache = await _repo.GetSystemGroups((SystemId)systemId).ToListAsync(); + } + + return _groupLookupCache.FirstOrDefault(x => x.Hid == groupRef || x.Uuid.ToString() == groupRef); + } + if (Guid.TryParse(groupRef, out var guid)) - return _repo.GetGroupByGuid(guid); + return await _repo.GetGroupByGuid(guid); if (_shortIdRegex.IsMatch(groupRef)) - return _repo.GetGroupByHid(groupRef); + return await _repo.GetGroupByHid(groupRef); - return Task.FromResult(null); + return null; } protected LookupContext ContextFor(PKSystem system) diff --git a/PluralKit.API/Controllers/v2/GroupMemberControllerV2.cs b/PluralKit.API/Controllers/v2/GroupMemberControllerV2.cs index 4a31d147..99ba21f8 100644 --- a/PluralKit.API/Controllers/v2/GroupMemberControllerV2.cs +++ b/PluralKit.API/Controllers/v2/GroupMemberControllerV2.cs @@ -53,7 +53,7 @@ public class GroupMemberControllerV2: PKControllerBase foreach (var JmemberRef in memberRefs) { var memberRef = JmemberRef.Value(); - var member = await ResolveMember(memberRef); + var member = await ResolveMember(memberRef, cache: true); // todo: have a list of these errors instead of immediately throwing @@ -93,7 +93,7 @@ public class GroupMemberControllerV2: PKControllerBase foreach (var JmemberRef in memberRefs) { var memberRef = JmemberRef.Value(); - var member = await ResolveMember(memberRef); + var member = await ResolveMember(memberRef, cache: true); if (member == null) throw Errors.MemberNotFoundWithRef(memberRef); @@ -124,7 +124,7 @@ public class GroupMemberControllerV2: PKControllerBase foreach (var JmemberRef in memberRefs) { var memberRef = JmemberRef.Value(); - var member = await ResolveMember(memberRef); + var member = await ResolveMember(memberRef, cache: true); if (member == null) throw Errors.MemberNotFoundWithRef(memberRef); @@ -182,7 +182,7 @@ public class GroupMemberControllerV2: PKControllerBase foreach (var JgroupRef in groupRefs) { var groupRef = JgroupRef.Value(); - var group = await ResolveGroup(groupRef); + var group = await ResolveGroup(groupRef, cache: true); if (group == null) throw Errors.GroupNotFound; @@ -220,7 +220,7 @@ public class GroupMemberControllerV2: PKControllerBase foreach (var JgroupRef in groupRefs) { var groupRef = JgroupRef.Value(); - var group = await ResolveGroup(groupRef); + var group = await ResolveGroup(groupRef, cache: true); if (group == null) throw Errors.GroupNotFoundWithRef(groupRef); @@ -251,7 +251,7 @@ public class GroupMemberControllerV2: PKControllerBase foreach (var JgroupRef in groupRefs) { var groupRef = JgroupRef.Value(); - var group = await ResolveGroup(groupRef); + var group = await ResolveGroup(groupRef, cache: true); if (group == null) throw Errors.GroupNotFoundWithRef(groupRef);