summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico <dico.karssiens@gmail.com>2018-09-26 09:58:37 +0100
committerDico <dico.karssiens@gmail.com>2018-09-26 09:58:37 +0100
commite7dcf7ecc9d448e3a07ef22843ef058d72dcb225 (patch)
tree6d6a081e8e39265a739094bb2eb013457ebf18e6
parent520ae530d2de076fa9e87da7f04fcf78e080f4de (diff)
Tweaks to command permissions
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/IContextFilter.java152
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/InheritingContextFilter.java64
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/PermissionContextFilter.java93
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java2
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt8
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt80
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt1
7 files changed, 222 insertions, 178 deletions
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/IContextFilter.java b/dicore3/command/src/main/java/io/dico/dicore/command/IContextFilter.java
index a60c34e..4a4c06d 100644
--- a/dicore3/command/src/main/java/io/dico/dicore/command/IContextFilter.java
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/IContextFilter.java
@@ -3,6 +3,7 @@ package io.dico.dicore.command;
import io.dico.dicore.exceptions.checkedfunctions.CheckedConsumer;
import io.dico.dicore.exceptions.checkedfunctions.CheckedRunnable;
import org.bukkit.command.CommandSender;
+import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Objects;
@@ -52,10 +53,11 @@ public interface IContextFilter extends Comparable<IContextFilter> {
* @return comparison value
*/
@Override
- default int compareTo(IContextFilter o) {
+ default int compareTo(@NotNull IContextFilter o) {
return getPriority().compareTo(o.getPriority());
}
+ /*
default boolean isInheritable() {
return false;
}
@@ -66,7 +68,7 @@ public interface IContextFilter extends Comparable<IContextFilter> {
}
return this;
- }
+ }*/
/**
* IContextFilter priorities. Executes from top to bottom.
@@ -110,6 +112,8 @@ public interface IContextFilter extends Comparable<IContextFilter> {
*/
POST_PARAMETERS;
+ private IContextFilter inheritor;
+
/**
* Get the context filter that inherits context filters from the parent of the same priority.
* If this filter is also present at the parent, it will do the same for the parent's parent, and so on.
@@ -117,56 +121,12 @@ public interface IContextFilter extends Comparable<IContextFilter> {
* @return the inheritor
*/
public IContextFilter getInheritor() {
+ if (inheritor == null) {
+ inheritor = InheritingContextFilter.inheritingPriority(this);
+ }
return inheritor;
}
- private static String[] addParent(String[] path, String parent) {
- String[] out = new String[path.length + 1];
- System.arraycopy(path, 0, out, 0, path.length);
- out[0] = parent;
- return out;
- }
-
- final IContextFilter inheritor = new IContextFilter() {
- @Override
- public void filterContext(ExecutionContext context) throws CommandException {
- ICommandAddress address = context.getAddress();
-
- String[] traversedPath = new String[0];
- do {
- traversedPath = addParent(traversedPath, address.getMainKey());
- address = address.getParent();
-
- if (address != null && address.hasCommand()) {
- boolean doBreak = true;
-
- Command command = address.getCommand();
- List<IContextFilter> contextFilterList = command.getContextFilters();
- for (IContextFilter filter : contextFilterList) {
- if (filter.getPriority() == Priority.this) {
- if (filter == this) {
- // do the same for next parent
- // this method is necessary to keep traversedPath information
- doBreak = false;
- } else {
- filter.filterSubContext(context, traversedPath);
- }
- }
- }
-
- if (doBreak) {
- break;
- }
- }
- } while (address != null);
- }
-
- @Override
- public Priority getPriority() {
- return Priority.this;
- }
- };
-
}
/**
@@ -215,14 +175,15 @@ public interface IContextFilter extends Comparable<IContextFilter> {
}
static IContextFilter permission(String permission) {
- Objects.requireNonNull(permission);
- return filterSender(Priority.PERMISSION, sender -> Validate.isAuthorized(sender, permission));
+ return new PermissionContextFilter(permission);
}
static IContextFilter permission(String permission, String failMessage) {
- Objects.requireNonNull(permission);
- Objects.requireNonNull(failMessage);
- return filterSender(Priority.PERMISSION, sender -> Validate.isAuthorized(sender, permission, failMessage));
+ return new PermissionContextFilter(permission, failMessage);
+ }
+
+ static IContextFilter inheritablePermission(String permission) {
+ return new PermissionContextFilter(permission, true);
}
/**
@@ -236,87 +197,8 @@ public interface IContextFilter extends Comparable<IContextFilter> {
* @throws IllegalArgumentException if componentInsertionIndex is out of range
*/
static IContextFilter inheritablePermission(String permission, int componentInsertionIndex, String failMessage) {
- Objects.requireNonNull(permission);
- Objects.requireNonNull(failMessage);
- if (componentInsertionIndex > permission.split("\\.").length || componentInsertionIndex < -1) {
- throw new IllegalArgumentException("componentInsertionIndex out of range");
- }
-
-
- return new IContextFilter() {
- private String getInheritedPermission(String[] components) {
- int insertedAmount = components.length;
- String[] currentComponents = permission.split("\\.");
- int currentAmount = currentComponents.length;
- String[] targetArray = new String[currentAmount + insertedAmount];
-
- int insertionIndex;
- //int newInsertionIndex;
- if (componentInsertionIndex == -1) {
- insertionIndex = currentAmount;
- //newInsertionIndex = -1;
- } else {
- insertionIndex = componentInsertionIndex;
- //newInsertionIndex = insertionIndex + insertedAmount;
- }
-
- // copy the current components up to insertionIndex
- System.arraycopy(currentComponents, 0, targetArray, 0, insertionIndex);
- // copy the new components into the array at insertionIndex
- System.arraycopy(components, 0, targetArray, insertionIndex, insertedAmount);
- // copy the current components from insertionIndex + inserted amount
- System.arraycopy(currentComponents, insertionIndex, targetArray, insertionIndex + insertedAmount, currentAmount - insertionIndex);
-
- return String.join(".", targetArray);
- }
-
- @Override
- public void filterContext(ExecutionContext context) throws CommandException {
- Validate.isAuthorized(context.getSender(), permission, failMessage);
- }
-
- @Override
- public void filterSubContext(ExecutionContext subContext, String... path) throws CommandException {
- Validate.isAuthorized(subContext.getSender(), getInheritedPermission(path), failMessage);
- }
-
- @Override
- public Priority getPriority() {
- return Priority.PERMISSION;
- }
-
- @Override
- public boolean isInheritable() {
- return true;
- }
-
- @Override
- public IContextFilter inherit(String... components) {
- int insertedAmount = components.length;
- String[] currentComponents = permission.split("\\.");
- int currentAmount = currentComponents.length;
- String[] targetArray = new String[currentAmount + insertedAmount];
-
- int insertionIndex;
- int newInsertionIndex;
- if (componentInsertionIndex == -1) {
- insertionIndex = currentAmount;
- newInsertionIndex = -1;
- } else {
- insertionIndex = componentInsertionIndex;
- newInsertionIndex = insertionIndex + insertedAmount;
- }
-
- // copy the current components up to insertionIndex
- System.arraycopy(currentComponents, 0, targetArray, 0, insertionIndex);
- // copy the new components into the array at insertionIndex
- System.arraycopy(components, 0, targetArray, insertionIndex, insertedAmount);
- // copy the current components from insertionIndex + inserted amount
- System.arraycopy(currentComponents, insertionIndex, targetArray, insertionIndex + insertedAmount, currentAmount - insertionIndex);
-
- return inheritablePermission(String.join(".", targetArray), newInsertionIndex, failMessage);
- }
- };
+ return new PermissionContextFilter(permission, componentInsertionIndex, failMessage);
}
}
+
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/InheritingContextFilter.java b/dicore3/command/src/main/java/io/dico/dicore/command/InheritingContextFilter.java
new file mode 100644
index 0000000..2f06ea7
--- /dev/null
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/InheritingContextFilter.java
@@ -0,0 +1,64 @@
+package io.dico.dicore.command;
+
+import java.util.List;
+
+public abstract class InheritingContextFilter implements IContextFilter {
+ private static final String[] emptyStringArray = new String[0];
+
+ private static String[] addParent(String[] path, String parent) {
+ String[] out = new String[path.length + 1];
+ System.arraycopy(path, 0, out, 0, path.length);
+ out[0] = parent;
+ return out;
+ }
+
+ protected abstract boolean isInherited(IContextFilter filter);
+
+ @Override
+ public void filterContext(ExecutionContext context) throws CommandException {
+ ICommandAddress address = context.getAddress();
+
+ String[] traversedPath = emptyStringArray;
+ do {
+ traversedPath = addParent(traversedPath, address.getMainKey());
+ address = address.getParent();
+
+ if (address != null && address.hasCommand()) {
+ boolean doBreak = true;
+
+ Command command = address.getCommand();
+ List<IContextFilter> contextFilterList = command.getContextFilters();
+ for (IContextFilter filter : contextFilterList) {
+ if (isInherited(filter)) {
+ if (filter == this) {
+ // do the same for next parent
+ // this method is necessary to keep traversedPath information
+ doBreak = false;
+ } else {
+ filter.filterSubContext(context, traversedPath);
+ }
+ }
+ }
+
+ if (doBreak) {
+ break;
+ }
+ }
+ } while (address != null);
+ }
+
+ static InheritingContextFilter inheritingPriority(Priority priority) {
+ return new InheritingContextFilter() {
+ @Override
+ protected boolean isInherited(IContextFilter filter) {
+ return filter.getPriority() == priority;
+ }
+
+ @Override
+ public Priority getPriority() {
+ return priority;
+ }
+ };
+ }
+
+}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/PermissionContextFilter.java b/dicore3/command/src/main/java/io/dico/dicore/command/PermissionContextFilter.java
new file mode 100644
index 0000000..6492677
--- /dev/null
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/PermissionContextFilter.java
@@ -0,0 +1,93 @@
+package io.dico.dicore.command;
+
+import java.util.Objects;
+
+public class PermissionContextFilter implements IContextFilter {
+ private String permission;
+ private String[] permissionComponents;
+ private int componentInsertionIndex;
+ private String failMessage;
+
+ public PermissionContextFilter(String permission) {
+ this.permission = Objects.requireNonNull(permission);
+ }
+
+ public PermissionContextFilter(String permission, String failMessage) {
+ this(permission);
+ this.failMessage = failMessage;
+ }
+
+ public PermissionContextFilter(String permission, boolean inheritable) {
+ this(permission, null, inheritable);
+ }
+
+ public PermissionContextFilter(String permission, String failMessage, boolean inheritable) {
+ this(permission, failMessage);
+ if (inheritable) {
+ setupInheritability(-1);
+ }
+ }
+
+ public PermissionContextFilter(String permission, int componentInsertionIndex, String failMessage) {
+ this(permission, failMessage);
+ setupInheritability(componentInsertionIndex);
+ }
+
+ private void setupInheritability(int componentInsertionIndex) {
+ this.permissionComponents = permission.split("\\.");
+ this.componentInsertionIndex = componentInsertionIndex < 0 ? permissionComponents.length : componentInsertionIndex;
+ if (componentInsertionIndex > permissionComponents.length) throw new IllegalArgumentException();
+ }
+
+ private void doFilter(ExecutionContext context, String permission) throws CommandException {
+ if (failMessage != null) {
+ Validate.isAuthorized(context.getSender(), permission, failMessage);
+ } else {
+ Validate.isAuthorized(context.getSender(), permission);
+ }
+ }
+
+ @Override
+ public void filterContext(ExecutionContext context) throws CommandException {
+ doFilter(context, permission);
+ }
+
+ private String getInheritedPermission(String[] components) {
+ int insertedAmount = components.length;
+ String[] currentComponents = permissionComponents;
+ int currentAmount = currentComponents.length;
+ String[] targetArray = new String[currentAmount + insertedAmount];
+
+ int insertionIndex;
+ //int newInsertionIndex;
+ if (componentInsertionIndex == -1) {
+ insertionIndex = currentAmount;
+ //newInsertionIndex = -1;
+ } else {
+ insertionIndex = componentInsertionIndex;
+ //newInsertionIndex = insertionIndex + insertedAmount;
+ }
+
+ // copy the current components up to insertionIndex
+ System.arraycopy(currentComponents, 0, targetArray, 0, insertionIndex);
+ // copy the new components into the array at insertionIndex
+ System.arraycopy(components, 0, targetArray, insertionIndex, insertedAmount);
+ // copy the current components from insertionIndex + inserted amount
+ System.arraycopy(currentComponents, insertionIndex, targetArray, insertionIndex + insertedAmount, currentAmount - insertionIndex);
+
+ return String.join(".", targetArray);
+ }
+
+ @Override
+ public void filterSubContext(ExecutionContext subContext, String... path) throws CommandException {
+ if (permissionComponents != null) {
+ doFilter(subContext, getInheritedPermission(path));
+ }
+ }
+
+ @Override
+ public Priority getPriority() {
+ return Priority.PERMISSION;
+ }
+
+}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java
index 0c64533..1279c2b 100644
--- a/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java
@@ -350,7 +350,7 @@ public class ReflectiveRegistration {
try {
//noinspection unchecked
- String flagPermission = flag == null ? null : flag.permission();
+ String flagPermission = flag == null || flag.permission().isEmpty() ? null : flag.permission();
return new Parameter<>(name, descString, parameterType, parameterInfo, type.isPrimitive(), name.startsWith("-"), flagPermission);
} catch (Exception ex) {
throw new CommandParseException("Invalid parameter", ex);
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt
index b6c7acd..60518af 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt
@@ -13,6 +13,7 @@ import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.block.BlockFace
import org.bukkit.block.data.Directional
+import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import java.util.Random
@@ -86,7 +87,12 @@ class CommandsDebug(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
fun cmdForceVisitors(): Any? {
val workers = plugin.workDispatcher.workers
plugin.workDispatcher.completeAllTasks()
- return "Task count: ${workers.size}"
+ return "Completed task count: ${workers.size}"
+ }
+
+ @Cmd("hasperm")
+ fun cmdHasperm(sender: CommandSender, target: Player, permission: String): Any? {
+ return target.hasPermission(permission).toString()
}
} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
index 1f1e4a7..7be112d 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
@@ -9,54 +9,52 @@ import java.util.LinkedList
import java.util.Queue
@Suppress("UsePropertyAccessSyntax")
-fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher =
- with(CommandBuilder()) {
- val parcelsAddress = SpecialCommandAddress()
-
- setChatController(ParcelsChatController())
- addParameterType(false, ParcelParameterType(plugin.parcelProvider))
- addParameterType(false, ProfileParameterType())
- addParameterType(true, ParcelTarget.PType(plugin.parcelProvider, parcelsAddress))
-
- group(parcelsAddress, "parcel", "plot", "plots", "p") {
- addRequiredPermission("parcels.command")
- registerCommands(CommandsGeneral(plugin, parcelsAddress))
- registerCommands(CommandsPrivilegesLocal(plugin))
-
- group("option", "opt", "o") {
- setGroupDescription(
- "changes interaction options for this parcel",
- "Sets whether players who are not allowed to",
- "build here can interact with certain things."
- )
-
- group("interact", "i") {
- val command = ParcelOptionsInteractCommand(plugin.parcelProvider)
- Interactables.classesById.forEach {
- addSubCommand(it.name, command)
- }
+fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher = CommandBuilder().apply {
+ val parcelsAddress = SpecialCommandAddress()
+
+ setChatController(ParcelsChatController())
+ addParameterType(false, ParcelParameterType(plugin.parcelProvider))
+ addParameterType(false, ProfileParameterType())
+ addParameterType(true, ParcelTarget.PType(plugin.parcelProvider, parcelsAddress))
+
+ group(parcelsAddress, "parcel", "plot", "plots", "p") {
+ addContextFilter(IContextFilter.inheritablePermission("parcels.command"))
+ registerCommands(CommandsGeneral(plugin, parcelsAddress))
+ registerCommands(CommandsPrivilegesLocal(plugin))
+
+ group("option", "opt", "o") {
+ setGroupDescription(
+ "changes interaction options for this parcel",
+ "Sets whether players who are not allowed to",
+ "build here can interact with certain things."
+ )
+
+ group("interact", "i") {
+ val command = ParcelOptionsInteractCommand(plugin.parcelProvider)
+ Interactables.classesById.forEach {
+ addSubCommand(it.name, command)
}
}
+ }
- group("global", "g") {
- registerCommands(CommandsPrivilegesGlobal(plugin))
- }
+ group("global", "g") {
+ registerCommands(CommandsPrivilegesGlobal(plugin))
+ }
- group("admin", "a") {
- registerCommands(CommandsAdmin(plugin))
- }
+ group("admin", "a") {
+ registerCommands(CommandsAdmin(plugin))
+ }
- if (!logger.isDebugEnabled) return@group
+ if (!logger.isDebugEnabled) return@group
- group("debug", "d") {
- registerCommands(CommandsDebug(plugin))
- }
+ group("debug", "d") {
+ registerCommands(CommandsDebug(plugin))
}
-
- generateHelpAndSyntaxCommands()
- getDispatcher()
}
+ generateHelpAndSyntaxCommands(parcelsAddress)
+}.getDispatcher()
+
inline fun CommandBuilder.group(name: String, vararg aliases: String, config: CommandBuilder.() -> Unit) {
group(name, *aliases)
config()
@@ -69,8 +67,8 @@ inline fun CommandBuilder.group(address: ICommandAddress, name: String, vararg a
parent()
}
-private fun CommandBuilder.generateHelpAndSyntaxCommands(): CommandBuilder {
- generateCommands(dispatcher as ICommandAddress, "help", "syntax")
+private fun CommandBuilder.generateHelpAndSyntaxCommands(root: ICommandAddress): CommandBuilder {
+ generateCommands(root, "help", "syntax")
return this
}
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt
index 2923173..8ba2d93 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt
@@ -15,6 +15,7 @@ class ParcelOptionsInteractCommand(val parcelProvider: ParcelProvider) : Command
init {
addContextFilter(IContextFilter.PLAYER_ONLY)
+ addContextFilter(IContextFilter.INHERIT_PERMISSIONS)
addParameter("allowed", "allowed", ParameterTypes.BOOLEAN)
}