Skip to content

Commit

Permalink
Fix issue with permitted node after not-permitted node
Browse files Browse the repository at this point in the history
  • Loading branch information
jpenilla committed Feb 21, 2024
1 parent d25f256 commit 23de304
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@
@API(status = API.Status.STABLE)
public abstract class CommandManager<C> implements Stateful<RegistrationState>, CommandBuilderSource<C> {

private final Configurable<ManagerSetting> settings = Configurable.enumConfigurable(ManagerSetting.class)
.set(ManagerSetting.ENFORCE_INTERMEDIARY_PERMISSIONS, true);
private final Configurable<ManagerSetting> settings = Configurable.enumConfigurable(ManagerSetting.class);
private final ServicePipeline servicePipeline = ServicePipeline.builder().build();
private final ParserRegistry<C> parserRegistry = new StandardParserRegistry<>();
private final Collection<Command<C>> commands = new LinkedList<>();
Expand Down
34 changes: 16 additions & 18 deletions cloud-core/src/main/java/org/incendo/cloud/CommandTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,7 @@ public void verifyAndRegister() {
}
});

this.getLeavesRaw(this.internalTree).forEach(this::propagateRequirements);
this.getExecutorNodes(this.internalTree).forEach(this::propagateRequirements);
}

/**
Expand All @@ -1071,34 +1071,19 @@ private void propagateRequirements(final @NonNull CommandNode<C> leafNode) {
if (senderType == null) {
senderType = Object.class;
}
/* All leaves must necessarily have an owning command */
leafNode.nodeMeta().put(CommandNode.META_KEY_PERMISSION, commandPermission);
leafNode.nodeMeta().put(CommandNode.META_KEY_SENDER_TYPES, new HashSet<>(Collections.singletonList(senderType)));
// Get chain and order it tail->head then skip the tail (leaf node)
// Get chain and order it tail->head
List<CommandNode<C>> chain = this.getChain(leafNode);
Collections.reverse(chain);
chain = chain.subList(1, chain.size());
// Go through all nodes from the tail upwards until a collision occurs
for (final CommandNode<C> commandArgumentNode : chain) {
final Permission existingPermission = (Permission) commandArgumentNode.nodeMeta().get(CommandNode.META_KEY_PERMISSION);

Permission permission;
final Permission permission;
if (existingPermission != null) {
permission = Permission.anyOf(commandPermission, existingPermission);
} else {
permission = commandPermission;
}

/* Now also check if there's a command handler attached to an upper level node */
if (commandArgumentNode.component() != null && commandArgumentNode.command() != null) {
final Command<C> command = commandArgumentNode.command();
if (this.commandManager().settings().get(ManagerSetting.ENFORCE_INTERMEDIARY_PERMISSIONS)) {
permission = command.commandPermission();
} else {
permission = Permission.anyOf(permission, command.commandPermission());
}
}

commandArgumentNode.nodeMeta().put(CommandNode.META_KEY_PERMISSION, permission);

final Set<Type> senderTypes = (Set<Type>) commandArgumentNode.nodeMeta()
Expand Down Expand Up @@ -1190,6 +1175,19 @@ private void checkAmbiguity(final @NonNull CommandNode<C> node) throws Ambiguous
return leaves;
}

private @NonNull List<@NonNull CommandNode<C>> getExecutorNodes(
final @NonNull CommandNode<C> node
) {
final List<CommandNode<C>> leaves = new LinkedList<>();
if (node.command() != null) {
leaves.add(node);
}
for (final CommandNode<C> child : node.children()) {
leaves.addAll(this.getExecutorNodes(child));
}
return leaves;
}

/**
* Returns all leaf nodes attached to the given {@code node} or its children.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@
*/
@API(status = API.Status.STABLE)
public enum ManagerSetting implements Setting {
/**
* Do not create a compound permission and do not look greedily
* for child permission values, if a preceding command in the tree path
* has a command handler attached
*/
ENFORCE_INTERMEDIARY_PERMISSIONS,

/**
* Force sending of an empty suggestion (i.e. a singleton list containing an empty string)
* when no suggestions are present
Expand All @@ -52,14 +45,12 @@ public enum ManagerSetting implements Setting {
* For example, if a platform serializes the command tree and sends it to clients,
* this will allow modifying the command tree after it has been sent, as long as these modifications are not blocked by
* the underlying platform
*
*/
@API(status = API.Status.STABLE)
ALLOW_UNSAFE_REGISTRATION,

/**
* Enables overriding of existing commands on supported platforms.
*
*/
@API(status = API.Status.STABLE)
OVERRIDE_EXISTING_COMMANDS,
Expand All @@ -68,7 +59,6 @@ public enum ManagerSetting implements Setting {
* Allows parsing flags at any position after the last literal by appending flag argument nodes between each command node.
* It can have some conflicts when integrating with other command systems like Brigadier,
* and code inspecting the command tree may need to be adjusted.
*
*/
@API(status = API.Status.EXPERIMENTAL)
LIBERAL_FLAG_PARSING
Expand Down

0 comments on commit 23de304

Please sign in to comment.