Implement basic permission system

This commit is contained in:
KingRainbow44 2022-04-18 23:46:04 -04:00
parent 93a6914261
commit 824b3a4bf4
5 changed files with 80 additions and 14 deletions

View File

@ -13,7 +13,7 @@ public @interface Command {
Execution execution() default Execution.ALL;
int gmLevel() default 1;
String permission() default "";
enum Execution {
ALL,

View File

@ -1,6 +1,7 @@
package emu.grasscutter.commands;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.Account;
import emu.grasscutter.game.GenshinPlayer;
import org.reflections.Reflections;
@ -13,7 +14,7 @@ public final class CommandMap {
}
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.
@ -26,14 +27,14 @@ public final class CommandMap {
// Get command data.
Command annotation = command.getClass().getAnnotation(Command.class);
this.executionPower.put(label, annotation.execution());
this.annotations.put(label, annotation);
this.commands.put(label, command);
// Register aliases.
if(annotation.aliases().length > 0) {
for (String alias : annotation.aliases()) {
this.commands.put(alias, command);
this.executionPower.put(alias, annotation.execution());
this.annotations.put(alias, annotation);
}
} return this;
}
@ -49,14 +50,14 @@ public final class CommandMap {
if(handler == null) return this;
Command annotation = handler.getClass().getAnnotation(Command.class);
this.executionPower.remove(label);
this.annotations.remove(label);
this.commands.remove(label);
// Unregister aliases.
if(annotation.aliases().length > 0) {
for (String alias : annotation.aliases()) {
this.commands.remove(alias);
this.executionPower.remove(alias);
this.annotations.remove(alias);
}
}
@ -106,8 +107,18 @@ public final class CommandMap {
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.
Command.Execution executionPower = this.executionPower.get(label);
Command.Execution executionPower = this.annotations.get(label).execution();
if(player == null && executionPower == Command.Execution.PLAYER) {
CommandHandler.sendMessage(null, "Run this command in-game."); return;
} else if (player != null && executionPower == Command.Execution.CONSOLE) {

View File

@ -109,7 +109,10 @@ public final class ServerCommands {
Account account = DatabaseHelper.createAccountWithId(username, uid);
if(account == null) {
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;
case "delete":
if(DatabaseHelper.deleteAccount(username)) {
@ -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",
usage = "Usage: help [command]")
public static class HelpCommand implements CommandHandler {

View File

@ -9,6 +9,8 @@ import emu.grasscutter.utils.Crypto;
import emu.grasscutter.utils.Utils;
import dev.morphia.annotations.IndexOptions;
import java.util.List;
@Entity(value = "accounts", noClassnameStored = true)
public class Account {
@Id private String id;
@ -23,6 +25,7 @@ public class Account {
private String token;
private String sessionKey; // Session token for dispatch server
private List<String> permissions;
@Deprecated
public Account() {}
@ -84,6 +87,22 @@ public class Account {
this.save();
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
public String generateLoginToken() {

View File

@ -1,11 +1,6 @@
package emu.grasscutter.game;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.*;
import dev.morphia.annotations.*;
import emu.grasscutter.GenshinConstants;