Add tests for disguise param options permissions

This commit is contained in:
libraryaddict 2022-02-17 20:44:17 +13:00
parent be3c1536a9
commit 145c1057c3
3 changed files with 120 additions and 91 deletions

View File

@ -333,61 +333,6 @@ public class DisguiseParser {
} }
} }
private static HashMap<String, HashMap<String, Boolean>> getDisguiseOptions(CommandSender sender, String permNode, DisguisePerm type) {
HashMap<String, HashMap<String, Boolean>> returns = new HashMap<>();
// libsdisguises.options.<command>.<disguise>.<method>.<options>
for (PermissionAttachmentInfo permission : sender.getEffectivePermissions()) {
String lowerPerm = permission.getPermission().toLowerCase(Locale.ENGLISH);
if (!lowerPerm.startsWith("libsdisguises.options.")) {
continue;
}
String[] split = lowerPerm.split("\\.");
// <command>.<disguise>.<method>.<options>
if (split.length < 4) {
continue;
}
if (!split[2].equalsIgnoreCase(permNode) && !split[2].equalsIgnoreCase("*")) {
continue;
}
boolean applicable = false;
for (String s : split[3].split("/")) {
if (!s.equals("*") && !s.replace("_", "").equalsIgnoreCase(type.toReadable().replace(" ", ""))) {
continue;
}
applicable = true;
break;
}
if (!applicable) {
continue;
}
HashMap<String, Boolean> options = new HashMap<>();
for (int i = 5; i < split.length; i++) {
options.put(split[i], permission.getValue());
}
for (String s : split[4].split("/")) {
if (returns.containsKey(s)) {
returns.get(s).putAll(options);
} else {
returns.put(s, options);
}
}
}
return returns;
}
public static DisguisePerm getDisguisePerm(String name) { public static DisguisePerm getDisguisePerm(String name) {
for (DisguisePerm perm : getDisguisePerms()) { for (DisguisePerm perm : getDisguisePerms()) {
if (!perm.toReadable().replaceAll("[ |_]", "").equalsIgnoreCase(name.replaceAll("[ |_]", ""))) { if (!perm.toReadable().replaceAll("[ |_]", "").equalsIgnoreCase(name.replaceAll("[ |_]", ""))) {
@ -440,32 +385,6 @@ public class DisguiseParser {
} }
} }
/**
* Returns true if the string is found in the map, or it's not a whitelisted setup
* <p>
* Returns if command user can access the disguise creation permission type
*/
private static boolean hasPermissionOption(HashMap<String, HashMap<String, Boolean>> disguiseOptions, String method, String value) {
method = method.toLowerCase(Locale.ENGLISH);
// If no permissions were defined, return true
if (!disguiseOptions.containsKey(method)) {
return true;
}
HashMap<String, Boolean> map = disguiseOptions.get(method);
value = value.toLowerCase(Locale.ENGLISH);
// If they were explictly defined, can just return the value
if (map.containsKey(value)) {
return map.get(value);
}
// If there is at least one whitelisted value, then they needed the whitelist to use it
return !map.containsValue(true);
}
public static String getName(CommandSender entity) { public static String getName(CommandSender entity) {
if (entity == null) { if (entity == null) {
return "??"; return "??";
@ -778,7 +697,7 @@ public class DisguiseParser {
throw new DisguiseParseException(LibsMsg.NO_PERM_DISGUISE); throw new DisguiseParseException(LibsMsg.NO_PERM_DISGUISE);
} }
HashMap<String, HashMap<String, Boolean>> disguiseOptions = getDisguiseOptions(sender, permNode, disguisePerm); HashMap<String, HashMap<String, Boolean>> disguiseOptions = DisguisePermissions.getDisguiseOptions(sender, permNode, disguisePerm);
if (disguise == null) { if (disguise == null) {
if (disguisePerm.isPlayer()) { if (disguisePerm.isPlayer()) {
@ -788,8 +707,9 @@ public class DisguiseParser {
throw new DisguiseParseException(LibsMsg.PARSE_SUPPLY_PLAYER); throw new DisguiseParseException(LibsMsg.PARSE_SUPPLY_PLAYER);
} else { } else {
// If they can't use this name, throw error // If they can't use this name, throw error
if (!hasPermissionOption(disguiseOptions, "setname", args[1].toLowerCase(Locale.ENGLISH))) { if (!DisguisePermissions.hasPermissionOption(disguiseOptions, "setname", args[1].toLowerCase(Locale.ENGLISH))) {
if (!args[1].equalsIgnoreCase(sender.getName()) || !hasPermissionOption(disguiseOptions, "setname", "themselves")) { if (!args[1].equalsIgnoreCase(sender.getName()) ||
!DisguisePermissions.hasPermissionOption(disguiseOptions, "setname", "themselves")) {
throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_NAME); throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_NAME);
} }
} }
@ -872,7 +792,7 @@ public class DisguiseParser {
doCheck(sender, permissions, disguisePerm, usedOptions); doCheck(sender, permissions, disguisePerm, usedOptions);
String itemName = itemStack == null ? "null" : itemStack.getType().name().toLowerCase(Locale.ENGLISH); String itemName = itemStack == null ? "null" : itemStack.getType().name().toLowerCase(Locale.ENGLISH);
if (!hasPermissionOption(disguiseOptions, optionName, itemName)) { if (!DisguisePermissions.hasPermissionOption(disguiseOptions, optionName, itemName)) {
throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_PARAM, itemName, disguisePerm.toReadable()); throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_PARAM, itemName, disguisePerm.toReadable());
} }
@ -898,7 +818,7 @@ public class DisguiseParser {
doCheck(sender, permissions, disguisePerm, usedOptions); doCheck(sender, permissions, disguisePerm, usedOptions);
if (!hasPermissionOption(disguiseOptions, optionName, miscId + "")) { if (!DisguisePermissions.hasPermissionOption(disguiseOptions, optionName, miscId + "")) {
throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_PARAM, miscId + "", disguisePerm.toReadable()); throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_PARAM, miscId + "", disguisePerm.toReadable());
} }
break; break;
@ -947,7 +867,7 @@ public class DisguiseParser {
Collection<String> usedOptions, String[] args, String permNode) throws Throwable { Collection<String> usedOptions, String[] args, String permNode) throws Throwable {
WatcherMethod[] methods = ParamInfoManager.getDisguiseWatcherMethods(disguise.getWatcher().getClass(), true); WatcherMethod[] methods = ParamInfoManager.getDisguiseWatcherMethods(disguise.getWatcher().getClass(), true);
List<String> list = new ArrayList<>(Arrays.asList(args)); List<String> list = new ArrayList<>(Arrays.asList(args));
HashMap<String, HashMap<String, Boolean>> disguiseOptions = getDisguiseOptions(sender, permNode, disguisePerm); HashMap<String, HashMap<String, Boolean>> disguiseOptions = DisguisePermissions.getDisguiseOptions(sender, permNode, disguisePerm);
for (int argIndex = 0; argIndex < args.length; argIndex++) { for (int argIndex = 0; argIndex < args.length; argIndex++) {
// This is the method name they provided // This is the method name they provided
@ -1034,7 +954,7 @@ public class DisguiseParser {
if (!disguiseOptions.isEmpty()) { if (!disguiseOptions.isEmpty()) {
String stringValue = ParamInfoManager.toString(valueToSet); String stringValue = ParamInfoManager.toString(valueToSet);
if (!hasPermissionOption(disguiseOptions, methodToUse.getName(), stringValue)) { if (!DisguisePermissions.hasPermissionOption(disguiseOptions, methodToUse.getName(), stringValue)) {
throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_PARAM, stringValue, disguisePerm.toReadable()); throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_PARAM, stringValue, disguisePerm.toReadable());
} }
} }

View File

@ -2,6 +2,7 @@ package me.libraryaddict.disguise.utilities.parser;
import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Ageable; import org.bukkit.entity.Ageable;
import org.bukkit.entity.Animals; import org.bukkit.entity.Animals;
import org.bukkit.entity.Monster; import org.bukkit.entity.Monster;
@ -494,4 +495,85 @@ public class DisguisePermissions {
private PermissionStorage getStorage(DisguisePerm disguisePerm) { private PermissionStorage getStorage(DisguisePerm disguisePerm) {
return disguises.stream().filter(disguise -> disguise.getDisguise().equals(disguisePerm)).findAny().orElse(null); return disguises.stream().filter(disguise -> disguise.getDisguise().equals(disguisePerm)).findAny().orElse(null);
} }
public static HashMap<String, HashMap<String, Boolean>> getDisguiseOptions(Permissible permissionsHolder, String permNode, DisguisePerm type) {
HashMap<String, HashMap<String, Boolean>> returns = new HashMap<>();
// libsdisguises.options.<command>.<disguise>.<method>.<options>
for (PermissionAttachmentInfo permission : permissionsHolder.getEffectivePermissions()) {
String lowerPerm = permission.getPermission().toLowerCase(Locale.ENGLISH);
if (!lowerPerm.startsWith("libsdisguises.options.")) {
continue;
}
String[] split = lowerPerm.split("\\.");
// <command>.<disguise>.<method>.<options>
if (split.length < 4) {
continue;
}
if (!split[2].equalsIgnoreCase(permNode) && !split[2].equalsIgnoreCase("*")) {
continue;
}
boolean applicable = false;
for (String s : split[3].split("/")) {
if (!s.equals("*") && !s.replace("_", "").equalsIgnoreCase(type.toReadable().replace(" ", ""))) {
continue;
}
applicable = true;
break;
}
if (!applicable) {
continue;
}
HashMap<String, Boolean> options = new HashMap<>();
for (int i = 5; i < split.length; i++) {
options.put(split[i], permission.getValue());
}
for (String s : split[4].split("/")) {
if (returns.containsKey(s)) {
returns.get(s).putAll(options);
} else {
returns.put(s, options);
}
}
}
return returns;
}
/**
* Returns true if the string is found in the map, or it's not a whitelisted setup
* <p>
* Returns if command user can access the disguise creation permission type
*/
public static boolean hasPermissionOption(HashMap<String, HashMap<String, Boolean>> disguiseOptions, String method, String value) {
method = method.toLowerCase(Locale.ENGLISH);
// If no permissions were defined, return true
if (!disguiseOptions.containsKey(method)) {
return true;
}
HashMap<String, Boolean> map = disguiseOptions.get(method);
value = value.toLowerCase(Locale.ENGLISH);
// If they were explictly defined, can just return the value
if (map.containsKey(value)) {
return map.get(value);
}
// If there is at least one whitelisted value, then they needed the whitelist to use it
return !map.containsValue(true);
}
} }

View File

@ -1,6 +1,10 @@
package me.libraryaddict.disguise.utilities.parser; package me.libraryaddict.disguise.utilities.parser;
import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.utilities.params.ParamInfoManager;
import me.libraryaddict.disguise.utilities.translations.LibsMsg;
import org.bukkit.Material;
import org.bukkit.permissions.Permissible; import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.Permission; import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment; import org.bukkit.permissions.PermissionAttachment;
@ -12,6 +16,7 @@ import org.junit.Test;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -158,7 +163,7 @@ public class DisguisePermissionsTest {
DisguisePermissions permissions = DisguisePermissions permissions =
createPermissions("Disguise", false, "libsdisguises.disguise.cow", "libsdisguises.disguise.sheep.setColor.setSprinting", createPermissions("Disguise", false, "libsdisguises.disguise.cow", "libsdisguises.disguise.sheep.setColor.setSprinting",
"libsdisguises.disguise.animal.-setSprinting"); "libsdisguises.disguise.animal.-setSprinting", "libsdisguises.disguise.sheep.setcolor.blue");
Assert.assertTrue("There should be a valid disguise", permissions.hasPermissions()); Assert.assertTrue("There should be a valid disguise", permissions.hasPermissions());
@ -192,6 +197,23 @@ public class DisguisePermissionsTest {
Assert.assertFalse("The disguise should not be allowed even with options", Assert.assertFalse("The disguise should not be allowed even with options",
permissions.isAllowedDisguise(firework, Arrays.asList("setBaby", "setBurning"))); permissions.isAllowedDisguise(firework, Arrays.asList("setBaby", "setBurning")));
}
@Test
public void testDisguiseParameters() {
HashMap<String, HashMap<String, Boolean>> disguiseOptions =
DisguisePermissions.getDisguiseOptions(createPermissionsHolder(false, "libsdisguises.options.disguise.falling_block.setblock.stone"), "Disguise",
new DisguisePerm(DisguiseType.FALLING_BLOCK));
Assert.assertTrue("They should be allowed to use true as a disguise option on setBurning",
DisguisePermissions.hasPermissionOption(disguiseOptions, "setBurning", "true"));
Assert.assertTrue("They should be allowed to use Material.STONE as a disguise option",
DisguisePermissions.hasPermissionOption(disguiseOptions, "setBlock", "STONE"));
Assert.assertFalse("They should be not allowed to use Material.DIRT as a disguise option",
DisguisePermissions.hasPermissionOption(disguiseOptions, "setBlock", "DIRT"));
} }
@Test @Test
@ -236,7 +258,8 @@ public class DisguisePermissionsTest {
DisguiseConfig.setExplicitDisguisePermissions(false); DisguiseConfig.setExplicitDisguisePermissions(false);
} }
private DisguisePermissions createPermissions(String commandName, boolean isOp, String... perms) { private Permissible createPermissionsHolder(boolean isOp, String... perms) {
List<String> permitted = new ArrayList<>(); List<String> permitted = new ArrayList<>();
List<String> negated = new ArrayList<>(); List<String> negated = new ArrayList<>();
Set<PermissionAttachmentInfo> attachments = new HashSet<>(); Set<PermissionAttachmentInfo> attachments = new HashSet<>();
@ -321,6 +344,10 @@ public class DisguisePermissionsTest {
attachments.add(new PermissionAttachmentInfo(permissible, perm, null, setTrue)); attachments.add(new PermissionAttachmentInfo(permissible, perm, null, setTrue));
}); });
return new DisguisePermissions(permissible, commandName); return permissible;
}
private DisguisePermissions createPermissions(String commandName, boolean isOp, String... perms) {
return new DisguisePermissions(createPermissionsHolder(isOp, perms), commandName);
} }
} }