Skip to content

Commit e8dc35c

Browse files
Fix permission checks
Show correct command names & permissions in RequireHomeserverPerm failure messages, properly honor OwnerOverride
1 parent 887b069 commit e8dc35c

File tree

2 files changed

+37
-23
lines changed

2 files changed

+37
-23
lines changed

Commands/GlobalCmds.cs

+28-21
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public async Task Help(CommandContext ctx, [Description("Command to provide help
3131

3232
Command? cmd = null;
3333
IEnumerable<Command>? searchIn = cmds;
34-
foreach (string c in commandSplit)
34+
for (int i = 0; i < commandSplit.Length; i++)
3535
{
3636
if (searchIn is null)
3737
{
@@ -41,35 +41,41 @@ public async Task Help(CommandContext ctx, [Description("Command to provide help
4141

4242
StringComparison comparison = StringComparison.InvariantCultureIgnoreCase;
4343
StringComparer comparer = StringComparer.InvariantCultureIgnoreCase;
44-
cmd = searchIn.FirstOrDefault(xc => xc.Name.Equals(c, comparison) || ((xc.Attributes.FirstOrDefault(x => x is TextAliasAttribute) as TextAliasAttribute)?.Aliases.Contains(c.Replace("textcmd", ""), comparer) ?? false));
44+
cmd = searchIn.FirstOrDefault(xc => xc.Name.Equals(commandSplit[i], comparison) || ((xc.Attributes.FirstOrDefault(x => x is TextAliasAttribute) as TextAliasAttribute)?.Aliases.Contains(commandSplit[i].Replace("textcmd", ""), comparer) ?? false));
4545

4646
if (cmd is null)
4747
{
4848
break;
4949
}
5050

51-
IEnumerable<ContextCheckAttribute> failedChecks = (await CheckPermissionsAsync(ctx, cmd)).ToList();
52-
if (failedChecks.Any())
51+
// Only run checks on the last command in the chain.
52+
// So if we are looking at a command group here, only run checks against the actual command,
53+
// not the group(s) it's under.
54+
if (i == commandSplit.Length - 1)
5355
{
54-
if (failedChecks.All(x => x is RequireHomeserverPermAttribute))
56+
IEnumerable<ContextCheckAttribute> failedChecks = (await CheckPermissionsAsync(ctx, cmd)).ToList();
57+
if (failedChecks.Any())
5558
{
56-
var att = failedChecks.FirstOrDefault(x => x is RequireHomeserverPermAttribute) as RequireHomeserverPermAttribute;
57-
if (att is not null)
59+
if (failedChecks.All(x => x is RequireHomeserverPermAttribute))
5860
{
59-
var level = (await GetPermLevelAsync(ctx.Member));
60-
var levelText = level.ToString();
61-
if (level == ServerPermLevel.Nothing && Program.rand.Next(1, 100) == 69)
62-
levelText = $"naught but a thing, my dear human. Congratulations, you win {Program.rand.Next(1, 10)} bonus points.";
61+
var att = failedChecks.FirstOrDefault(x => x is RequireHomeserverPermAttribute) as RequireHomeserverPermAttribute;
62+
if (att is not null)
63+
{
64+
var level = (await GetPermLevelAsync(ctx.Member));
65+
var levelText = level.ToString();
66+
if (level == ServerPermLevel.Nothing && Program.rand.Next(1, 100) == 69)
67+
levelText = $"naught but a thing, my dear human. Congratulations, you win {Program.rand.Next(1, 10)} bonus points.";
6368

64-
await ctx.RespondAsync(
65-
$"{Program.cfgjson.Emoji.NoPermissions} Invalid permissions to use command **{cmd.Name.Replace("textcmd", "")}**!\n" +
66-
$"Required: `{att.TargetLvl}`\nYou have: `{levelText}`");
69+
await ctx.RespondAsync(
70+
$"{Program.cfgjson.Emoji.NoPermissions} Invalid permissions to use command **{command.Replace("textcmd", "")}**!\n" +
71+
$"Required: `{att.TargetLvl}`\nYou have: `{levelText}`");
6772

68-
return;
73+
return;
74+
}
6975
}
70-
}
7176

72-
return;
77+
return;
78+
}
7379
}
7480

7581
searchIn = cmd.Subcommands.Any() ? cmd.Subcommands : null;
@@ -322,22 +328,23 @@ private async Task<IEnumerable<ContextCheckAttribute>> CheckPermissionsAsync(Com
322328

323329
if (check is RequireHomeserverPermAttribute requireHomeserverPermAttribute)
324330
{
331+
// Fail if guild member is null but this cmd does not work outside of the home server
325332
if (ctx.Member is null && !requireHomeserverPermAttribute.WorkOutside)
326333
{
327334
failedChecks.Add(requireHomeserverPermAttribute);
328335
}
329336
else
330337
{
331-
if (!requireHomeserverPermAttribute.WorkOutside)
338+
var level = await GetPermLevelAsync(ctx.Member);
339+
if (level < requireHomeserverPermAttribute.TargetLvl)
332340
{
333-
var level = await GetPermLevelAsync(ctx.Member);
334-
if (level < requireHomeserverPermAttribute.TargetLvl)
341+
if (requireHomeserverPermAttribute.OwnerOverride && !Program.cfgjson.BotOwners.Contains(ctx.User.Id)
342+
|| !requireHomeserverPermAttribute.OwnerOverride)
335343
{
336344
failedChecks.Add(requireHomeserverPermAttribute);
337345
}
338346
}
339347
}
340-
341348
}
342349

343350
if (check is RequirePermissionsAttribute requirePermissionsAttribute)

Events/ErrorEvents.cs

+9-2
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,16 @@ await e.Context.RespondAsync(
7171

7272
if (ex is ChecksFailedException cfex && (commandName != "help"))
7373
{
74-
foreach (var check in cfex.Errors)
74+
// Iterate over RequireHomeserverPermAttribute failures.
75+
// Only evaluate the last one, so that if we are looking at a command in a group (say, debug shutdown),
76+
// we only evaluate against permissions for the command (shutdown) instead of the group (debug) in case they differ.
77+
var permErrIndex = 1;
78+
foreach(var permErr in cfex.Errors.Where(x => x.ContextCheckAttribute is RequireHomeserverPermAttribute))
7579
{
76-
if (check.ContextCheckAttribute is RequireHomeserverPermAttribute att)
80+
// Only evaluate the last failed RequireHomeserverPermAttribute
81+
if (permErrIndex == cfex.Errors.Count(x => x.ContextCheckAttribute is RequireHomeserverPermAttribute))
7782
{
83+
var att = permErr.ContextCheckAttribute as RequireHomeserverPermAttribute;
7884
var level = (await GetPermLevelAsync(e.Context.Member));
7985
var levelText = level.ToString();
8086
if (level == ServerPermLevel.Nothing && Program.rand.Next(1, 100) == 69)
@@ -86,6 +92,7 @@ await e.Context.RespondAsync(
8692

8793
return;
8894
}
95+
permErrIndex++;
8996
}
9097
return;
9198
}

0 commit comments

Comments
 (0)