Skip to content

fix: check flag permissions before adding them to the sytnax formatter #765

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.apiguardian.api.API;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
Expand Down Expand Up @@ -76,7 +77,7 @@ public StandardCommandSyntaxFormatter(final @NonNull CommandManager<C> manager)
final @NonNull List<@NonNull CommandComponent<C>> commandComponents,
final @Nullable CommandNode<C> node
) {
return this.apply(commandComponents, node, n -> {
return this.apply(sender, commandComponents, node, n -> {
if (sender == null) {
return true;
}
Expand All @@ -95,7 +96,9 @@ public StandardCommandSyntaxFormatter(final @NonNull CommandManager<C> manager)
});
}

@SuppressWarnings("unchecked")
private @NonNull String apply(
final @Nullable C sender,
final @NonNull List<@NonNull CommandComponent<C>> commandComponents,
final @Nullable CommandNode<C> node,
final @NonNull Predicate<@NonNull CommandNode<C>> filter
Expand All @@ -110,7 +113,7 @@ public StandardCommandSyntaxFormatter(final @NonNull CommandManager<C> manager)
final AggregateParser<?, ?> aggregateParser = (AggregateParser<?, ?>) commandComponent.parser();
formattingInstance.appendAggregate(commandComponent, aggregateParser);
} else if (commandComponent.type() == CommandComponent.ComponentType.FLAG) {
formattingInstance.appendFlag((CommandFlagParser<?>) commandComponent.parser());
formattingInstance.appendFlag(this.filterFlagsByPermission(sender, (CommandFlagParser<C>) commandComponent.parser()));
} else {
if (commandComponent.required()) {
formattingInstance.appendRequired(commandComponent);
Expand Down Expand Up @@ -163,8 +166,12 @@ public StandardCommandSyntaxFormatter(final @NonNull CommandManager<C> manager)
formattingInstance.appendBlankSpace();
formattingInstance.appendAggregate(component, aggregateParser);
} else if (component.type() == CommandComponent.ComponentType.FLAG) {
formattingInstance.appendBlankSpace();
formattingInstance.appendFlag((CommandFlagParser<?>) component.parser());
final List<CommandFlag<?>> flags = this.filterFlagsByPermission(sender, (CommandFlagParser<C>) component.parser());

if (!flags.isEmpty()) {
formattingInstance.appendBlankSpace();
formattingInstance.appendFlag(flags);
}
} else if (component.type() == CommandComponent.ComponentType.LITERAL) {
formattingInstance.appendBlankSpace();
formattingInstance.appendLiteral(component);
Expand All @@ -190,6 +197,16 @@ public StandardCommandSyntaxFormatter(final @NonNull CommandManager<C> manager)
return new FormattingInstance();
}

private List<CommandFlag<?>> filterFlagsByPermission(
final @Nullable C sender,
final @NonNull CommandFlagParser<C> flagParser
) {
return flagParser
.flags()
.stream()
.filter(flag -> sender == null || this.manager.testPermission(sender, flag.permission()).allowed())
.collect(Collectors.toList());
}

/**
* Instance that is used when building command syntax
Expand Down Expand Up @@ -251,14 +268,12 @@ public void appendAggregate(
/**
* Appends a flag argument
*
* @param flagParser flag parser
* @param flags the flags to append
*/
public void appendFlag(final @NonNull CommandFlagParser<?> flagParser) {
public void appendFlag(final @NonNull Iterable<CommandFlag<?>> flags) {
this.builder.append(this.optionalPrefix());

final Iterator<CommandFlag<?>> flagIterator = flagParser
.flags()
.iterator();
final Iterator<CommandFlag<?>> flagIterator = flags.iterator();

while (flagIterator.hasNext()) {
final CommandFlag<?> flag = flagIterator.next();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.incendo.cloud.execution.ExecutionCoordinator;
import org.incendo.cloud.internal.CommandNode;
import org.incendo.cloud.internal.CommandRegistrationHandler;
import org.incendo.cloud.parser.flag.CommandFlag;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -106,6 +107,25 @@ void respectsPermissions() {
assertThat(formatted).isEqualTo(" all");
}

@Test
void respectsFlagPermissions() {
final Command.Builder<TestCommandSender> root = this.manager.commandBuilder("root");
this.manager.command(
root.flag(CommandFlag.builder("some_flag").withPermission("some_permission").build())
.handler(ctx -> {})
);

final CommandNode<TestCommandSender> rootNode = this.manager.commandTree().getNamedNode("root");

final String permittedFormatted = this.formatter.apply(
new TestCommandSender("some_permission"), Collections.emptyList(), rootNode);
assertThat(permittedFormatted).isEqualTo(" [--some_flag]");

final String formatted = this.formatter.apply(
new TestCommandSender(), Collections.emptyList(), rootNode);
assertThat(formatted).isEqualTo("");
}

static final class SpecificTestCommandSender extends TestCommandSender {

}
Expand Down
Loading