From 881132857152a92d997e8750d2b1510f2d891d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Thu, 5 Dec 2024 12:46:51 +0100 Subject: [PATCH] implemented working WhitelistRepository --- .../java/eu/mhsl/craftattack/spawn/Main.java | 8 ++- .../spawn/api/client/HttpRepository.java | 32 ++++----- .../spawn/api/client/Repository.java | 2 +- .../spawn/api/client/RepositoryLoader.java | 15 +++- .../craftattack/spawn/api/client/ReqResp.java | 4 ++ .../client/repositories/ReportRepository.java | 5 +- .../repositories/WhitelistRepository.java | 30 ++++++++ .../spawn/appliances/report/Report.java | 5 +- .../spawn/appliances/whitelist/Whitelist.java | 68 ++++++------------- .../craftattack/spawn/util/api/ApiUtil.java | 14 ++-- .../spawn/util/api/HttpStatus.java | 14 ++++ src/main/resources/config.yml | 4 +- 12 files changed, 118 insertions(+), 83 deletions(-) create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/api/client/ReqResp.java create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/api/client/repositories/WhitelistRepository.java create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/util/api/HttpStatus.java diff --git a/src/main/java/eu/mhsl/craftattack/spawn/Main.java b/src/main/java/eu/mhsl/craftattack/spawn/Main.java index d6ff55d..edb907b 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/Main.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/Main.java @@ -20,7 +20,7 @@ public final class Main extends JavaPlugin { private static Logger logger; private List appliances; - private final RepositoryLoader repositoryLoader = new RepositoryLoader(); + private RepositoryLoader repositoryLoader; @Override public void onEnable() { @@ -39,7 +39,11 @@ public final class Main extends JavaPlugin { Configuration.readConfig(); List disabledAppliances = Configuration.pluginConfig.getStringList("disabledAppliances"); - Main.logger.info("Loading appliances..."); + Main.logger().info("Loading Repositories..."); + this.repositoryLoader = new RepositoryLoader(); + Main.logger().info(String.format("Loaded %d repositories!", this.repositoryLoader.getRepositories().size())); + + Main.logger().info("Loading appliances..."); Reflections reflections = new Reflections(this.getClass().getPackageName()); Set> applianceClasses = reflections.getSubTypesOf(Appliance.class); diff --git a/src/main/java/eu/mhsl/craftattack/spawn/api/client/HttpRepository.java b/src/main/java/eu/mhsl/craftattack/spawn/api/client/HttpRepository.java index f470c7c..963c3a0 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/api/client/HttpRepository.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/api/client/HttpRepository.java @@ -12,7 +12,8 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.util.function.Consumer; -public class HttpRepository extends Repository { +@RepositoryLoader.IgnoreRepository +public abstract class HttpRepository extends Repository { private final Consumer baseUriBuilder; public HttpRepository(URI basePath) { @@ -26,29 +27,26 @@ public class HttpRepository extends Repository { : baseUriBuilder; } - public record RequestResponse(int status, TData data) { + protected ReqResp post(String command, TInput data, Class outputType) { + return this.post(command, parameters -> {}, data, outputType); } - - protected RequestResponse post(String command, TInput data, Class clazz) { - return this.post(command, parameters -> {}, data, clazz); - } - protected RequestResponse post(String command, Consumer parameters, TInput data, Class clazz) { + protected ReqResp post(String command, Consumer parameters, TInput data, Class outputType) { HttpRequest request = this.getRequestBuilder(this.getUri(command, parameters)) .POST(HttpRequest.BodyPublishers.ofString(this.gson.toJson(data))) .build(); - return this.execute(request, clazz); + return this.execute(request, outputType); } - protected RequestResponse get(String command, Class clazz) { - return this.get(command, parameters -> {}, clazz); + protected ReqResp get(String command, Class outputType) { + return this.get(command, parameters -> {}, outputType); } - protected RequestResponse get(String command, Consumer parameters, Class clazz) { + protected ReqResp get(String command, Consumer parameters, Class outputType) { HttpRequest request = this.getRequestBuilder(this.getUri(command, parameters)) .GET() .build(); - return this.execute(request, clazz); + return this.execute(request, outputType); } private URI getUri(String command, Consumer parameters) { @@ -69,15 +67,15 @@ public class HttpRepository extends Repository { .header("Content-Type", "application/json"); } - private RequestResponse execute(HttpRequest request, Class clazz) { - RequestResponse rawResponse = this.sendHttp(request); - return new RequestResponse<>(rawResponse.status, this.gson.fromJson(rawResponse.data, clazz)); + private ReqResp execute(HttpRequest request, Class clazz) { + ReqResp rawResponse = this.sendHttp(request); + return new ReqResp<>(rawResponse.status(), this.gson.fromJson(rawResponse.data(), clazz)); } - private RequestResponse sendHttp(HttpRequest request) { + private ReqResp sendHttp(HttpRequest request) { try(HttpClient client = HttpClient.newHttpClient()) { HttpResponse httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString()); - return new RequestResponse<>(httpResponse.statusCode(), httpResponse.body()); + return new ReqResp<>(httpResponse.statusCode(), httpResponse.body()); } catch(IOException | InterruptedException e) { throw new RuntimeException(e); } diff --git a/src/main/java/eu/mhsl/craftattack/spawn/api/client/Repository.java b/src/main/java/eu/mhsl/craftattack/spawn/api/client/Repository.java index 2c9bbe5..9250ece 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/api/client/Repository.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/api/client/Repository.java @@ -4,7 +4,7 @@ import com.google.gson.Gson; import java.net.URI; -public class Repository { +public abstract class Repository { protected URI basePath; protected Gson gson; diff --git a/src/main/java/eu/mhsl/craftattack/spawn/api/client/RepositoryLoader.java b/src/main/java/eu/mhsl/craftattack/spawn/api/client/RepositoryLoader.java index eb773ca..637a79b 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/api/client/RepositoryLoader.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/api/client/RepositoryLoader.java @@ -3,6 +3,8 @@ package eu.mhsl.craftattack.spawn.api.client; import org.apache.commons.lang3.NotImplementedException; import org.reflections.Reflections; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Set; @@ -10,14 +12,19 @@ import java.util.Set; public class RepositoryLoader { private final List repositories; + @Retention(RetentionPolicy.RUNTIME) + public @interface IgnoreRepository { + } + public RepositoryLoader() { Reflections reflections = new Reflections(this.getClass().getPackageName()); Set> repositories = reflections.getSubTypesOf(Repository.class); this.repositories = repositories.stream() - .map(clazz -> { + .filter(repository -> !repository.isAnnotationPresent(IgnoreRepository.class)) + .map(repository -> { try { - return (Repository) clazz.getDeclaredConstructor().newInstance(); + return (Repository) repository.getDeclaredConstructor().newInstance(); } catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { throw new RuntimeException(e); } @@ -33,4 +40,8 @@ public class RepositoryLoader { .findFirst() .orElseThrow(() -> new NotImplementedException(String.format("Repository '%s' not found!", clazz.getSimpleName()))); } + + public List getRepositories() { + return repositories; + } } diff --git a/src/main/java/eu/mhsl/craftattack/spawn/api/client/ReqResp.java b/src/main/java/eu/mhsl/craftattack/spawn/api/client/ReqResp.java new file mode 100644 index 0000000..2bb3f3f --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/api/client/ReqResp.java @@ -0,0 +1,4 @@ +package eu.mhsl.craftattack.spawn.api.client; + +public record ReqResp(int status, TData data) { +} \ No newline at end of file diff --git a/src/main/java/eu/mhsl/craftattack/spawn/api/client/repositories/ReportRepository.java b/src/main/java/eu/mhsl/craftattack/spawn/api/client/repositories/ReportRepository.java index cd14df0..4f50acf 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/api/client/repositories/ReportRepository.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/api/client/repositories/ReportRepository.java @@ -1,19 +1,20 @@ package eu.mhsl.craftattack.spawn.api.client.repositories; import eu.mhsl.craftattack.spawn.api.client.HttpRepository; +import eu.mhsl.craftattack.spawn.api.client.ReqResp; import eu.mhsl.craftattack.spawn.util.api.ApiUtil; import java.util.UUID; public class ReportRepository extends HttpRepository { public ReportRepository() { - super(ApiUtil.getBaseUri()); + super(ApiUtil.getBaseUri(), ApiUtil::withAuthorizationSecret); } public record SendReportResponse(UUID user) {} public record ReportInput(UUID user) {} - public RequestResponse sendReport(ReportInput input) { + public ReqResp sendReport(ReportInput input) { return this.post("reports", (builder) -> builder.addParameter("token", "asd"), input, SendReportResponse.class); } } diff --git a/src/main/java/eu/mhsl/craftattack/spawn/api/client/repositories/WhitelistRepository.java b/src/main/java/eu/mhsl/craftattack/spawn/api/client/repositories/WhitelistRepository.java new file mode 100644 index 0000000..f0830b0 --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/api/client/repositories/WhitelistRepository.java @@ -0,0 +1,30 @@ +package eu.mhsl.craftattack.spawn.api.client.repositories; + +import eu.mhsl.craftattack.spawn.api.client.HttpRepository; +import eu.mhsl.craftattack.spawn.api.client.ReqResp; +import eu.mhsl.craftattack.spawn.util.api.ApiUtil; + +import java.util.UUID; + +public class WhitelistRepository extends HttpRepository { + public WhitelistRepository() { + super(ApiUtil.getBaseUri(), ApiUtil::withAuthorizationSecret); + } + + public record UserData( + UUID uuid, + String username, + String firstname, + String lastname, + Long banned_until, + Long outlawed_until + ) {} + + public ReqResp getUserData(UUID userId) { + return this.get( + "user", + uriBuilder -> uriBuilder.addParameter("uuid", userId.toString()), + UserData.class + ); + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/report/Report.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/report/Report.java index c10dcf1..c426c95 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/report/Report.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/report/Report.java @@ -4,7 +4,6 @@ import com.google.gson.Gson; import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; -import eu.mhsl.craftattack.spawn.util.api.ApiUtil; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.ComponentBuilder; import net.kyori.adventure.text.TextComponent; @@ -39,8 +38,8 @@ public class Report extends Appliance { .build(); } - private final URI apiEndpoint = ApiUtil.getReportEndpoint(); - private final String apiSecret = ApiUtil.getApiSecret(); + private URI apiEndpoint; + private String apiSecret; public Report() { super("report"); diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/whitelist/Whitelist.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/whitelist/Whitelist.java index ecb928d..97d9b3c 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/whitelist/Whitelist.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/whitelist/Whitelist.java @@ -1,25 +1,19 @@ package eu.mhsl.craftattack.spawn.appliances.whitelist; -import com.google.gson.Gson; import eu.mhsl.craftattack.spawn.Main; +import eu.mhsl.craftattack.spawn.api.client.ReqResp; +import eu.mhsl.craftattack.spawn.api.client.repositories.WhitelistRepository; import eu.mhsl.craftattack.spawn.api.server.HttpServer; import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliances.outlawed.Outlawed; -import eu.mhsl.craftattack.spawn.util.api.ApiUtil; +import eu.mhsl.craftattack.spawn.util.api.HttpStatus; import eu.mhsl.craftattack.spawn.util.server.Floodgate; import eu.mhsl.craftattack.spawn.util.text.DisconnectInfo; -import org.apache.http.client.utils.URIBuilder; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; import java.time.Instant; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; @@ -30,13 +24,6 @@ import java.util.UUID; import java.util.logging.Level; public class Whitelist extends Appliance { - private record UserData(UUID uuid, String username, String firstname, String lastname, Long banned_until, - Long outlawed_until) { - } - - private final URI apiEndpoint = ApiUtil.getWhitelistEndpoint(); - private final String apiSecret = ApiUtil.getApiSecret(); - public Whitelist() { super("whitelist"); } @@ -45,12 +32,12 @@ public class Whitelist extends Appliance { try { Main.instance().getLogger().info(String.format("Running integrityCheck for %s", player.getName())); boolean overrideCheck = localConfig().getBoolean("overrideIntegrityCheck", false); - UserData user = overrideCheck - ? new UserData(player.getUniqueId(), player.getName(), "", "", 0L, 0L) + WhitelistRepository.UserData user = overrideCheck + ? new WhitelistRepository.UserData(player.getUniqueId(), player.getName(), "", "", 0L, 0L) : this.fetchUserData(player.getUniqueId()); - if (timestampRelevant(user.banned_until)) { - Instant bannedDate = new Date(user.banned_until * 1000L) + if (timestampRelevant(user.banned_until())) { + Instant bannedDate = new Date(user.banned_until() * 1000L) .toInstant() .plus(1, ChronoUnit.HOURS); @@ -65,16 +52,16 @@ public class Whitelist extends Appliance { ); } - queryAppliance(Outlawed.class).updateForcedStatus(player, timestampRelevant(user.outlawed_until)); + queryAppliance(Outlawed.class).updateForcedStatus(player, timestampRelevant(user.outlawed_until())); String purePlayerName = Floodgate.isBedrock(player) ? Floodgate.getBedrockPlayer(player).getUsername() : player.getName(); - if (!user.username.trim().equalsIgnoreCase(purePlayerName)) + if (!user.username().trim().equalsIgnoreCase(purePlayerName)) throw new DisconnectInfo.Throwable( "Nutzername geändert", - String.format("Der Name '%s' stimmt nicht mit '%s' überein.", user.username, player.getName()), + String.format("Der Name '%s' stimmt nicht mit '%s' überein.", user.username(), player.getName()), "Bitte kontaktiere einen Admin, um Deine Anmeldedaten zu aktualisieren!", player.getUniqueId() ); @@ -97,33 +84,18 @@ public class Whitelist extends Appliance { return timestamp > System.currentTimeMillis() / 1000L; } - private UserData fetchUserData(UUID uuid) throws DisconnectInfo.Throwable { - URIBuilder uriBuilder = new URIBuilder(this.apiEndpoint); - uriBuilder.addParameter("secret", this.apiSecret); - uriBuilder.addParameter("uuid", uuid.toString()); + private WhitelistRepository.UserData fetchUserData(UUID uuid) throws DisconnectInfo.Throwable { + ReqResp response = this.queryRepository(WhitelistRepository.class).getUserData(uuid); - try(HttpClient client = HttpClient.newHttpClient()) { - HttpRequest httpRequest = HttpRequest.newBuilder() - .uri(uriBuilder.build()) - .header("Content-Type", "application/json") - .GET() - .build(); + if(response.status() == HttpStatus.NOT_FOUND) + throw new DisconnectInfo.Throwable( + "Nicht angemeldet", + "Du bist derzeit nicht als Teilnehmer des CraftAttack-Projektes registriert!", + "Melde Dich bei einem Admin für eine nachträgliche Anmeldung.", + uuid + ); - HttpResponse httpResponse = client.send(httpRequest, HttpResponse.BodyHandlers.ofString()); - - if(httpResponse.statusCode() == 404) - throw new DisconnectInfo.Throwable( - "Nicht angemeldet", - "Du bist derzeit nicht als Teilnehmer des CraftAttack-Projektes registriert!", - "Melde Dich bei einem Admin für eine nachträgliche Anmeldung.", - uuid - ); - - return new Gson().fromJson(httpResponse.body(), UserData.class); - - } catch(IOException | InterruptedException | URISyntaxException e) { - throw new RuntimeException(e); - } + return response.data(); } @Override diff --git a/src/main/java/eu/mhsl/craftattack/spawn/util/api/ApiUtil.java b/src/main/java/eu/mhsl/craftattack/spawn/util/api/ApiUtil.java index 2c9b778..0fe700c 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/util/api/ApiUtil.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/util/api/ApiUtil.java @@ -1,17 +1,17 @@ package eu.mhsl.craftattack.spawn.util.api; import eu.mhsl.craftattack.spawn.config.Configuration; +import org.apache.http.client.utils.URIBuilder; +import org.bukkit.configuration.ConfigurationSection; import java.net.URI; import java.net.URISyntaxException; import java.util.Objects; public class ApiUtil { - public final static String basePath = Objects.requireNonNull(Configuration.cfg.getConfigurationSection("api")) - .getString("baseurl"); - - public final static String apiSecret = Objects.requireNonNull(Configuration.cfg.getConfigurationSection("api")) - .getString("secret"); + private final static ConfigurationSection apiConfig = Objects.requireNonNull(Configuration.cfg.getConfigurationSection("api")); + public final static String basePath = apiConfig.getString("baseurl"); + public final static String apiSecret = apiConfig.getString("secret"); public static URI getBaseUri() { Objects.requireNonNull(basePath); @@ -21,4 +21,8 @@ public class ApiUtil { throw new RuntimeException(e); } } + + public static void withAuthorizationSecret(URIBuilder builder) { + builder.addParameter("secret", apiSecret); + } } diff --git a/src/main/java/eu/mhsl/craftattack/spawn/util/api/HttpStatus.java b/src/main/java/eu/mhsl/craftattack/spawn/util/api/HttpStatus.java new file mode 100644 index 0000000..658cd20 --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/util/api/HttpStatus.java @@ -0,0 +1,14 @@ +package eu.mhsl.craftattack.spawn.util.api; + +public class HttpStatus { + public static final int OK = 200; + public static final int CREATED = 201; + public static final int ACCEPTED = 202; + public static final int NO_CONTENT = 204; + public static final int BAD_REQUEST = 400; + public static final int UNAUTHORIZED = 401; + public static final int FORBIDDEN = 403; + public static final int NOT_FOUND = 404; + public static final int INTERNAL_SERVER_ERROR = 500; + public static final int SERVICE_UNAVAILABLE = 503; +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 95a0324..fef788d 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -3,10 +3,8 @@ plugin: - NameOfApplianceClass api: - secret: qeeDmIXn@Wfye4@f8twTJkdNWr7Uz2byETKJBE9bfxz&M7VqOnuA3q3GT#WkwTVn + secret: secret baseurl: https://mhsl.eu/craftattack/api/ - report: report - whitelist: user worldMuseum: uuid: