Skip to content

Commit ab9bbbf

Browse files
committed
Return syntax instead of no permission in some cases
1 parent b9c37a4 commit ab9bbbf

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
@@ -226,11 +226,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
226226
final PermissionResult permissionResult = this.determinePermissionResult(commandContext.sender(), root);
227227
if (permissionResult.denied()) {
228228
return CompletableFutures.failedFuture(
229-
new NoPermissionException(
230-
permissionResult,
231-
commandContext.sender(),
232-
this.getComponentChain(root)
233-
)
229+
this.noPermissionOrSyntax(permissionResult, commandContext.sender(), root)
234230
);
235231
}
236232

@@ -329,11 +325,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
329325
);
330326
if (check.denied()) {
331327
return CompletableFutures.failedFuture(
332-
new NoPermissionException(
333-
check,
334-
commandContext.sender(),
335-
this.getComponentChain(root)
336-
)
328+
this.noPermissionOrSyntax(check, commandContext.sender(), root)
337329
);
338330
}
339331
return CompletableFuture.completedFuture(root.command());
@@ -350,6 +342,72 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
350342
});
351343
}
352344

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

@@ -448,11 +502,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
448502
return CompletableFuture.completedFuture(command);
449503
}
450504
return CompletableFutures.failedFuture(
451-
new NoPermissionException(
452-
check,
453-
sender,
454-
this.getComponentChain(root)
455-
)
505+
this.noPermissionOrSyntax(check, sender, root)
456506
);
457507
} else {
458508
// The child is not a leaf, but may have an intermediary executor, attempt to use it
@@ -477,11 +527,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
477527
}
478528

479529
return CompletableFutures.failedFuture(
480-
new NoPermissionException(
481-
check,
482-
sender,
483-
this.getComponentChain(root)
484-
)
530+
this.noPermissionOrSyntax(check, sender, root)
485531
);
486532
}
487533
}

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)