diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java index 1e6ab17a..5f9cdc49 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java @@ -50,7 +50,9 @@ public void invoke(String... args) { if (client.trustLevel != null) { logger.info("trustLevel | key {} | pubkey {}", client.trustLevel.keyChecked ? "checked" : "unchecked", client.trustLevel.publicKey == null ? "null" : new String(Base64.getEncoder().encode(client.trustLevel.publicKey))); } - logger.info("Permissions: {} (permissions {} | flags {})", client.permissions == null ? "null" : client.permissions.toString(), client.permissions == null ? 0 : client.permissions.permissions, client.permissions == null ? 0 : client.permissions.flags); + if (client.permissions != null) { + logger.info("Permissions: {}", client.permissions.toString()); + } } })); } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AdditionalDataResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AdditionalDataResponse.java index 0414279a..874e031c 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AdditionalDataResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AdditionalDataResponse.java @@ -12,6 +12,7 @@ import java.util.Map; import java.util.UUID; +@SuppressWarnings("deprecation") public class AdditionalDataResponse extends SimpleResponse { public String username; public UUID uuid; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java index 7ccdeff2..7b196f1d 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java @@ -2,7 +2,6 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; -import pro.gravit.launcher.ClientPermissions; import pro.gravit.launcher.events.RequestEvent; import pro.gravit.launcher.events.request.ExitRequestEvent; import pro.gravit.launchserver.LaunchServer; @@ -35,7 +34,7 @@ public String getType() { @Override public void execute(ChannelHandlerContext ctx, Client client) { - if (username != null && (!client.isAuth || client.permissions == null || !client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN))) { + if (username != null && (!client.isAuth || client.permissions == null || !client.permissions.hasAction("launchserver\\.management\\.kick"))) { sendError("Permissions denied"); return; } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/PingServerReportResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/PingServerReportResponse.java index e2bcd34f..88b18396 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/PingServerReportResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/PingServerReportResponse.java @@ -1,7 +1,6 @@ package pro.gravit.launchserver.socket.response.management; import io.netty.channel.ChannelHandlerContext; -import pro.gravit.launcher.ClientPermissions; import pro.gravit.launcher.events.request.PingServerReportRequestEvent; import pro.gravit.launcher.request.management.PingServerReportRequest; import pro.gravit.launchserver.socket.Client; @@ -18,7 +17,7 @@ public String getType() { @Override public void execute(ChannelHandlerContext ctx, Client client) { - if (!client.isAuth || client.permissions == null || !client.permissions.isPermission(ClientPermissions.PermissionConsts.MANAGEMENT)) { + if (!client.isAuth || client.permissions == null || !client.permissions.hasAction("launchserver\\.management\\.pingserver")) { sendError("Access denied"); return; } diff --git a/Launcher/src/main/java/pro/gravit/launcher/api/AuthService.java b/Launcher/src/main/java/pro/gravit/launcher/api/AuthService.java index 225cee08..1a1c0818 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/api/AuthService.java +++ b/Launcher/src/main/java/pro/gravit/launcher/api/AuthService.java @@ -11,7 +11,7 @@ public class AuthService { public static UUID uuid; public static ClientProfile profile; - public static boolean isAdmin() { - return permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN); + public static boolean hasPermission(String permission) { + return permissions.hasAction(permission); } } diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/ClientPermissions.java b/LauncherAPI/src/main/java/pro/gravit/launcher/ClientPermissions.java index cdf2d3a7..d61f6d6c 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/ClientPermissions.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/ClientPermissions.java @@ -3,13 +3,25 @@ import pro.gravit.launcher.serialize.HInput; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; public class ClientPermissions { public static final ClientPermissions DEFAULT = new ClientPermissions(); @LauncherNetworkAPI + @Deprecated public long permissions; @LauncherNetworkAPI + @Deprecated public long flags; + @LauncherNetworkAPI + private List roles; + @LauncherNetworkAPI + private List actions; + + private transient List available; public ClientPermissions(HInput input) throws IOException { this(input.readLong()); @@ -31,6 +43,7 @@ public ClientPermissions(long permissions, long flags) { public static ClientPermissions getSuperuserAccount() { ClientPermissions perm = new ClientPermissions(); perm.setPermission(PermissionConsts.ADMIN, true); + perm.addAction("*"); return perm; } @@ -38,39 +51,102 @@ public long toLong() { return permissions; } + public boolean hasRole(String role) { + return roles != null && roles.contains(role); + } + + public synchronized void compile() { + if (available != null) { + return; + } + available = new ArrayList<>(actions.size()); + for (String a : actions) { + available.add(Pattern.compile(a)); + } + if (permissions != 0) { + if (isPermission(PermissionConsts.ADMIN)) { + roles.add("ADMIN"); + available.add(Pattern.compile(".*")); + } + } + } + + public boolean hasAction(String action) { + if (available == null) { + compile(); + } + for (Pattern p : available) { + if (p.matcher(action).matches()) { + return true; + } + } + return false; + } + + public void addRole(String role) { + if (roles == null) { + roles = new ArrayList<>(1); + } + roles.add(role); + } + + public void addAction(String action) { + if (actions == null) { + actions = new ArrayList<>(); + } + actions.add(action); + available.add(Pattern.compile(action)); + } + + public List getRoles() { + return roles; + } + + public List getActions() { + return actions; + } + //Read methods + @Deprecated public final boolean isPermission(PermissionConsts con) { return (permissions & con.mask) != 0; } + @Deprecated public final boolean isPermission(long mask) { return (permissions & mask) != 0; } + @Deprecated public final boolean isFlag(FlagConsts con) { return (flags & con.mask) != 0; } + @Deprecated public final boolean isFlag(long mask) { return (flags & mask) != 0; } //Write methods + @Deprecated public final void setPermission(PermissionConsts con, boolean value) { if (value) this.permissions |= con.mask; else this.permissions &= ~con.mask; } + @Deprecated public final void setPermission(long mask, boolean value) { if (value) this.permissions |= mask; else this.permissions &= ~mask; } + @Deprecated public final void setFlag(FlagConsts con, boolean value) { if (value) this.flags |= con.mask; else this.flags &= ~con.mask; } + @Deprecated public final void setFlag(long mask, boolean value) { if (value) this.flags |= mask; else this.flags &= ~mask; @@ -78,12 +154,19 @@ public final void setFlag(long mask, boolean value) { @Override public String toString() { + if (roles != null || actions != null) { + return "ClientPermissions{" + + "roles=" + String.join(", ", roles == null ? Collections.emptyList() : roles) + + ", actions=" + String.join(", ", actions == null ? Collections.emptyList() : actions) + + '}'; + } return "ClientPermissions{" + "permissions=" + permissions + ", flags=" + flags + '}'; } + @Deprecated public enum PermissionConsts { ADMIN(0x01), MANAGEMENT(0x02); @@ -94,7 +177,7 @@ public enum PermissionConsts { } } - + @Deprecated public enum FlagConsts { SYSTEM(0x01), BANNED(0x02),