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) {
for (DisguisePerm perm : getDisguisePerms()) {
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) {
if (entity == null) {
return "??";
@ -778,7 +697,7 @@ public class DisguiseParser {
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 (disguisePerm.isPlayer()) {
@ -788,8 +707,9 @@ public class DisguiseParser {
throw new DisguiseParseException(LibsMsg.PARSE_SUPPLY_PLAYER);
} else {
// If they can't use this name, throw error
if (!hasPermissionOption(disguiseOptions, "setname", args[1].toLowerCase(Locale.ENGLISH))) {
if (!args[1].equalsIgnoreCase(sender.getName()) || !hasPermissionOption(disguiseOptions, "setname", "themselves")) {
if (!DisguisePermissions.hasPermissionOption(disguiseOptions, "setname", args[1].toLowerCase(Locale.ENGLISH))) {
if (!args[1].equalsIgnoreCase(sender.getName()) ||
!DisguisePermissions.hasPermissionOption(disguiseOptions, "setname", "themselves")) {
throw new DisguiseParseException(LibsMsg.PARSE_NO_PERM_NAME);
}
}
@ -872,7 +792,7 @@ public class DisguiseParser {
doCheck(sender, permissions, disguisePerm, usedOptions);
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());
}
@ -898,7 +818,7 @@ public class DisguiseParser {
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());
}
break;
@ -947,7 +867,7 @@ public class DisguiseParser {
Collection<String> usedOptions, String[] args, String permNode) throws Throwable {
WatcherMethod[] methods = ParamInfoManager.getDisguiseWatcherMethods(disguise.getWatcher().getClass(), true);
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++) {
// This is the method name they provided
@ -1034,7 +954,7 @@ public class DisguiseParser {
if (!disguiseOptions.isEmpty()) {
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());
}
}

View File

@ -2,6 +2,7 @@ package me.libraryaddict.disguise.utilities.parser;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Animals;
import org.bukkit.entity.Monster;
@ -494,4 +495,85 @@ public class DisguisePermissions {
private PermissionStorage getStorage(DisguisePerm disguisePerm) {
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;
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.Permission;
import org.bukkit.permissions.PermissionAttachment;
@ -12,6 +16,7 @@ import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -158,7 +163,7 @@ public class DisguisePermissionsTest {
DisguisePermissions permissions =
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());
@ -192,6 +197,23 @@ public class DisguisePermissionsTest {
Assert.assertFalse("The disguise should not be allowed even with options",
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
@ -236,7 +258,8 @@ public class DisguisePermissionsTest {
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> negated = new ArrayList<>();
Set<PermissionAttachmentInfo> attachments = new HashSet<>();
@ -321,6 +344,10 @@ public class DisguisePermissionsTest {
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);
}
}