From 53f048ac86d45a5942b2bfe33b476fc197c448c6 Mon Sep 17 00:00:00 2001 From: PssbleTrngle Date: Tue, 21 Jun 2022 11:44:17 +0200 Subject: [PATCH 1/4] add fabric-permissions & luckperms provider --- fabric-1.19/build.gradle | 8 ++ .../org/dynmap/fabric_1_19/DynmapPlugin.java | 16 ++- .../permissions/FabricPermissions.java | 47 ++++++++ .../permissions/LuckPermissions.java | 102 ++++++++++++++++++ 4 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FabricPermissions.java create mode 100644 fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java diff --git a/fabric-1.19/build.gradle b/fabric-1.19/build.gradle index 5d6eea4a..0b0194f6 100644 --- a/fabric-1.19/build.gradle +++ b/fabric-1.19/build.gradle @@ -18,6 +18,11 @@ configurations { implementation.extendsFrom(shadow) } +repositories { + mavenCentral() + maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } +} + dependencies { minecraft "com.mojang:minecraft:${project.minecraft_version}" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" @@ -27,6 +32,9 @@ dependencies { compileOnly group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.2' shadow project(path: ':DynmapCore', configuration: 'shadow') + + modCompileOnly "me.lucko:fabric-permissions-api:0.1-SNAPSHOT" + compileOnly 'net.luckperms:api:5.4' } processResources { diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapPlugin.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapPlugin.java index 7c265749..5bb6c754 100644 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapPlugin.java +++ b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapPlugin.java @@ -396,9 +396,19 @@ public class DynmapPlugin { registerPlayerLoginListener(); /* Initialize permissions handler */ - permissions = FilePermissions.create(); - if (permissions == null) { - permissions = new OpPermissions(new String[]{"webchat", "marker.icons", "marker.list", "webregister", "stats", "hide.self", "show.self"}); + if (FabricLoader.getInstance().isModLoaded("luckperms")) { + Log.info("Using luckperms for access control"); + permissions = new LuckPermissions(); + } + else if (FabricLoader.getInstance().isModLoaded("fabric-permissions-api-v0")) { + Log.info("Using fabric-permissions-api for access control"); + permissions = new FabricPermissions(); + } else { + /* Initialize permissions handler */ + permissions = FilePermissions.create(); + if (permissions == null) { + permissions = new OpPermissions(new String[]{"webchat", "marker.icons", "marker.list", "webregister", "stats", "hide.self", "show.self"}); + } } /* Get and initialize data folder */ File dataDirectory = new File("dynmap"); diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FabricPermissions.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FabricPermissions.java new file mode 100644 index 00000000..c572acc4 --- /dev/null +++ b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FabricPermissions.java @@ -0,0 +1,47 @@ +package org.dynmap.fabric_1_18_2.permissions; + +import me.lucko.fabric.api.permissions.v0.Permissions; +import net.minecraft.entity.player.PlayerEntity; +import org.dynmap.Log; +import org.dynmap.fabric_1_18_2.DynmapPlugin; +import org.dynmap.json.simple.parser.JSONParser; + +import java.util.Set; +import java.util.stream.Collectors; + +public class FabricPermissions implements PermissionProvider { + + private String permissionKey(String perm) { + return "dynmap." + perm; + } + + @Override + public Set hasOfflinePermissions(String player, Set perms) { + return perms.stream() + .filter(perm -> hasOfflinePermission(player, perm)) + .collect(Collectors.toSet()); + } + + @Override + public boolean hasOfflinePermission(String player, String perm) { + return DynmapPlugin.plugin.isOp(player.toLowerCase()); + } + + @Override + public boolean has(PlayerEntity player, String permission) { + if (player == null) return false; + String name = player.getName().getString().toLowerCase(); + if (DynmapPlugin.plugin.isOp(name)) return true; + return Permissions.check(player, permissionKey(permission)); + } + + @Override + public boolean hasPermissionNode(PlayerEntity player, String permission) { + if (player != null) { + String name = player.getName().getString().toLowerCase(); + return DynmapPlugin.plugin.isOp(name); + } + return false; + } + +} diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java new file mode 100644 index 00000000..829c8a80 --- /dev/null +++ b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java @@ -0,0 +1,102 @@ +package org.dynmap.fabric_1_18_2.permissions; + +import me.lucko.fabric.api.permissions.v0.Permissions; +import net.luckperms.api.LuckPerms; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.cacheddata.CachedPermissionData; +import net.luckperms.api.model.user.User; +import net.luckperms.api.util.Tristate; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.MinecraftServer; +import org.dynmap.Log; +import org.dynmap.fabric_1_18_2.DynmapPlugin; +import org.dynmap.json.simple.JSONArray; +import org.dynmap.json.simple.JSONObject; +import org.dynmap.json.simple.parser.JSONParser; +import org.dynmap.json.simple.parser.ParseException; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +public class LuckPermissions implements PermissionProvider { + + private final JSONParser parser = new JSONParser(); + private LuckPerms api = null; + + private Optional getApi() { + if (api != null) return Optional.of(api); + try { + api = LuckPermsProvider.get(); + return Optional.of(api); + } catch (Exception ex) { + Log.warning("Trying to access LuckPerms before it has loaded"); + return Optional.empty(); + } + } + + private Optional cachedUUID(String username) { + try { + BufferedReader reader = new BufferedReader(new FileReader(MinecraftServer.USER_CACHE_FILE)); + JSONArray cache = (JSONArray) parser.parse(reader); + for (Object it : cache) { + JSONObject user = (JSONObject) it; + if (user.get("name").toString().equalsIgnoreCase(username)) { + String uuid = user.get("uuid").toString(); + return Optional.of(UUID.fromString(uuid)); + } + } + + reader.close(); + } catch (IOException | ParseException ex) { + Log.warning("Unable to read usercache.json"); + } + + return Optional.empty(); + } + + private String permissionKey(String perm) { + return "dynmap." + perm; + } + + @Override + public Set hasOfflinePermissions(String player, Set perms) { + return perms.stream() + .filter(perm -> hasOfflinePermission(player, perm)) + .collect(Collectors.toSet()); + } + + @Override + public boolean hasOfflinePermission(String player, String perm) { + if (DynmapPlugin.plugin.isOp(player.toLowerCase())) return true; + Optional api = getApi(); + Optional uuid = cachedUUID(player); + if (!uuid.isPresent() || !api.isPresent()) return false; + User user = api.get().getUserManager().loadUser(uuid.get()).join(); + CachedPermissionData permissions = user.getCachedData().getPermissionData(); + Tristate state = permissions.checkPermission(permissionKey(perm)); + return state.asBoolean(); + } + + @Override + public boolean has(PlayerEntity player, String permission) { + if (player == null) return false; + String name = player.getName().getString().toLowerCase(); + if (DynmapPlugin.plugin.isOp(name)) return true; + return Permissions.check(player, permissionKey(permission)); + } + + @Override + public boolean hasPermissionNode(PlayerEntity player, String permission) { + if (player != null) { + String name = player.getName().getString().toLowerCase(); + return DynmapPlugin.plugin.isOp(name); + } + return false; + } + +} From 9f865fa5bd179b685df1537ba1b807b1bd85dc2f Mon Sep 17 00:00:00 2001 From: PssbleTrngle Date: Tue, 21 Jun 2022 11:51:08 +0200 Subject: [PATCH 2/4] fix imports --- .../org/dynmap/fabric_1_19/permissions/FabricPermissions.java | 4 ++-- .../org/dynmap/fabric_1_19/permissions/LuckPermissions.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FabricPermissions.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FabricPermissions.java index c572acc4..270ff000 100644 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FabricPermissions.java +++ b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/FabricPermissions.java @@ -1,9 +1,9 @@ -package org.dynmap.fabric_1_18_2.permissions; +package org.dynmap.fabric_1_19.permissions; import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.entity.player.PlayerEntity; import org.dynmap.Log; -import org.dynmap.fabric_1_18_2.DynmapPlugin; +import org.dynmap.fabric_1_19.DynmapPlugin; import org.dynmap.json.simple.parser.JSONParser; import java.util.Set; diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java index 829c8a80..737e162b 100644 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java +++ b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_18_2.permissions; +package org.dynmap.fabric_1_19.permissions; import me.lucko.fabric.api.permissions.v0.Permissions; import net.luckperms.api.LuckPerms; @@ -9,7 +9,7 @@ import net.luckperms.api.util.Tristate; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.MinecraftServer; import org.dynmap.Log; -import org.dynmap.fabric_1_18_2.DynmapPlugin; +import org.dynmap.fabric_1_19.DynmapPlugin; import org.dynmap.json.simple.JSONArray; import org.dynmap.json.simple.JSONObject; import org.dynmap.json.simple.parser.JSONParser; From c25945ea13107db6a734218abb27dd17604f127d Mon Sep 17 00:00:00 2001 From: PssbleTrngle Date: Tue, 21 Jun 2022 12:06:26 +0200 Subject: [PATCH 3/4] add missing import --- .../main/java/org/dynmap/fabric_1_19/DynmapPlugin.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapPlugin.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapPlugin.java index 5bb6c754..f209550b 100644 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapPlugin.java +++ b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/DynmapPlugin.java @@ -3,10 +3,10 @@ package org.dynmap.fabric_1_19; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.FluidBlock; @@ -30,9 +30,6 @@ import net.minecraft.world.WorldAccess; import net.minecraft.world.biome.Biome; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.ChunkSection; -import net.minecraft.world.chunk.ChunkStatus; -import net.minecraft.world.chunk.WorldChunk; - import org.dynmap.*; import org.dynmap.common.BiomeMap; import org.dynmap.common.DynmapCommandSender; @@ -48,9 +45,7 @@ import org.dynmap.fabric_1_19.event.CustomServerChunkEvents; import org.dynmap.fabric_1_19.event.CustomServerLifecycleEvents; import org.dynmap.fabric_1_19.event.PlayerEvents; import org.dynmap.fabric_1_19.mixin.BiomeEffectsAccessor; -import org.dynmap.fabric_1_19.permissions.FilePermissions; -import org.dynmap.fabric_1_19.permissions.OpPermissions; -import org.dynmap.fabric_1_19.permissions.PermissionProvider; +import org.dynmap.fabric_1_19.permissions.*; import org.dynmap.permissions.PermissionsHandler; import org.dynmap.renderer.DynmapBlockState; From 3b1cbdca0915da36608d43a73530ca8017d28925 Mon Sep 17 00:00:00 2001 From: PssbleTrngle Date: Tue, 21 Jun 2022 12:07:48 +0200 Subject: [PATCH 4/4] usercache filename --- .../org/dynmap/fabric_1_19/permissions/LuckPermissions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java index 737e162b..143fa7bf 100644 --- a/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java +++ b/fabric-1.19/src/main/java/org/dynmap/fabric_1_19/permissions/LuckPermissions.java @@ -41,7 +41,7 @@ public class LuckPermissions implements PermissionProvider { private Optional cachedUUID(String username) { try { - BufferedReader reader = new BufferedReader(new FileReader(MinecraftServer.USER_CACHE_FILE)); + BufferedReader reader = new BufferedReader(new FileReader("usercache.json")); JSONArray cache = (JSONArray) parser.parse(reader); for (Object it : cache) { JSONObject user = (JSONObject) it;