Skip to content

Commit b225229

Browse files
committed
Return syntax instead of no permission in some cases
1 parent 23de304 commit b225229

File tree

2 files changed

+75
-26
lines changed

2 files changed

+75
-26
lines changed

cloud-core/src/main/java/org/incendo/cloud/CommandTree.java

Lines changed: 71 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
225225
final PermissionResult permissionResult = this.determinePermissionResult(commandContext.sender(), root);
226226
if (permissionResult.denied()) {
227227
return CompletableFutures.failedFuture(
228-
new NoPermissionException(
229-
permissionResult,
230-
commandContext.sender(),
231-
this.getComponentChain(root)
232-
)
228+
this.noPermissionOrSyntax(permissionResult, commandContext.sender(), root)
233229
);
234230
}
235231

@@ -328,11 +324,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
328324
);
329325
if (check.denied()) {
330326
return CompletableFutures.failedFuture(
331-
new NoPermissionException(
332-
check,
333-
commandContext.sender(),
334-
this.getComponentChain(root)
335-
)
327+
this.noPermissionOrSyntax(check, commandContext.sender(), root)
336328
);
337329
}
338330
return CompletableFuture.completedFuture(root.command());
@@ -349,6 +341,72 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
349341
});
350342
}
351343

344+
@SuppressWarnings({"unchecked", "rawtypes"})
345+
private Exception noPermissionOrSyntax(
346+
final PermissionResult permissionResult,
347+
final C sender,
348+
final CommandNode<C> root
349+
) {
350+
final boolean convert = this.commandManager.settings().get(ManagerSetting.CONVERT_NO_PERMISSION_TO_SYNTAX_EXCEPTION);
351+
if (!convert) {
352+
return new NoPermissionException(
353+
permissionResult,
354+
sender,
355+
this.getComponentChain(root)
356+
);
357+
}
358+
359+
if (this.childPermitted(root, sender)) {
360+
return new InvalidSyntaxException(
361+
this.commandManager.commandSyntaxFormatter().apply(sender, (List) this.getComponentChain(root), root),
362+
sender, this.getComponentChain(root)
363+
);
364+
}
365+
366+
final @Nullable List<CommandNode<C>> parentChain = this.permittedParentChain(root, sender);
367+
if (parentChain != null) {
368+
return new InvalidSyntaxException(
369+
this.commandManager.commandSyntaxFormatter().apply(
370+
sender,
371+
parentChain.stream().map(CommandNode::component)
372+
.filter(Objects::nonNull).collect(Collectors.toList()),
373+
root
374+
),
375+
sender, this.getComponentChain(root)
376+
);
377+
}
378+
379+
return new NoPermissionException(
380+
permissionResult,
381+
sender,
382+
this.getComponentChain(root)
383+
);
384+
}
385+
386+
private boolean childPermitted(CommandNode<C> node, C sender) {
387+
if (this.determinePermissionResult(sender, node).allowed()) {
388+
return true;
389+
}
390+
for (final CommandNode<C> child : node.children()) {
391+
if (this.childPermitted(child, sender)) {
392+
return true;
393+
}
394+
}
395+
return false;
396+
}
397+
398+
private @Nullable List<CommandNode<C>> permittedParentChain(CommandNode<C> node, C sender) {
399+
final @Nullable CommandNode<C> parent = node.parent();
400+
if (parent != null) {
401+
if (this.determinePermissionResult(sender, parent).allowed()) {
402+
return this.getChain(parent);
403+
} else {
404+
return this.permittedParentChain(parent, sender);
405+
}
406+
}
407+
return null;
408+
}
409+
352410
private @Nullable CompletableFuture<@Nullable Command<C>> attemptParseUnambiguousChild(
353411
final @NonNull List<@NonNull CommandComponent<C>> parsedArguments,
354412
final @NonNull CommandContext<C> commandContext,
@@ -380,11 +438,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
380438
final PermissionResult childCheck = this.determinePermissionResult(sender, child);
381439
if (!commandInput.isEmpty() && childCheck.denied()) {
382440
return CompletableFutures.failedFuture(
383-
new NoPermissionException(
384-
childCheck,
385-
sender,
386-
this.getComponentChain(child)
387-
)
441+
this.noPermissionOrSyntax(childCheck, sender, child)
388442
);
389443
}
390444

@@ -447,11 +501,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
447501
return CompletableFuture.completedFuture(command);
448502
}
449503
return CompletableFutures.failedFuture(
450-
new NoPermissionException(
451-
check,
452-
sender,
453-
this.getComponentChain(root)
454-
)
504+
this.noPermissionOrSyntax(check, sender, root)
455505
);
456506
} else {
457507
// The child is not a leaf, but may have an intermediary executor, attempt to use it
@@ -476,11 +526,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
476526
}
477527

478528
return CompletableFutures.failedFuture(
479-
new NoPermissionException(
480-
check,
481-
sender,
482-
this.getComponentChain(root)
483-
)
529+
this.noPermissionOrSyntax(check, sender, root)
484530
);
485531
}
486532
}

cloud-core/src/main/java/org/incendo/cloud/setting/ManagerSetting.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,8 @@ public enum ManagerSetting implements Setting {
6161
* and code inspecting the command tree may need to be adjusted.
6262
*/
6363
@API(status = API.Status.EXPERIMENTAL)
64-
LIBERAL_FLAG_PARSING
64+
LIBERAL_FLAG_PARSING,
65+
66+
@API(status = API.Status.EXPERIMENTAL)
67+
CONVERT_NO_PERMISSION_TO_SYNTAX_EXCEPTION
6568
}

0 commit comments

Comments
 (0)