Commit 824b3a4b authored by KingRainbow44's avatar KingRainbow44
Browse files

Implement basic permission system

parent 93a69142
...@@ -13,7 +13,7 @@ public @interface Command { ...@@ -13,7 +13,7 @@ public @interface Command {
Execution execution() default Execution.ALL; Execution execution() default Execution.ALL;
int gmLevel() default 1; String permission() default "";
enum Execution { enum Execution {
ALL, ALL,
......
package emu.grasscutter.commands; package emu.grasscutter.commands;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.Account;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import org.reflections.Reflections; import org.reflections.Reflections;
...@@ -13,7 +14,7 @@ public final class CommandMap { ...@@ -13,7 +14,7 @@ public final class CommandMap {
} }
private final Map<String, CommandHandler> commands = new HashMap<>(); private final Map<String, CommandHandler> commands = new HashMap<>();
private final Map<String, Command.Execution> executionPower = new HashMap<>(); private final Map<String, Command> annotations = new HashMap<>();
/** /**
* Register a command handler. * Register a command handler.
...@@ -26,14 +27,14 @@ public final class CommandMap { ...@@ -26,14 +27,14 @@ public final class CommandMap {
// Get command data. // Get command data.
Command annotation = command.getClass().getAnnotation(Command.class); Command annotation = command.getClass().getAnnotation(Command.class);
this.executionPower.put(label, annotation.execution()); this.annotations.put(label, annotation);
this.commands.put(label, command); this.commands.put(label, command);
// Register aliases. // Register aliases.
if(annotation.aliases().length > 0) { if(annotation.aliases().length > 0) {
for (String alias : annotation.aliases()) { for (String alias : annotation.aliases()) {
this.commands.put(alias, command); this.commands.put(alias, command);
this.executionPower.put(alias, annotation.execution()); this.annotations.put(alias, annotation);
} }
} return this; } return this;
} }
...@@ -49,14 +50,14 @@ public final class CommandMap { ...@@ -49,14 +50,14 @@ public final class CommandMap {
if(handler == null) return this; if(handler == null) return this;
Command annotation = handler.getClass().getAnnotation(Command.class); Command annotation = handler.getClass().getAnnotation(Command.class);
this.executionPower.remove(label); this.annotations.remove(label);
this.commands.remove(label); this.commands.remove(label);
// Unregister aliases. // Unregister aliases.
if(annotation.aliases().length > 0) { if(annotation.aliases().length > 0) {
for (String alias : annotation.aliases()) { for (String alias : annotation.aliases()) {
this.commands.remove(alias); this.commands.remove(alias);
this.executionPower.remove(alias); this.annotations.remove(alias);
} }
} }
...@@ -106,8 +107,18 @@ public final class CommandMap { ...@@ -106,8 +107,18 @@ public final class CommandMap {
CommandHandler.sendMessage(player, "Unknown command: " + label); return; CommandHandler.sendMessage(player, "Unknown command: " + label); return;
} }
// Check for permission.
if(player != null) {
String permissionNode = this.annotations.get(label).permission();
Account account = player.getAccount();
List<String> permissions = account.getPermissions();
if(!permissions.contains("*") && !permissions.contains(permissionNode)) {
CommandHandler.sendMessage(player, "You do not have permission to run this command."); return;
}
}
// Execution power check. // Execution power check.
Command.Execution executionPower = this.executionPower.get(label); Command.Execution executionPower = this.annotations.get(label).execution();
if(player == null && executionPower == Command.Execution.PLAYER) { if(player == null && executionPower == Command.Execution.PLAYER) {
CommandHandler.sendMessage(null, "Run this command in-game."); return; CommandHandler.sendMessage(null, "Run this command in-game."); return;
} else if (player != null && executionPower == Command.Execution.CONSOLE) { } else if (player != null && executionPower == Command.Execution.CONSOLE) {
......
...@@ -109,7 +109,10 @@ public final class ServerCommands { ...@@ -109,7 +109,10 @@ public final class ServerCommands {
Account account = DatabaseHelper.createAccountWithId(username, uid); Account account = DatabaseHelper.createAccountWithId(username, uid);
if(account == null) { if(account == null) {
CommandHandler.sendMessage(null, "Account already exists."); return; CommandHandler.sendMessage(null, "Account already exists."); return;
} else CommandHandler.sendMessage(null, "Account created with UID " + account.getPlayerId() + "."); } else {
CommandHandler.sendMessage(null, "Account created with UID " + account.getPlayerId() + ".");
account.addPermission("*"); // Grant the player superuser permissions.
}
return; return;
case "delete": case "delete":
if(DatabaseHelper.deleteAccount(username)) { if(DatabaseHelper.deleteAccount(username)) {
...@@ -120,6 +123,44 @@ public final class ServerCommands { ...@@ -120,6 +123,44 @@ public final class ServerCommands {
} }
} }
@Command(label = "permission",
usage = "Usage: permission <add|remove> <username> <permission>",
execution = Command.Execution.CONSOLE)
public static class PermissionCommand implements CommandHandler {
@Override
public void execute(List<String> args) {
if(args.size() < 3) {
CommandHandler.sendMessage(null, "Usage: permission <add|remove> <username> <permission>"); return;
}
String action = args.get(0);
String username = args.get(1);
String permission = args.get(2);
Account account = DatabaseHelper.getAccountByName(username);
if(account == null) {
CommandHandler.sendMessage(null, "Account not found."); return;
}
switch(action) {
default:
CommandHandler.sendMessage(null, "Usage: permission <add|remove> <username> <permission>");
return;
case "add":
if(account.addPermission(permission)) {
CommandHandler.sendMessage(null, "Permission added."); return;
} else CommandHandler.sendMessage(null, "They already have this permission!");
return;
case "remove":
if(account.removePermission(permission)) {
CommandHandler.sendMessage(null, "Permission removed."); return;
} else CommandHandler.sendMessage(null, "They don't have this permission!");
return;
}
}
}
@Command(label = "help", @Command(label = "help",
usage = "Usage: help [command]") usage = "Usage: help [command]")
public static class HelpCommand implements CommandHandler { public static class HelpCommand implements CommandHandler {
......
...@@ -9,6 +9,8 @@ import emu.grasscutter.utils.Crypto; ...@@ -9,6 +9,8 @@ import emu.grasscutter.utils.Crypto;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import dev.morphia.annotations.IndexOptions; import dev.morphia.annotations.IndexOptions;
import java.util.List;
@Entity(value = "accounts", noClassnameStored = true) @Entity(value = "accounts", noClassnameStored = true)
public class Account { public class Account {
@Id private String id; @Id private String id;
...@@ -23,6 +25,7 @@ public class Account { ...@@ -23,6 +25,7 @@ public class Account {
private String token; private String token;
private String sessionKey; // Session token for dispatch server private String sessionKey; // Session token for dispatch server
private List<String> permissions;
@Deprecated @Deprecated
public Account() {} public Account() {}
...@@ -84,6 +87,22 @@ public class Account { ...@@ -84,6 +87,22 @@ public class Account {
this.save(); this.save();
return this.sessionKey; return this.sessionKey;
} }
/**
* The collection of a player's permissions.
*/
public List<String> getPermissions() {
return this.permissions;
}
public boolean addPermission(String permission) {
if(this.permissions.contains(permission)) return false;
this.permissions.add(permission); return true;
}
public boolean removePermission(String permission) {
return this.permissions.remove(permission);
}
// TODO make unique // TODO make unique
public String generateLoginToken() { public String generateLoginToken() {
......
package emu.grasscutter.game; package emu.grasscutter.game;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import dev.morphia.annotations.*; import dev.morphia.annotations.*;
import emu.grasscutter.GenshinConstants; import emu.grasscutter.GenshinConstants;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment