mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2025-02-16 12:31:59 +01:00
Bukkit perms are broken.
Or at least they don't work the way they (in my opinion) should. Take a look at HierarchyPermission.java for a detailed explanation.
This commit is contained in:
parent
4a66a2f5bb
commit
caf4f1b566
@ -0,0 +1,52 @@
|
|||||||
|
package com.onarandombox.MultiverseCore.permissions;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.permissions.Permission;
|
||||||
|
import org.bukkit.permissions.Permissible;
|
||||||
|
import org.bukkit.permissions.PermissionDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides improved parent-child relationships for permissions. This is the standard implementation of {@link PermissionNode}.
|
||||||
|
* <p>
|
||||||
|
* Apparently parents override their children in Bukkit:
|
||||||
|
* Let {@code permissionA} be a parent permission of {@code permissionB}, setting {@code permissionB} to {@code true}.
|
||||||
|
* Now a player has {@code permissionA=true} and {@code permissionB=false}. Result: Both are {@code true}.
|
||||||
|
* Another player has {@code permissionA=false} and {@code permissionB=true}. Result: Both are {@code false}.
|
||||||
|
* <p>
|
||||||
|
* This is completely useless for things like MV's world access permissions where you could for example want to deny
|
||||||
|
* access to all worlds by default, with a few exceptions.
|
||||||
|
* <p>
|
||||||
|
* This class takes over all the permission hierarchy checks and provides a way that makes sense. In the
|
||||||
|
* above examples, the effective permissions would be equal to the permissions that were set.
|
||||||
|
*/
|
||||||
|
public class HierarchyPermission implements PermissionNode {
|
||||||
|
private final PermissionNode parent;
|
||||||
|
private final Permission permission;
|
||||||
|
|
||||||
|
public HierarchyPermission(final PermissionNode parent, final String permission, final String description) {
|
||||||
|
this.parent = parent;
|
||||||
|
Permission p = Bukkit.getServer().getPluginManager().getPermission(permission);
|
||||||
|
if (p == null)
|
||||||
|
p = new Permission(permission, description, PermissionDefault.FALSE);
|
||||||
|
else {
|
||||||
|
p.getChildren().clear();
|
||||||
|
//p.recalculatePermissibles(); // Not necessary because it's done automatically after setting the default
|
||||||
|
p.setDefault(PermissionDefault.FALSE);
|
||||||
|
}
|
||||||
|
this.permission = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a given {@link Permissible} has this {@link HierarchyPermission}.
|
||||||
|
*
|
||||||
|
* @param permissible The {@link Permissible} that might have the permission.
|
||||||
|
* @return Whether it has the permission.
|
||||||
|
*/
|
||||||
|
public boolean has(Permissible permissible) {
|
||||||
|
if (permissible.isPermissionSet(permission))
|
||||||
|
return permissible.hasPermission(permission);
|
||||||
|
|
||||||
|
// ask the guy over there
|
||||||
|
return parent.has(permissible);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.onarandombox.MultiverseCore.permissions;
|
||||||
|
|
||||||
|
import org.bukkit.permissions.Permissible;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a permission node with dynamically created children.
|
||||||
|
*/
|
||||||
|
public class PermissionCollection {
|
||||||
|
private final PermissionNode root;
|
||||||
|
private final Map<String, PermissionNode> elements;
|
||||||
|
private final String prefix;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
public PermissionCollection(PermissionNode parent, String prefix, String description) {
|
||||||
|
if (!prefix.endsWith("."))
|
||||||
|
throw new IllegalArgumentException("The prefix must end with a dot!");
|
||||||
|
this.root = new HierarchyPermission(parent, prefix + "*", description);
|
||||||
|
this.elements = new HashMap<String, PermissionNode>();
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a given {@link Permissible} has a specified element permission.
|
||||||
|
*
|
||||||
|
* @param p The {@link Permissible}.
|
||||||
|
* @param element The element.
|
||||||
|
* @return Whether the {@link Permissible} has the permission.
|
||||||
|
*/
|
||||||
|
public boolean has(Permissible p, String element) {
|
||||||
|
if (!this.elements.containsKey(element))
|
||||||
|
this.elements.put(element, new HierarchyPermission(root, prefix + element, description));
|
||||||
|
return this.elements.get(element).has(p);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.onarandombox.MultiverseCore.permissions;
|
||||||
|
|
||||||
|
import org.bukkit.permissions.Permissible;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A node in a permissions hierarchy.
|
||||||
|
*
|
||||||
|
* @see HierarchyPermission
|
||||||
|
*/
|
||||||
|
public interface PermissionNode {
|
||||||
|
static final class OperatorDefault implements PermissionNode {
|
||||||
|
@Override
|
||||||
|
public boolean has(final Permissible permissible) {
|
||||||
|
return permissible.isOp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link HierarchyPermission} depends on the operator state. Ops have it, non-ops don't.
|
||||||
|
*/
|
||||||
|
PermissionNode OP_DEFAULT = new OperatorDefault();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a given {@link Permissible} has this node.
|
||||||
|
*
|
||||||
|
* @param permissible The {@link Permissible} that might have the permission.
|
||||||
|
* @return Whether it has the permission.
|
||||||
|
*/
|
||||||
|
boolean has(Permissible permissible);
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.onarandombox.MultiverseCore.permissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permission nodes.
|
||||||
|
*/
|
||||||
|
public class Permissions {
|
||||||
|
protected Permissions() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@code multiverse.*} permission.
|
||||||
|
*/
|
||||||
|
public static final HierarchyPermission MV_ROOT = new HierarchyPermission(PermissionNode.OP_DEFAULT,
|
||||||
|
"multiverse.*", "Provides access to all Multiverse features.");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@code multiverse.access.*} family of permissions.
|
||||||
|
*/
|
||||||
|
public static final PermissionCollection ACCESS = new PermissionCollection(MV_ROOT, "multiverse.access.", "World access");
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* Contains permissions utility classes.
|
||||||
|
*/
|
||||||
|
package com.onarandombox.MultiverseCore.permissions;
|
@ -11,6 +11,7 @@ import com.onarandombox.MultiverseCore.MultiverseCore;
|
|||||||
import com.onarandombox.MultiverseCore.api.MVDestination;
|
import com.onarandombox.MultiverseCore.api.MVDestination;
|
||||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||||
|
import com.onarandombox.MultiverseCore.permissions.Permissions;
|
||||||
import com.pneumaticraft.commandhandler.PermissionsInterface;
|
import com.pneumaticraft.commandhandler.PermissionsInterface;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -103,18 +104,15 @@ public class MVPermissions implements PermissionsInterface {
|
|||||||
this.plugin.log(Level.FINEST, "EnforceAccess is OFF. Player was allowed in " + w.getAlias());
|
this.plugin.log(Level.FINEST, "EnforceAccess is OFF. Player was allowed in " + w.getAlias());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return this.hasPermission(p, "multiverse.access." + w.getName(), false);
|
return Permissions.ACCESS.has(p, w.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canEnterLocation(Player p, Location l) {
|
private boolean canEnterLocation(Player p, Location l) {
|
||||||
if (l == null) {
|
if (l == null)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
String worldName = l.getWorld().getName();
|
String worldName = l.getWorld().getName();
|
||||||
if (!this.plugin.getMVWorldManager().isMVWorld(worldName)) {
|
return this.plugin.getMVWorldManager().isMVWorld(worldName) && Permissions.ACCESS.has(p, worldName);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return this.hasPermission(p, "multiverse.access." + worldName, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user