From 28b928f4b29a92bdae0ae0b0736e765f52cda7d0 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 3 May 2020 20:52:24 -0400 Subject: [PATCH] Add API allowing addons to check trust levels for offline players (#801) * Expose explicit ClaimPermission levels * Add getPermission to allow addons to check other trust --- .../ryanhamshire/GriefPrevention/Claim.java | 99 ++++++++++--------- .../GriefPrevention/ClaimPermission.java | 15 ++- 2 files changed, 66 insertions(+), 48 deletions(-) diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/Claim.java b/src/main/java/me/ryanhamshire/GriefPrevention/Claim.java index 8858f3b..0d9f323 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/Claim.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/Claim.java @@ -208,26 +208,17 @@ public class Claim //other permissions for(String builderID : builderIDs) { - if(builderID != null && !builderID.isEmpty()) - { - this.playerIDToClaimPermissionMap.put(builderID, ClaimPermission.Build); - } + this.setPermission(builderID, ClaimPermission.Build); } for(String containerID : containerIDs) { - if(containerID != null && !containerID.isEmpty()) - { - this.playerIDToClaimPermissionMap.put(containerID, ClaimPermission.Inventory); - } + this.setPermission(containerID, ClaimPermission.Inventory); } for(String accessorID : accessorIDs) { - if(accessorID != null && !accessorID.isEmpty()) - { - this.playerIDToClaimPermissionMap.put(accessorID, ClaimPermission.Access); - } + this.setPermission(accessorID, ClaimPermission.Access); } for(String managerID : managerIDs) @@ -379,10 +370,9 @@ public class Claim //anyone with explicit build permission can make changes if(this.hasExplicitPermission(player, ClaimPermission.Build)) return null; - + //also everyone is a member of the "public", so check for public permission - ClaimPermission permissionLevel = this.playerIDToClaimPermissionMap.get("public"); - if(ClaimPermission.Build == permissionLevel) return null; + if(ClaimPermission.Build.isGrantedBy(this.playerIDToClaimPermissionMap.get("public"))) return null; //allow for farming with /containertrust permission if(this.allowContainers(player) == null) @@ -410,31 +400,36 @@ public class Claim return reason; } - - private boolean hasExplicitPermission(Player player, ClaimPermission level) + + public boolean hasExplicitPermission(UUID uuid, ClaimPermission level) { - String playerID = player.getUniqueId().toString(); - Set keys = this.playerIDToClaimPermissionMap.keySet(); - Iterator iterator = keys.iterator(); - while(iterator.hasNext()) + return level.isGrantedBy(this.playerIDToClaimPermissionMap.get(uuid.toString())); + } + + public boolean hasExplicitPermission(Player player, ClaimPermission level) + { + // Check explicit ClaimPermission for UUID + if (this.hasExplicitPermission(player.getUniqueId(), level)) return true; + + // Check permission-based ClaimPermission + for (Map.Entry stringToPermission : this.playerIDToClaimPermissionMap.entrySet()) { - String identifier = iterator.next(); - if(playerID.equalsIgnoreCase(identifier) && this.playerIDToClaimPermissionMap.get(identifier) == level) return true; - - else if(identifier.startsWith("[") && identifier.endsWith("]")) + String node = stringToPermission.getKey(); + // Ensure valid permission format for permissions - [permission.node] + if (node.length() < 3 || node.charAt(0) != '[' || node.charAt(node.length() -1) != ']') { - //drop the brackets - String permissionIdentifier = identifier.substring(1, identifier.length() - 1); - - //defensive coding - if(permissionIdentifier == null || permissionIdentifier.isEmpty()) continue; - - //check permission - if(player.hasPermission(permissionIdentifier) && this.playerIDToClaimPermissionMap.get(identifier) == level) return true; + continue; + } + + // Check if level is high enough and player has node + if (level.isGrantedBy(stringToPermission.getValue()) + && player.hasPermission(node.substring(1, node.length() - 1))) + { + return true; } } - - return false; + + return false; } //break permission check @@ -492,12 +487,9 @@ public class Claim //look for explicit individual access, inventory, or build permission if(this.hasExplicitPermission(player, ClaimPermission.Access)) return null; - if(this.hasExplicitPermission(player, ClaimPermission.Inventory)) return null; - if(this.hasExplicitPermission(player, ClaimPermission.Build)) return null; - + //also check for public permission - ClaimPermission permissionLevel = this.playerIDToClaimPermissionMap.get("public"); - if(ClaimPermission.Build == permissionLevel || ClaimPermission.Inventory == permissionLevel || ClaimPermission.Access == permissionLevel) return null; + if(ClaimPermission.Access.isGrantedBy(this.playerIDToClaimPermissionMap.get("public"))) return null; //permission inheritance for subdivisions if(this.parent != null) @@ -541,11 +533,9 @@ public class Claim //check for explicit individual container or build permission if(this.hasExplicitPermission(player, ClaimPermission.Inventory)) return null; - if(this.hasExplicitPermission(player, ClaimPermission.Build)) return null; //check for public container or build permission - ClaimPermission permissionLevel = this.playerIDToClaimPermissionMap.get("public"); - if(ClaimPermission.Build == permissionLevel || ClaimPermission.Inventory == permissionLevel) return null; + if(ClaimPermission.Inventory.isGrantedBy(this.playerIDToClaimPermissionMap.get("public"))) return null; //permission inheritance for subdivisions if(this.parent != null) @@ -601,11 +591,26 @@ public class Claim reason += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement); return reason; } + + public ClaimPermission getPermission(String playerID) + { + if (playerID == null || playerID.isEmpty()) + { + return null; + } + + return this.playerIDToClaimPermissionMap.get(playerID.toLowerCase()); + } //grants a permission for a player or the public public void setPermission(String playerID, ClaimPermission permissionLevel) { - this.playerIDToClaimPermissionMap.put(playerID.toLowerCase(), permissionLevel); + if (playerID == null || playerID.isEmpty()) + { + return; + } + + this.playerIDToClaimPermissionMap.put(playerID.toLowerCase(), permissionLevel); } //revokes a permission for a player or the public @@ -636,11 +641,11 @@ public class Claim public void getPermissions(ArrayList builders, ArrayList containers, ArrayList accessors, ArrayList managers) { //loop through all the entries in the hash map - Iterator> mappingsIterator = this.playerIDToClaimPermissionMap.entrySet().iterator(); + Iterator> mappingsIterator = this.playerIDToClaimPermissionMap.entrySet().iterator(); while(mappingsIterator.hasNext()) { Map.Entry entry = mappingsIterator.next(); - + //build up a list for each permission level if(entry.getValue() == ClaimPermission.Build) { @@ -653,7 +658,7 @@ public class Claim else { accessors.add(entry.getKey()); - } + } } //managers are handled a little differently diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/ClaimPermission.java b/src/main/java/me/ryanhamshire/GriefPrevention/ClaimPermission.java index e480b7f..a24e0be 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/ClaimPermission.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/ClaimPermission.java @@ -23,5 +23,18 @@ public enum ClaimPermission { Build, Inventory, - Access + Access; + + /** + * Check if a ClaimPermission is granted by another ClaimPermission. + * + * @param other the ClaimPermission to compare against + * @return true if this ClaimPermission is equal or lesser than the provided ClaimPermission + */ + public boolean isGrantedBy(ClaimPermission other) + { + // As this uses declaration order to compare, if trust levels are reordered this method must be rewritten. + return other != null && other.ordinal() <= this.ordinal(); + } + }