Fix superperms to pass all tests

http://dev.bukkit.org/server-mods/superpermstest/
This commit is contained in:
ElgarL 2011-11-25 15:49:35 +00:00
parent cd8ef9361b
commit 24a6073488
3 changed files with 312 additions and 231 deletions

View file

@ -77,3 +77,4 @@ v 1.6:
- Prevent Group.equals tests throwing a NullPointerException for GlobalGroups. - Prevent Group.equals tests throwing a NullPointerException for GlobalGroups.
- Stop throwing errors on an empty users file. - Stop throwing errors on an empty users file.
- Optimize sorting to speedup permission tests. - Optimize sorting to speedup permission tests.
- Fix superperms to pass all tests http://dev.bukkit.org/server-mods/superpermstest/

View file

@ -97,43 +97,59 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface {
@Override @Override
public List<String> getAllPlayersPermissions(String userName) { public List<String> getAllPlayersPermissions(String userName) {
List<String> playerPermArray = new ArrayList<String>(ph.getUser(userName).getPermissionList()); List<String> playerPermArray = new ArrayList<String>();
for (String perm : ph.getUser(userName).getPermissionList()) {
if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) {
playerPermArray.add(perm);
Map<String, Boolean> children = GroupManager.BukkitPermissions.getAllChildren(perm, playerPermArray);
if (children != null) {
for (String child : children.keySet()) {
if (children.get(child))
if ((!playerPermArray.contains(child)) && (!playerPermArray.contains("-" + child))) {
playerPermArray.add(child);
}
}
}
}
}
for (String group : getGroups(userName)) { for (String group : getGroups(userName)) {
if (group.startsWith("g:") && GroupManager.getGlobalGroups().hasGroup(group)) { if (group.startsWith("g:") && GroupManager.getGlobalGroups().hasGroup(group)) {
for (String perm : GroupManager.getGlobalGroups().getGroupsPermissions(group)) { for (String perm : GroupManager.getGlobalGroups().getGroupsPermissions(group)) {
if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) { if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) {
playerPermArray.add(perm); playerPermArray.add(perm);
Map<String, Boolean> children = GroupManager.BukkitPermissions.getChildren(perm); Map<String, Boolean> children = GroupManager.BukkitPermissions.getAllChildren(perm, playerPermArray);
if (children != null) { if (children != null) {
for (String child : children.keySet()) { for (String child : children.keySet()) {
if (children.get(child)) if (children.get(child))
if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) if ((!playerPermArray.contains(child)) && (!playerPermArray.contains("-" + child)))
playerPermArray.add(child); playerPermArray.add(child);
} }
} }
} }
} }
} else { } else {
for (String perm : ph.getGroup(group).getPermissionList()) { for (String perm : ph.getGroup(group).getPermissionList()) {
if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) { if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) {
playerPermArray.add(perm); playerPermArray.add(perm);
Map<String, Boolean> children = GroupManager.BukkitPermissions.getChildren(perm); Map<String, Boolean> children = GroupManager.BukkitPermissions.getAllChildren(perm, playerPermArray);
if (children != null) { if (children != null) {
for (String child : children.keySet()) { for (String child : children.keySet()) {
if (children.get(child)) if (children.get(child))
if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) if ((!playerPermArray.contains(child)) && (!playerPermArray.contains("-" + child))) {
playerPermArray.add(child); playerPermArray.add(child);
}
} }
} }
} }
} }
} }
} }
//Collections.sort(playerPermArray, StringPermissionComparator.getInstance());
return playerPermArray; return playerPermArray;
} }
@ -670,8 +686,22 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface {
* @return PermissionCheckResult * @return PermissionCheckResult
*/ */
public PermissionCheckResult checkFullUserPermission(User user, String targetPermission) { public PermissionCheckResult checkFullUserPermission(User user, String targetPermission) {
return checkFullGMPermission(user, targetPermission, true);
}
/**
* Check user and groups with inheritance and Bukkit if bukkit = true
* return a PermissionCheckResult.
*
* @param user
* @param targetPermission
* @param checkBukkit
* @return PermissionCheckResult
*/
public PermissionCheckResult checkFullGMPermission(User user, String targetPermission, Boolean checkBukkit) {
PermissionCheckResult result = new PermissionCheckResult(); PermissionCheckResult result = new PermissionCheckResult();
result.askedPermission = targetPermission; result.accessLevel = targetPermission;
result.resultType = PermissionCheckResult.Type.NOTFOUND; result.resultType = PermissionCheckResult.Type.NOTFOUND;
if (user == null || targetPermission == null || targetPermission.isEmpty()) { if (user == null || targetPermission == null || targetPermission.isEmpty()) {
@ -697,12 +727,14 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface {
} }
} }
// Check Bukkit perms to support plugins which add perms via code (Heroes). if (checkBukkit == true) {
final Player player = Bukkit.getPlayer(user.getName()); // Check Bukkit perms to support plugins which add perms via code (Heroes).
if ((player != null) && (player.hasPermission(targetPermission))) { final Player player = Bukkit.getPlayer(user.getName());
result.resultType = PermissionCheckResult.Type.FOUND; if ((player != null) && (player.hasPermission(targetPermission))) {
result.owner = user; result.resultType = PermissionCheckResult.Type.FOUND;
return result; result.owner = user;
return result;
}
} }
// THEN IT RETURNS A NOT FOUND // THEN IT RETURNS A NOT FOUND
@ -960,7 +992,7 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface {
* Every '-' or '+' in the beginning is ignored. It will match only node * Every '-' or '+' in the beginning is ignored. It will match only node
* names. * names.
* *
* @param userAcessLevel * @param userAccessLevel
* @param fullPermissionName * @param fullPermissionName
* @return true if found a matching token. false if not. * @return true if found a matching token. false if not.
*/ */
@ -986,9 +1018,11 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface {
} }
if (userAccessLevel.charAt(userAccessLevel.length() - 1) == '*') { if (userAccessLevel.charAt(userAccessLevel.length() - 1) == '*') {
userAccessLevelLength--; return userAccessLevel.regionMatches(true, userAccessLevelOffset, fullPermissionName, fullPermissionNameOffset, userAccessLevelLength - userAccessLevelOffset - 1);
} } else {
return userAccessLevel.regionMatches(true, userAccessLevelOffset, fullPermissionName, fullPermissionNameOffset, userAccessLevelLength - userAccessLevelOffset); return userAccessLevel.regionMatches(true, userAccessLevelOffset, fullPermissionName, fullPermissionNameOffset,
Math.max(userAccessLevelLength - userAccessLevelOffset, fullPermissionName.length() - fullPermissionNameOffset));
}
} }

View file

@ -18,14 +18,14 @@ package org.anjocaido.groupmanager.permissions;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.anjocaido.groupmanager.GroupManager; import org.anjocaido.groupmanager.GroupManager;
import org.anjocaido.groupmanager.data.User; import org.anjocaido.groupmanager.data.User;
import org.anjocaido.groupmanager.dataholder.OverloadedWorldHolder; import org.anjocaido.groupmanager.dataholder.OverloadedWorldHolder;
import org.anjocaido.groupmanager.utils.PermissionCheckResult;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -56,239 +56,285 @@ import org.bukkit.plugin.PluginManager;
*/ */
public class BukkitPermissions { public class BukkitPermissions {
protected Map<Player, PermissionAttachment> attachments = new HashMap<Player, PermissionAttachment>(); protected Map<Player, PermissionAttachment> attachments = new HashMap<Player, PermissionAttachment>();
protected Set<Permission> registeredPermissions = new HashSet<Permission>(); protected LinkedList<Permission> registeredPermissions = new LinkedList<Permission>();
protected GroupManager plugin; protected GroupManager plugin;
protected boolean dumpAllPermissions = true; protected boolean dumpAllPermissions = true;
protected boolean dumpMatchedPermissions = true; protected boolean dumpMatchedPermissions = true;
public boolean player_join = false; public boolean player_join = false;
public BukkitPermissions(GroupManager plugin) { public BukkitPermissions(GroupManager plugin) {
this.plugin = plugin; this.plugin = plugin;
this.collectPermissions(); this.collectPermissions();
this.registerEvents(); this.registerEvents();
this.updateAllPlayers(); this.updateAllPlayers();
GroupManager.logger.info("Superperms support enabled."); GroupManager.logger.info("Superperms support enabled.");
} }
private void registerEvents() { private void registerEvents() {
PluginManager manager = plugin.getServer().getPluginManager(); PluginManager manager = plugin.getServer().getPluginManager();
PlayerEvents playerEventListener = new PlayerEvents(); PlayerEvents playerEventListener = new PlayerEvents();
manager.registerEvent(Event.Type.PLAYER_JOIN, playerEventListener, Event.Priority.Lowest, plugin); manager.registerEvent(Event.Type.PLAYER_JOIN, playerEventListener, Event.Priority.Lowest, plugin);
manager.registerEvent(Event.Type.PLAYER_KICK, playerEventListener, Event.Priority.Lowest, plugin); manager.registerEvent(Event.Type.PLAYER_KICK, playerEventListener, Event.Priority.Lowest, plugin);
manager.registerEvent(Event.Type.PLAYER_QUIT, playerEventListener, Event.Priority.Lowest, plugin); manager.registerEvent(Event.Type.PLAYER_QUIT, playerEventListener, Event.Priority.Lowest, plugin);
manager.registerEvent(Event.Type.PLAYER_RESPAWN, playerEventListener, Event.Priority.Lowest, plugin); manager.registerEvent(Event.Type.PLAYER_RESPAWN, playerEventListener, Event.Priority.Lowest, plugin);
manager.registerEvent(Event.Type.PLAYER_TELEPORT, playerEventListener, Event.Priority.Lowest, plugin); manager.registerEvent(Event.Type.PLAYER_TELEPORT, playerEventListener, Event.Priority.Lowest, plugin);
manager.registerEvent(Event.Type.PLAYER_PORTAL, playerEventListener, Event.Priority.Lowest, plugin); manager.registerEvent(Event.Type.PLAYER_PORTAL, playerEventListener, Event.Priority.Lowest, plugin);
ServerListener serverListener = new BukkitEvents(); ServerListener serverListener = new BukkitEvents();
manager.registerEvent(Event.Type.PLUGIN_ENABLE, serverListener, Event.Priority.Normal, plugin); manager.registerEvent(Event.Type.PLUGIN_ENABLE, serverListener, Event.Priority.Normal, plugin);
manager.registerEvent(Event.Type.PLUGIN_DISABLE, serverListener, Event.Priority.Normal, plugin); manager.registerEvent(Event.Type.PLUGIN_DISABLE, serverListener, Event.Priority.Normal, plugin);
} }
public void collectPermissions() { public void collectPermissions() {
registeredPermissions.clear(); registeredPermissions.clear();
for (Plugin bukkitPlugin : Bukkit.getServer().getPluginManager().getPlugins()) { for (Plugin bukkitPlugin : Bukkit.getServer().getPluginManager().getPlugins()) {
for(Permission permission : bukkitPlugin.getDescription().getPermissions()) for (Permission permission : bukkitPlugin.getDescription().getPermissions())
registeredPermissions.add(permission); registeredPermissions.push(permission);
} }
} }
public void updatePermissions(Player player){ public void updatePermissions(Player player) {
this.updatePermissions(player, null); this.updatePermissions(player, null);
} }
public void updatePermissions(Player player, String world) { public void updatePermissions(Player player, String world) {
if (player == null || !GroupManager.isLoaded()) { if (player == null || !GroupManager.isLoaded()) {
return; return;
} }
if (!this.attachments.containsKey(player)) { if (!this.attachments.containsKey(player)) {
this.attachments.put(player, player.addAttachment(plugin)); this.attachments.put(player, player.addAttachment(plugin));
} }
if(world == null){ if (world == null) {
world = player.getWorld().getName(); world = player.getWorld().getName();
} }
// All permissions registered with Bukkit for this player // All permissions registered with Bukkit for this player
PermissionAttachment attachment = this.attachments.get(player); PermissionAttachment attachment = this.attachments.get(player);
OverloadedWorldHolder worldData = plugin.getWorldsHolder().getWorldData(world); OverloadedWorldHolder worldData = plugin.getWorldsHolder().getWorldData(world);
User user = worldData.getUser(player.getName()); User user = worldData.getUser(player.getName());
// clear permissions // clear permissions
for (String permission : attachment.getPermissions().keySet()) for (String permission : attachment.getPermissions().keySet())
attachment.unsetPermission(permission); attachment.unsetPermission(permission);
/* /*
* find matching permissions * find matching permissions
* *
* and base bukkit perms if we are set to allow bukkit permissions to override. * and base bukkit perms if we are set to allow bukkit permissions to
*/ * override.
Boolean value; */
for (Permission permission : registeredPermissions) { Boolean value = false;
value = worldData.getPermissionsHandler().checkUserPermission(user, permission.getName()); for (Permission permission : registeredPermissions) {
// Only check bukkit override IF we don't have the permission directly. PermissionCheckResult result = worldData.getPermissionsHandler().checkFullGMPermission(user, permission.getName(), false);
if (value = false) {
PermissionDefault permDefault = permission.getDefault();
if ((plugin.getGMConfig().isBukkitPermsOverride()) // Only check bukkit override IF we don't have the permission
&& ((permDefault == PermissionDefault.TRUE) // directly.
|| ((permDefault == PermissionDefault.NOT_OP) && !player.isOp()) if (result.resultType == PermissionCheckResult.Type.NOTFOUND) {
|| ((permDefault == PermissionDefault.OP) && player.isOp()))) PermissionDefault permDefault = permission.getDefault();
value = true;
}
if (value == true){ if ((plugin.getGMConfig().isBukkitPermsOverride()) && ((permDefault == PermissionDefault.TRUE)
// Set the root permission || ((permDefault == PermissionDefault.NOT_OP) && !player.isOp())
attachment.setPermission(permission, value); || ((permDefault == PermissionDefault.OP) && player.isOp()))) {
// fetch and set all children of this permission node value = true;
Map<String, Boolean> children = permission.getChildren(); } else {
if (children != null) { value = false;
for (String child : children.keySet()) { }
if (children.get(child)) } else if (result.resultType == PermissionCheckResult.Type.NEGATION) {
attachment.setPermission(child, true); value = false;
} } else {
} value = true;
}
} // Set the root permission
} if ((value == true) || (result.resultType == PermissionCheckResult.Type.NEGATION)) {
attachment.setPermission(permission, value);
}
/*
if ((value == true) || (result.resultType == PermissionCheckResult.Type.NOTFOUND)) {
// fetch and set all children of this permission node
Map<String, Boolean> children = permission.getChildren();
if (children != null) {
for (String child : children.keySet()) {
if (children.get(child))
attachment.setPermission(child, value);
}
}
}*/
// Add any missing permissions for this player (non bukkit plugins) }
List<String> playerPermArray = new ArrayList<String>(worldData.getPermissionsHandler().getAllPlayersPermissions(player.getName()));
for (String permission : playerPermArray) { // Add any missing permissions for this player (non bukkit plugins and child nodes)
value = true; List<String> playerPermArray = worldData.getPermissionsHandler().getAllPlayersPermissions(player.getName());
if (permission.startsWith("-")) {
permission = permission.substring(1); // cut off -
value = false;
}
if (!attachment.getPermissions().containsKey(permission)) { for (String permission : playerPermArray) {
attachment.setPermission(permission, value); value = true;
} if (permission.startsWith("-")) {
} permission = permission.substring(1); // cut off -
player.recalculatePermissions(); value = false;
} }
/** if (!attachment.getPermissions().containsKey(permission)) {
* Returns a map of the child permissions as defined by the supplying plugin attachment.setPermission(permission, value);
* null is empty }
* }
* @param node player.recalculatePermissions();
* @return Map of child permissions }
*/
public Map<String, Boolean> getChildren(String node) {
for (Permission permission : registeredPermissions) {
if (permission.getName() == node) {
return permission.getChildren();
}
}
return null;
}
public List<String> listPerms(Player player) { /**
List<String> perms = new ArrayList<String>(); * Returns a map of the ALL child permissions as defined by the supplying plugin
* null is empty
*
* @param node
* @return Map of child permissions
*/
public Map<String, Boolean> getAllChildren(String node, List<String> playerPermArray) {
/* LinkedList<String> stack = new LinkedList<String>();
// All permissions registered with Bukkit for this player Map<String, Boolean> alreadyVisited = new HashMap<String, Boolean>();
PermissionAttachment attachment = this.attachments.get(player); stack.push(node);
alreadyVisited.put(node, true);
// List perms for this player while (!stack.isEmpty()) {
perms.add("Attachment Permissions:"); String now = stack.pop();
for(Map.Entry<String, Boolean> entry : attachment.getPermissions().entrySet()){
perms.add(" " + entry.getKey() + " = " + entry.getValue());
}
*/
perms.add("Effective Permissions:"); Map<String, Boolean> children = getChildren(now);
for(PermissionAttachmentInfo info : player.getEffectivePermissions()){
if (info.getValue() == true)
perms.add(" " + info.getPermission() + " = " + info.getValue());
}
return perms;
}
public void updateAllPlayers() { if ((children != null) && (!playerPermArray.contains("-"+now))) {
for (Player player : Bukkit.getServer().getOnlinePlayers()) { for (String childName : children.keySet()) {
updatePermissions(player); if (!alreadyVisited.containsKey(childName)) {
} stack.push(childName);
} alreadyVisited.put(childName, children.get(childName));
}
}
}
}
alreadyVisited.remove(node);
if (!alreadyVisited.isEmpty()) return alreadyVisited;
protected class PlayerEvents extends PlayerListener { return null;
}
@Override /**
public void onPlayerJoin(PlayerJoinEvent event) { * Returns a map of the child permissions (1 node deep) as defined by the supplying plugin
player_join = true; * null is empty
Player player = event.getPlayer(); *
//force GM to create the player if they are not already listed. * @param node
if (plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getUser(player.getName()) != null) { * @return Map of child permissions
player_join = false; */
updatePermissions(event.getPlayer()); public Map<String, Boolean> getChildren(String node) {
} else for (Permission permission : registeredPermissions) {
player_join = false; if (permission.getName().equalsIgnoreCase(node)) {
} return permission.getChildren();
}
}
@Override return null;
public void onPlayerPortal(PlayerPortalEvent event) { // will portal into another world }
if(event.getTo() != null && !event.getFrom().getWorld().equals(event.getTo().getWorld())){ // only if world actually changed
updatePermissions(event.getPlayer(), event.getTo().getWorld().getName());
}
}
@Override public List<String> listPerms(Player player) {
public void onPlayerRespawn(PlayerRespawnEvent event) { // can be respawned in another world List<String> perms = new ArrayList<String>();
updatePermissions(event.getPlayer(), event.getRespawnLocation().getWorld().getName());
}
@Override /*
public void onPlayerTeleport(PlayerTeleportEvent event) { // can be teleported into another world * // All permissions registered with Bukkit for this player
if (event.getTo() != null && !event.getFrom().getWorld().equals(event.getTo().getWorld())) { // only if world actually changed * PermissionAttachment attachment = this.attachments.get(player);
updatePermissions(event.getPlayer(), event.getTo().getWorld().getName()); *
} * // List perms for this player perms.add("Attachment Permissions:");
} * for(Map.Entry<String, Boolean> entry :
* attachment.getPermissions().entrySet()){ perms.add(" " +
* entry.getKey() + " = " + entry.getValue()); }
*/
@Override perms.add("Effective Permissions:");
public void onPlayerQuit(PlayerQuitEvent event) { for (PermissionAttachmentInfo info : player.getEffectivePermissions()) {
if (!GroupManager.isLoaded()) if (info.getValue() == true)
return; perms.add(" " + info.getPermission() + " = " + info.getValue());
}
return perms;
}
attachments.remove(event.getPlayer()); public void updateAllPlayers() {
} for (Player player : Bukkit.getServer().getOnlinePlayers()) {
updatePermissions(player);
}
}
@Override protected class PlayerEvents extends PlayerListener {
public void onPlayerKick(PlayerKickEvent event) {
attachments.remove(event.getPlayer());
}
}
protected class BukkitEvents extends ServerListener { @Override
public void onPlayerJoin(PlayerJoinEvent event) {
player_join = true;
Player player = event.getPlayer();
// force GM to create the player if they are not already listed.
if (plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getUser(player.getName()) != null) {
player_join = false;
updatePermissions(event.getPlayer());
} else
player_join = false;
}
@Override @Override
public void onPluginEnable(PluginEnableEvent event) { public void onPlayerPortal(PlayerPortalEvent event) { // will portal into another world
if (!GroupManager.isLoaded()) if (event.getTo() != null && !event.getFrom().getWorld().equals(event.getTo().getWorld())) { // only if world actually changed
return; updatePermissions(event.getPlayer(), event.getTo().getWorld().getName());
}
}
collectPermissions(); @Override
updateAllPlayers(); public void onPlayerRespawn(PlayerRespawnEvent event) { // can be respawned in another world
} updatePermissions(event.getPlayer(), event.getRespawnLocation().getWorld().getName());
}
@Override @Override
public void onPluginDisable(PluginDisableEvent event) { public void onPlayerTeleport(PlayerTeleportEvent event) { // can be teleported into another world
//collectPermissions(); if (event.getTo() != null && !event.getFrom().getWorld().equals(event.getTo().getWorld())) { // only if world actually changed
//updateAllPlayers(); updatePermissions(event.getPlayer(), event.getTo().getWorld().getName());
} }
} }
@Override
public void onPlayerQuit(PlayerQuitEvent event) {
if (!GroupManager.isLoaded())
return;
attachments.remove(event.getPlayer());
}
@Override
public void onPlayerKick(PlayerKickEvent event) {
attachments.remove(event.getPlayer());
}
}
protected class BukkitEvents extends ServerListener {
@Override
public void onPluginEnable(PluginEnableEvent event) {
if (!GroupManager.isLoaded())
return;
collectPermissions();
updateAllPlayers();
}
@Override
public void onPluginDisable(PluginDisableEvent event) {
// collectPermissions();
// updateAllPlayers();
}
}
} }