Add wildcard permissions
This commit is contained in:
@@ -106,6 +106,12 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
List<String> getPlayerList();
|
||||
|
||||
/**
|
||||
* Gets all possible permission nodes, used for resolving wildcards
|
||||
* @return a {@link List} of permission nodes
|
||||
*/
|
||||
List<String> getPossiblePermissions();
|
||||
|
||||
/**
|
||||
* Runs an update task
|
||||
*/
|
||||
|
||||
+5
@@ -63,6 +63,11 @@ public class LPConfigurationLink implements LPConfiguration {
|
||||
return master.getOnlineMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getApplyWildcards() {
|
||||
return master.getApplyWildcards();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MySQLConfiguration getDatabaseValues() {
|
||||
return master.getDatabaseValues();
|
||||
|
||||
+10
@@ -175,11 +175,21 @@ class PermissionHolderLink implements PermissionHolder {
|
||||
master.unsetPermission(checkNode(node), checkServer(server), world, temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups, List<String> possibleNodes) {
|
||||
return master.getLocalPermissions(server, world, excludedGroups, possibleNodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups) {
|
||||
return master.getLocalPermissions(server, world, excludedGroups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups, List<String> possibleNodes) {
|
||||
return master.getLocalPermissions(server, excludedGroups, possibleNodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups) {
|
||||
return master.getLocalPermissions(server, excludedGroups);
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
package me.lucko.luckperms.constants;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
@@ -42,74 +41,56 @@ public enum Permission {
|
||||
DELETE_TRACK("deletetrack", null),
|
||||
LIST_TRACKS("listtracks", null),
|
||||
|
||||
USER_INFO("info", PermissionGroup.USER),
|
||||
USER_GETUUID("getuuid", PermissionGroup.USER),
|
||||
USER_LISTNODES("listnodes", PermissionGroup.USER),
|
||||
USER_HASPERMISSION("haspermission", PermissionGroup.USER),
|
||||
USER_INHERITSPERMISSION("inheritspermission", PermissionGroup.USER),
|
||||
USER_SETPERMISSION("setpermission", PermissionGroup.USER),
|
||||
USER_UNSETPERMISSION("unsetpermission", PermissionGroup.USER),
|
||||
USER_ADDGROUP("addgroup", PermissionGroup.USER),
|
||||
USER_REMOVEGROUP("removegroup", PermissionGroup.USER),
|
||||
USER_SET_TEMP_PERMISSION("settemppermission", PermissionGroup.USER),
|
||||
USER_UNSET_TEMP_PERMISSION("unsettemppermission", PermissionGroup.USER),
|
||||
USER_ADDTEMPGROUP("addtempgroup", PermissionGroup.USER),
|
||||
USER_REMOVETEMPGROUP("removetempgroup", PermissionGroup.USER),
|
||||
USER_SETPRIMARYGROUP("setprimarygroup", PermissionGroup.USER),
|
||||
USER_SHOWTRACKS("showtracks", PermissionGroup.USER),
|
||||
USER_PROMOTE("promote", PermissionGroup.USER),
|
||||
USER_DEMOTE("demote", PermissionGroup.USER),
|
||||
USER_SHOWPOS("showpos", PermissionGroup.USER),
|
||||
USER_CLEAR("clear", PermissionGroup.USER),
|
||||
USER_INFO("info", "user"),
|
||||
USER_GETUUID("getuuid", "user"),
|
||||
USER_LISTNODES("listnodes", "user"),
|
||||
USER_HASPERMISSION("haspermission", "user"),
|
||||
USER_INHERITSPERMISSION("inheritspermission", "user"),
|
||||
USER_SETPERMISSION("setpermission", "user"),
|
||||
USER_UNSETPERMISSION("unsetpermission", "user"),
|
||||
USER_ADDGROUP("addgroup", "user"),
|
||||
USER_REMOVEGROUP("removegroup", "user"),
|
||||
USER_SET_TEMP_PERMISSION("settemppermission", "user"),
|
||||
USER_UNSET_TEMP_PERMISSION("unsettemppermission", "user"),
|
||||
USER_ADDTEMPGROUP("addtempgroup", "user"),
|
||||
USER_REMOVETEMPGROUP("removetempgroup", "user"),
|
||||
USER_SETPRIMARYGROUP("setprimarygroup", "user"),
|
||||
USER_SHOWTRACKS("showtracks", "user"),
|
||||
USER_PROMOTE("promote", "user"),
|
||||
USER_DEMOTE("demote", "user"),
|
||||
USER_SHOWPOS("showpos", "user"),
|
||||
USER_CLEAR("clear", "user"),
|
||||
|
||||
GROUP_INFO("info", PermissionGroup.GROUP),
|
||||
GROUP_LISTNODES("listnodes", PermissionGroup.GROUP),
|
||||
GROUP_HASPERMISSION("haspermission", PermissionGroup.GROUP),
|
||||
GROUP_INHERITSPERMISSION("inheritspermission", PermissionGroup.GROUP),
|
||||
GROUP_SETPERMISSION("setpermission", PermissionGroup.GROUP),
|
||||
GROUP_UNSETPERMISSION("unsetpermission", PermissionGroup.GROUP),
|
||||
GROUP_SETINHERIT("setinherit", PermissionGroup.GROUP),
|
||||
GROUP_UNSETINHERIT("unsetinherit", PermissionGroup.GROUP),
|
||||
GROUP_SET_TEMP_PERMISSION("settemppermission", PermissionGroup.GROUP),
|
||||
GROUP_UNSET_TEMP_PERMISSION("unsettemppermission", PermissionGroup.GROUP),
|
||||
GROUP_SET_TEMP_INHERIT("settempinherit", PermissionGroup.GROUP),
|
||||
GROUP_UNSET_TEMP_INHERIT("unsettempinherit", PermissionGroup.GROUP),
|
||||
GROUP_SHOWTRACKS("showtracks", PermissionGroup.GROUP),
|
||||
GROUP_CLEAR("clear", PermissionGroup.GROUP),
|
||||
GROUP_INFO("info", "group"),
|
||||
GROUP_LISTNODES("listnodes", "group"),
|
||||
GROUP_HASPERMISSION("haspermission", "group"),
|
||||
GROUP_INHERITSPERMISSION("inheritspermission", "group"),
|
||||
GROUP_SETPERMISSION("setpermission", "group"),
|
||||
GROUP_UNSETPERMISSION("unsetpermission", "group"),
|
||||
GROUP_SETINHERIT("setinherit", "group"),
|
||||
GROUP_UNSETINHERIT("unsetinherit", "group"),
|
||||
GROUP_SET_TEMP_PERMISSION("settemppermission", "group"),
|
||||
GROUP_UNSET_TEMP_PERMISSION("unsettemppermission", "group"),
|
||||
GROUP_SET_TEMP_INHERIT("settempinherit", "group"),
|
||||
GROUP_UNSET_TEMP_INHERIT("unsettempinherit", "group"),
|
||||
GROUP_SHOWTRACKS("showtracks", "group"),
|
||||
GROUP_CLEAR("clear", "group"),
|
||||
|
||||
TRACK_INFO("info", PermissionGroup.TRACK),
|
||||
TRACK_APPEND("append", PermissionGroup.TRACK),
|
||||
TRACK_INSERT("insert", PermissionGroup.TRACK),
|
||||
TRACK_REMOVE("remove", PermissionGroup.TRACK),
|
||||
TRACK_CLEAR("clear", PermissionGroup.TRACK);
|
||||
TRACK_INFO("info", "track"),
|
||||
TRACK_APPEND("append", "track"),
|
||||
TRACK_INSERT("insert", "track"),
|
||||
TRACK_REMOVE("remove", "track"),
|
||||
TRACK_CLEAR("clear", "track");
|
||||
|
||||
private String node;
|
||||
private PermissionGroup group;
|
||||
private String group;
|
||||
|
||||
public boolean isAuthorized(Sender sender) {
|
||||
if (sender.hasPermission("luckperms.*")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (group != null) {
|
||||
return group.isAuthorized(sender) || sender.hasPermission("luckperms." + group.getNode() + "." + node);
|
||||
return sender.hasPermission("luckperms." + group + "." + node);
|
||||
}
|
||||
|
||||
return sender.hasPermission("luckperms." + node);
|
||||
}
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
private enum PermissionGroup {
|
||||
USER("user"),
|
||||
GROUP("group"),
|
||||
TRACK("track");
|
||||
|
||||
private String node;
|
||||
|
||||
private boolean isAuthorized(Sender sender) {
|
||||
return sender.hasPermission("luckperms." + node + ".*");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ public class Group extends PermissionHolder {
|
||||
*/
|
||||
private List<String> getGroups(String server, String world, boolean includeGlobal) {
|
||||
// Call super #getPermissions method, and just sort through those
|
||||
Map<String, Boolean> perms = getPermissions(server, world, null, includeGlobal);
|
||||
Map<String, Boolean> perms = getPermissions(server, world, null, includeGlobal, null);
|
||||
return perms.keySet().stream()
|
||||
.filter(s -> Patterns.GROUP_MATCH.matcher(s).matches())
|
||||
.map(s -> Patterns.DOT.split(s, 2)[1])
|
||||
|
||||
@@ -313,7 +313,7 @@ public abstract class User extends PermissionHolder {
|
||||
*/
|
||||
private List<String> getGroups(String server, String world, boolean includeGlobal) {
|
||||
// Call super #getPermissions method, and just sort through those
|
||||
Map<String, Boolean> perms = getPermissions(server, world, null, includeGlobal);
|
||||
Map<String, Boolean> perms = getPermissions(server, world, null, includeGlobal, null);
|
||||
return perms.keySet().stream()
|
||||
.filter(s -> Patterns.GROUP_MATCH.matcher(s).matches())
|
||||
.map(s -> Patterns.DOT.split(s, 2)[1])
|
||||
|
||||
@@ -88,6 +88,10 @@ public abstract class LPConfiguration<T extends LuckPermsPlugin> {
|
||||
return getBoolean("online-mode", true);
|
||||
}
|
||||
|
||||
public boolean getApplyWildcards() {
|
||||
return getBoolean("apply-wildcards", true);
|
||||
}
|
||||
|
||||
public MySQLConfiguration getDatabaseValues() {
|
||||
return new MySQLConfiguration(
|
||||
getString("sql.address", null),
|
||||
|
||||
@@ -396,6 +396,18 @@ public abstract class PermissionHolder {
|
||||
unsetPermission(server + "-" + world + "/" + node, temporary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server
|
||||
* @param server The server to get nodes for
|
||||
* @param world The world to get nodes for
|
||||
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
|
||||
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
|
||||
* @return a {@link Map} of the permissions
|
||||
*/
|
||||
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups, List<String> possibleNodes) {
|
||||
return getPermissions(server, world, excludedGroups, plugin.getConfiguration().getIncludeGlobalPerms(), possibleNodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server
|
||||
* @param server The server to get nodes for
|
||||
@@ -404,7 +416,18 @@ public abstract class PermissionHolder {
|
||||
* @return a {@link Map} of the permissions
|
||||
*/
|
||||
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups) {
|
||||
return getPermissions(server, world, excludedGroups, plugin.getConfiguration().getIncludeGlobalPerms());
|
||||
return getPermissions(server, world, excludedGroups, plugin.getConfiguration().getIncludeGlobalPerms(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server
|
||||
* @param server The server to get nodes for
|
||||
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
|
||||
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
|
||||
* @return a {@link Map} of the permissions
|
||||
*/
|
||||
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups, List<String> possibleNodes) {
|
||||
return getLocalPermissions(server, null, excludedGroups, possibleNodes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -414,7 +437,7 @@ public abstract class PermissionHolder {
|
||||
* @return a {@link Map} of the permissions
|
||||
*/
|
||||
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups) {
|
||||
return getLocalPermissions(server, null, excludedGroups);
|
||||
return getLocalPermissions(server, null, excludedGroups, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -468,7 +491,7 @@ public abstract class PermissionHolder {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
protected Map<String, Boolean> getPermissions(String server, String world, List<String> excludedGroups, boolean includeGlobal) {
|
||||
protected Map<String, Boolean> getPermissions(String server, String world, List<String> excludedGroups, boolean includeGlobal, List<String> possibleNodes) {
|
||||
if (excludedGroups == null) {
|
||||
excludedGroups = new ArrayList<>();
|
||||
}
|
||||
@@ -643,9 +666,61 @@ public abstract class PermissionHolder {
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.getConfiguration().getApplyWildcards()) {
|
||||
if (possibleNodes != null && !possibleNodes.isEmpty()) {
|
||||
return applyWildcards(perms, possibleNodes);
|
||||
}
|
||||
return applyWildcards(perms, plugin.getPossiblePermissions());
|
||||
}
|
||||
|
||||
return perms;
|
||||
}
|
||||
|
||||
private Map<String, Boolean> applyWildcards(Map<String, Boolean> input, List<String> possibleNodes) {
|
||||
// Add all group nodes, so wildcard group.* and '*' can apply.
|
||||
plugin.getGroupManager().getGroups().keySet().forEach(s -> possibleNodes.add("group." + s));
|
||||
|
||||
SortedMap<Integer, Map<String, Boolean>> wildcards = new TreeMap<>(Collections.reverseOrder());
|
||||
for (Map.Entry<String, Boolean> e : input.entrySet()) {
|
||||
if (e.getKey().equals("*") || e.getKey().equals("'*'")) {
|
||||
wildcards.put(0, Collections.singletonMap("*", e.getValue()));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!e.getKey().endsWith(".*")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String node = e.getKey().substring(0, e.getKey().length() - 2);
|
||||
final String[] parts = Patterns.DOT.split(node);
|
||||
|
||||
if (!wildcards.containsKey(parts.length)) {
|
||||
wildcards.put(parts.length, new HashMap<>());
|
||||
}
|
||||
|
||||
wildcards.get(parts.length).put(node, e.getValue());
|
||||
}
|
||||
|
||||
for (Map.Entry<Integer, Map<String, Boolean>> e : wildcards.entrySet()) {
|
||||
if (e.getKey() == 0) {
|
||||
// Apply all permissions
|
||||
possibleNodes.stream()
|
||||
.filter(n -> !input.containsKey(n)) // Don't override existing nodes
|
||||
.forEach(n -> input.put(n, e.getValue().get("*")));
|
||||
break;
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Boolean> wc : e.getValue().entrySet()) {
|
||||
possibleNodes.stream()
|
||||
.filter(n -> n.startsWith(wc.getKey() + ".")) // Only nodes that match the wildcard are applied
|
||||
.filter(n -> !input.containsKey(n)) // Don't override existing nodes
|
||||
.forEach(n -> input.put(n, wc.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
private static String stripTime(String s) {
|
||||
if (s.contains("$")) {
|
||||
return Patterns.TEMP_DELIMITER.split(s)[0];
|
||||
|
||||
Reference in New Issue
Block a user