diff --git a/PluralKit.Bot/CommandSystem/Context/Context.cs b/PluralKit.Bot/CommandSystem/Context/Context.cs index d0c7bd7a..52bd586e 100644 --- a/PluralKit.Bot/CommandSystem/Context/Context.cs +++ b/PluralKit.Bot/CommandSystem/Context/Context.cs @@ -133,14 +133,29 @@ public class Context await Reply($"{Emojis.Warn} This command is deprecated and will be removed soon. In the future, please use `pk;{commandDef.Key}`."); } - public LookupContext LookupContextFor(PKSystem target) => - System?.Id == target.Id ? LookupContext.ByOwner : LookupContext.ByNonOwner; + public LookupContext LookupContextFor(SystemId systemId) + { + var hasPrivateOverride = this.MatchFlag("private", "priv"); + var hasPublicOverride = this.MatchFlag("public", "pub"); - public LookupContext LookupContextFor(SystemId systemId) => - System?.Id == systemId ? LookupContext.ByOwner : LookupContext.ByNonOwner; + if (hasPrivateOverride && hasPublicOverride) + throw new PKError("Cannot match both public and private flags at the same time."); - public LookupContext LookupContextFor(PKMember target) => - System?.Id == target.System ? LookupContext.ByOwner : LookupContext.ByNonOwner; + if (System.Id != systemId) + { + if (hasPrivateOverride) + throw Errors.NotOwnInfo; + return LookupContext.ByNonOwner; + } + + if (hasPrivateOverride) + return LookupContext.ByOwner; + if (hasPublicOverride) + return LookupContext.ByNonOwner; + + // todo: add config defaults + return LookupContext.ByOwner; + } public IComponentContext Services => _provider; } \ No newline at end of file diff --git a/PluralKit.Bot/CommandSystem/Context/ContextChecksExt.cs b/PluralKit.Bot/CommandSystem/Context/ContextChecksExt.cs index e280d340..64fa8194 100644 --- a/PluralKit.Bot/CommandSystem/Context/ContextChecksExt.cs +++ b/PluralKit.Bot/CommandSystem/Context/ContextChecksExt.cs @@ -23,7 +23,7 @@ public static class ContextChecksExt public static Context CheckSystemPrivacy(this Context ctx, PKSystem target, PrivacyLevel level) { - if (level.CanAccess(ctx.LookupContextFor(target))) return ctx; + if (level.CanAccess(ctx.LookupContextFor(target.Id))) return ctx; throw new PKError("You do not have permission to access this information."); } diff --git a/PluralKit.Bot/CommandSystem/Context/ContextPrivacyExt.cs b/PluralKit.Bot/CommandSystem/Context/ContextPrivacyExt.cs index fe55503f..f8fc53d3 100644 --- a/PluralKit.Bot/CommandSystem/Context/ContextPrivacyExt.cs +++ b/PluralKit.Bot/CommandSystem/Context/ContextPrivacyExt.cs @@ -48,13 +48,4 @@ public static class ContextPrivacyExt ctx.PopArgument(); return subject; } - - public static bool MatchPrivateFlag(this Context ctx, LookupContext pctx) - { - var privacy = true; - if (ctx.MatchFlag("a", "all")) privacy = false; - if (pctx == LookupContext.ByNonOwner && !privacy) throw Errors.LookupNotAllowed; - - return privacy; - } } \ No newline at end of file diff --git a/PluralKit.Bot/Commands/Groups.cs b/PluralKit.Bot/Commands/Groups.cs index 3183a81c..fbb250d5 100644 --- a/PluralKit.Bot/Commands/Groups.cs +++ b/PluralKit.Bot/Commands/Groups.cs @@ -599,7 +599,7 @@ public class Groups var frontpercent = await _db.Execute(c => _repo.GetFrontBreakdown(c, targetSystem.Id, target.Id, rangeStart.Value.ToInstant(), now)); await ctx.Reply(embed: await _embeds.CreateFrontPercentEmbed(frontpercent, targetSystem, target, - ctx.Zone, ctx.LookupContextFor(targetSystem), title.ToString(), ignoreNoFronters, showFlat)); + ctx.Zone, ctx.LookupContextFor(targetSystem.Id), title.ToString(), ignoreNoFronters, showFlat)); } private async Task GetGroupSystem(Context ctx, PKGroup target) diff --git a/PluralKit.Bot/Commands/Lists/ContextListExt.cs b/PluralKit.Bot/Commands/Lists/ContextListExt.cs index 2403aa38..77cfbbeb 100644 --- a/PluralKit.Bot/Commands/Lists/ContextListExt.cs +++ b/PluralKit.Bot/Commands/Lists/ContextListExt.cs @@ -60,7 +60,7 @@ public static class ContextListExt // PERM CHECK: If we're trying to access non-public members of another system, error if (p.PrivacyFilter != PrivacyLevel.Public && lookupCtx != LookupContext.ByOwner) // TODO: should this just return null instead of throwing or something? >.> - throw new PKError("You cannot look up private members of another system."); + throw Errors.NotOwnInfo; // Additional fields to include in the search results if (ctx.MatchFlag("with-last-switch", "with-last-fronted", "with-last-front", "wls", "wlf")) diff --git a/PluralKit.Bot/Commands/Member.cs b/PluralKit.Bot/Commands/Member.cs index 98a678a7..883deb76 100644 --- a/PluralKit.Bot/Commands/Member.cs +++ b/PluralKit.Bot/Commands/Member.cs @@ -120,14 +120,14 @@ public class Member { var system = await _repo.GetSystem(target.System); await ctx.Reply( - embed: await _embeds.CreateMemberEmbed(system, target, ctx.Guild, ctx.LookupContextFor(system), ctx.Zone)); + embed: await _embeds.CreateMemberEmbed(system, target, ctx.Guild, ctx.LookupContextFor(system.Id), ctx.Zone)); } public async Task Soulscream(Context ctx, PKMember target) { // this is for a meme, please don't take this code seriously. :) - var name = target.NameFor(ctx.LookupContextFor(target)); + var name = target.NameFor(ctx.LookupContextFor(target.System)); var encoded = HttpUtility.UrlEncode(name); var resp = await _client.GetAsync($"https://onomancer.sibr.dev/api/generateStats2?name={encoded}"); diff --git a/PluralKit.Bot/Commands/MemberAvatar.cs b/PluralKit.Bot/Commands/MemberAvatar.cs index 496f2bf9..53460080 100644 --- a/PluralKit.Bot/Commands/MemberAvatar.cs +++ b/PluralKit.Bot/Commands/MemberAvatar.cs @@ -43,7 +43,7 @@ public class MemberAvatar { var currentValue = location == AvatarLocation.Member ? target.AvatarUrl : guildData?.AvatarUrl; var canAccess = location != AvatarLocation.Member || - target.AvatarPrivacy.CanAccess(ctx.LookupContextFor(target)); + target.AvatarPrivacy.CanAccess(ctx.LookupContextFor(target.System)); if (string.IsNullOrEmpty(currentValue) || !canAccess) { if (location == AvatarLocation.Member) diff --git a/PluralKit.Bot/Commands/MemberEdit.cs b/PluralKit.Bot/Commands/MemberEdit.cs index 65c27e9d..a3b0798b 100644 --- a/PluralKit.Bot/Commands/MemberEdit.cs +++ b/PluralKit.Bot/Commands/MemberEdit.cs @@ -329,7 +329,7 @@ public class MemberEdit private async Task CreateMemberNameInfoEmbed(Context ctx, PKMember target) { - var lcx = ctx.LookupContextFor(target); + var lcx = ctx.LookupContextFor(target.System); MemberGuildSettings memberGuildConfig = null; if (ctx.Guild != null) diff --git a/PluralKit.Bot/Commands/Random.cs b/PluralKit.Bot/Commands/Random.cs index 4ded2da8..fd8b4c68 100644 --- a/PluralKit.Bot/Commands/Random.cs +++ b/PluralKit.Bot/Commands/Random.cs @@ -34,7 +34,7 @@ public class Random var randInt = randGen.Next(members.Count); await ctx.Reply(embed: await _embeds.CreateMemberEmbed(ctx.System, members[randInt], ctx.Guild, - ctx.LookupContextFor(ctx.System), ctx.Zone)); + ctx.LookupContextFor(ctx.System.Id), ctx.Zone)); } public async Task Group(Context ctx) @@ -72,6 +72,6 @@ public class Random var randInt = randGen.Next(ms.Count); await ctx.Reply(embed: await _embeds.CreateMemberEmbed(ctx.System, ms[randInt], ctx.Guild, - ctx.LookupContextFor(ctx.System), ctx.Zone)); + ctx.LookupContextFor(ctx.System.Id), ctx.Zone)); } } \ No newline at end of file diff --git a/PluralKit.Bot/Commands/Switch.cs b/PluralKit.Bot/Commands/Switch.cs index b315d453..3c341466 100644 --- a/PluralKit.Bot/Commands/Switch.cs +++ b/PluralKit.Bot/Commands/Switch.cs @@ -50,7 +50,7 @@ public class Switch // Make sure the requested switch isn't identical to the last one if (await lastSwitchMembers.Select(m => m.Id) .SequenceEqualAsync(members.Select(m => m.Id).ToAsyncEnumerable())) - throw Errors.SameSwitch(members, ctx.LookupContextFor(ctx.System)); + throw Errors.SameSwitch(members, ctx.LookupContextFor(ctx.System.Id)); } await _repo.AddSwitch(conn, ctx.System.Id, members.Select(m => m.Id).ToList()); @@ -138,7 +138,7 @@ public class Switch // Make sure switch isn't being edited to have the members it already does if (await lastSwitchMembers.Select(m => m.Id) .SequenceEqualAsync(members.Select(m => m.Id).ToAsyncEnumerable())) - throw Errors.SameSwitch(members, ctx.LookupContextFor(ctx.System)); + throw Errors.SameSwitch(members, ctx.LookupContextFor(ctx.System.Id)); // Send a prompt asking the user to confirm the switch var lastSwitchDeltaStr = (SystemClock.Instance.GetCurrentInstant() - lastSwitch.Timestamp).FormatDuration(); diff --git a/PluralKit.Bot/Commands/System.cs b/PluralKit.Bot/Commands/System.cs index f25d7757..703c1654 100644 --- a/PluralKit.Bot/Commands/System.cs +++ b/PluralKit.Bot/Commands/System.cs @@ -17,7 +17,7 @@ public class System { if (system == null) throw Errors.NoSystemError; - await ctx.Reply(embed: await _embeds.CreateSystemEmbed(ctx, system, ctx.LookupContextFor(system))); + await ctx.Reply(embed: await _embeds.CreateSystemEmbed(ctx, system, ctx.LookupContextFor(system.Id))); } public async Task New(Context ctx) diff --git a/PluralKit.Bot/Commands/SystemFront.cs b/PluralKit.Bot/Commands/SystemFront.cs index fd86a2ea..32291f35 100644 --- a/PluralKit.Bot/Commands/SystemFront.cs +++ b/PluralKit.Bot/Commands/SystemFront.cs @@ -27,7 +27,7 @@ public class SystemFront var sw = await _repo.GetLatestSwitch(system.Id); if (sw == null) throw Errors.NoRegisteredSwitches; - await ctx.Reply(embed: await _embeds.CreateFronterEmbed(sw, ctx.Zone, ctx.LookupContextFor(system))); + await ctx.Reply(embed: await _embeds.CreateFronterEmbed(sw, ctx.Zone, ctx.LookupContextFor(system.Id))); } public async Task SystemFrontHistory(Context ctx, PKSystem system) @@ -128,7 +128,7 @@ public class SystemFront var frontpercent = await _db.Execute(c => _repo.GetFrontBreakdown(c, system.Id, null, rangeStart.Value.ToInstant(), now)); await ctx.Reply(embed: await _embeds.CreateFrontPercentEmbed(frontpercent, system, null, ctx.Zone, - ctx.LookupContextFor(system), title.ToString(), ignoreNoFronters, showFlat)); + ctx.LookupContextFor(system.Id), title.ToString(), ignoreNoFronters, showFlat)); } private struct FrontHistoryEntry diff --git a/PluralKit.Bot/Commands/SystemList.cs b/PluralKit.Bot/Commands/SystemList.cs index b1fbb172..d6157031 100644 --- a/PluralKit.Bot/Commands/SystemList.cs +++ b/PluralKit.Bot/Commands/SystemList.cs @@ -11,9 +11,9 @@ public class SystemList if (target == null) throw Errors.NoSystemError; ctx.CheckSystemPrivacy(target, target.MemberListPrivacy); - var opts = ctx.ParseMemberListOptions(ctx.LookupContextFor(target)); + var opts = ctx.ParseMemberListOptions(ctx.LookupContextFor(target.Id)); await ctx.RenderMemberList( - ctx.LookupContextFor(target), + ctx.LookupContextFor(target.Id), target.Id, GetEmbedTitle(target, opts), target.Color, diff --git a/PluralKit.Bot/Errors.cs b/PluralKit.Bot/Errors.cs index b15b30d0..cec1208b 100644 --- a/PluralKit.Bot/Errors.cs +++ b/PluralKit.Bot/Errors.cs @@ -34,6 +34,8 @@ public static class Errors public static PKError NotOwnMemberError => new("You can only run this command on your own member."); public static PKError NotOwnGroupError => new("You can only run this command on your own group."); + public static PKError NotOwnInfo => new("You cannot look up private information of another system."); + public static PKError NoSystemError => new("You do not have a system registered with PluralKit. To create one, type `pk;system new`."); diff --git a/PluralKit.Bot/Services/EmbedService.cs b/PluralKit.Bot/Services/EmbedService.cs index 36154b14..46756d94 100644 --- a/PluralKit.Bot/Services/EmbedService.cs +++ b/PluralKit.Bot/Services/EmbedService.cs @@ -45,9 +45,7 @@ public class EmbedService var accounts = await _repo.GetSystemAccounts(system.Id); var users = (await GetUsers(accounts)).Select(x => x.User?.NameAndMention() ?? $"(deleted account {x.Id})"); - var memberCount = cctx.MatchPrivateFlag(ctx) - ? await _repo.GetSystemMemberCount(system.Id, PrivacyLevel.Public) - : await _repo.GetSystemMemberCount(system.Id); + var memberCount = await _repo.GetSystemMemberCount(system.Id, ctx == LookupContext.ByOwner ? null : PrivacyLevel.Public); uint color; try @@ -225,10 +223,8 @@ public class EmbedService public async Task CreateGroupEmbed(Context ctx, PKSystem system, PKGroup target) { - var pctx = ctx.LookupContextFor(system); - var memberCount = ctx.MatchPrivateFlag(pctx) - ? await _repo.GetGroupMemberCount(target.Id, PrivacyLevel.Public) - : await _repo.GetGroupMemberCount(target.Id); + var pctx = ctx.LookupContextFor(system.Id); + var memberCount = await _repo.GetSystemMemberCount(system.Id, pctx == LookupContext.ByOwner ? null : PrivacyLevel.Public); var nameField = target.Name; if (system.Name != null) diff --git a/PluralKit.Bot/Utils/ModelUtils.cs b/PluralKit.Bot/Utils/ModelUtils.cs index 4c3102a8..dae85ac9 100644 --- a/PluralKit.Bot/Utils/ModelUtils.cs +++ b/PluralKit.Bot/Utils/ModelUtils.cs @@ -7,10 +7,10 @@ namespace PluralKit.Bot; public static class ModelUtils { public static string NameFor(this PKMember member, Context ctx) => - member.NameFor(ctx.LookupContextFor(member)); + member.NameFor(ctx.LookupContextFor(member.System)); public static string AvatarFor(this PKMember member, Context ctx) => - member.AvatarFor(ctx.LookupContextFor(member)).TryGetCleanCdnUrl(); + member.AvatarFor(ctx.LookupContextFor(member.System)).TryGetCleanCdnUrl(); public static string DisplayName(this PKMember member) => member.DisplayName ?? member.Name;