aboutsummaryrefslogtreecommitdiff
path: root/mod/src/main/java/moe/ymc/acron/config/json
diff options
context:
space:
mode:
Diffstat (limited to 'mod/src/main/java/moe/ymc/acron/config/json')
-rw-r--r--mod/src/main/java/moe/ymc/acron/config/json/Client.java45
-rw-r--r--mod/src/main/java/moe/ymc/acron/config/json/Config.java103
-rw-r--r--mod/src/main/java/moe/ymc/acron/config/json/ConfigDeserializationException.java18
-rw-r--r--mod/src/main/java/moe/ymc/acron/config/json/ConfigDeserializer.java27
-rw-r--r--mod/src/main/java/moe/ymc/acron/config/json/ConfigJsonObject.java7
-rw-r--r--mod/src/main/java/moe/ymc/acron/config/json/Rule.java35
6 files changed, 235 insertions, 0 deletions
diff --git a/mod/src/main/java/moe/ymc/acron/config/json/Client.java b/mod/src/main/java/moe/ymc/acron/config/json/Client.java
new file mode 100644
index 0000000..4d31308
--- /dev/null
+++ b/mod/src/main/java/moe/ymc/acron/config/json/Client.java
@@ -0,0 +1,45 @@
+package moe.ymc.acron.config.json;
+
+import com.google.gson.annotations.SerializedName;
+import moe.ymc.acron.auth.Action;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+class Client implements ConfigJsonObject<moe.ymc.acron.auth.Client> {
+ @SerializedName("id")
+ private final String id;
+
+ @SerializedName("token")
+ private final String token;
+
+ @SerializedName("policy_mode")
+ private final Action policyMode;
+
+ @SerializedName("rules")
+ private final List<Rule> rules;
+
+ private Client(String id,
+ String token,
+ Action policyMode,
+ List<Rule> rules) {
+ this.id = id;
+ this.token = token;
+ this.policyMode = policyMode;
+ this.rules = rules;
+ }
+
+ @Override
+ public @NotNull moe.ymc.acron.auth.Client create(boolean startup) throws ConfigDeserializationException {
+ if (id == null || id.trim().equals("") ||
+ token == null || token.trim().equals("")) {
+ throw new ConfigDeserializationException(".clients[].id or .clients[].token is not supplied.");
+ }
+ return new moe.ymc.acron.auth.Client(id,
+ token,
+ policyMode == null ? Action.DENY : policyMode,
+ rules == null ? new moe.ymc.acron.auth.Rule[]{} :
+ rules.stream().map(rule -> rule.create(startup)).toList()
+ .toArray(new moe.ymc.acron.auth.Rule[rules.size()]));
+ }
+}
diff --git a/mod/src/main/java/moe/ymc/acron/config/json/Config.java b/mod/src/main/java/moe/ymc/acron/config/json/Config.java
new file mode 100644
index 0000000..e8c5a83
--- /dev/null
+++ b/mod/src/main/java/moe/ymc/acron/config/json/Config.java
@@ -0,0 +1,103 @@
+package moe.ymc.acron.config.json;
+
+import com.google.gson.annotations.SerializedName;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.jetbrains.annotations.NotNull;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+class Config implements ConfigJsonObject<moe.ymc.acron.config.Config> {
+ private static final Logger LOGGER = LogManager.getLogger();
+
+ @SerializedName("listen")
+ private final String listen;
+
+ @SerializedName("port")
+ private final Integer port;
+
+ @SerializedName("native_transport")
+ private final boolean nativeTransport;
+
+ @SerializedName("clients")
+ private final List<Client> clients;
+
+ private Config(String listen,
+ Integer port,
+ boolean nativeTransport,
+ List<Client> clients) {
+ this.listen = listen;
+ this.port = port;
+ this.nativeTransport = nativeTransport;
+ this.clients = clients;
+ }
+
+ @Override
+ public @NotNull moe.ymc.acron.config.Config create(boolean startup) throws ConfigDeserializationException {
+ final InetAddress address;
+ final int p;
+ final boolean nt;
+ if (!startup) {
+ address = moe.ymc.acron.config.Config.getGlobalConfig().address();
+ p = moe.ymc.acron.config.Config.getGlobalConfig().port();
+ nt = moe.ymc.acron.config.Config.getGlobalConfig().useNativeTransport();
+ } else {
+ if (listen == null || listen.trim().equals("")) {
+ address = InetAddress.getLoopbackAddress();
+ } else {
+ try {
+ address = InetAddress.getByName(listen);
+ } catch (UnknownHostException e) {
+ throw new ConfigDeserializationException("Cannot parse address: " + e.getMessage(),
+ true);
+ }
+ }
+ if (port == null) {
+ p = 25575;
+ } else {
+ if (port < 0 || port > 65535) {
+ throw new ConfigDeserializationException("The port is out of range.", true);
+ }
+ p = port;
+ }
+ nt = nativeTransport;
+ }
+
+
+ Map<String, moe.ymc.acron.auth.Client> map;
+ try {
+ if (clients != null) {
+ map = clients.stream()
+ .collect(Collectors.<Client, String, moe.ymc.acron.auth.Client>
+ toMap(client -> client.create(startup).id(),
+ client -> client.create(startup)));
+ } else {
+ map = new HashMap<>(0);
+ }
+ } catch (IllegalStateException e) {
+ // Collision.
+ LOGGER.error("Duplicate clients with the same ID in the Acron configuration. All clients are ignored. " +
+ "Fix the configuration and reload.", e);
+ if (!startup) {
+ throw new ConfigDeserializationException("Duplicate clients with the same ID: " + e.getMessage());
+ }
+ map = new HashMap<>(0);
+ } catch (ConfigDeserializationException e) {
+ LOGGER.error("Cannot parse the Acron configuration. All clients are ignored. " +
+ "Fix the configuration and reload.", e);
+ if (!startup) {
+ throw e;
+ }
+ map = new HashMap<>(0);
+ }
+ return new moe.ymc.acron.config.Config(address,
+ p,
+ nt,
+ map);
+ }
+}
diff --git a/mod/src/main/java/moe/ymc/acron/config/json/ConfigDeserializationException.java b/mod/src/main/java/moe/ymc/acron/config/json/ConfigDeserializationException.java
new file mode 100644
index 0000000..baf5b35
--- /dev/null
+++ b/mod/src/main/java/moe/ymc/acron/config/json/ConfigDeserializationException.java
@@ -0,0 +1,18 @@
+package moe.ymc.acron.config.json;
+
+public class ConfigDeserializationException extends RuntimeException {
+ private final boolean fetal;
+
+ public ConfigDeserializationException(String message) {
+ this(message, false);
+ }
+
+ public ConfigDeserializationException(String message, boolean fetal) {
+ super(message);
+ this.fetal = fetal;
+ }
+
+ public boolean isFetal() {
+ return fetal;
+ }
+}
diff --git a/mod/src/main/java/moe/ymc/acron/config/json/ConfigDeserializer.java b/mod/src/main/java/moe/ymc/acron/config/json/ConfigDeserializer.java
new file mode 100644
index 0000000..e91b355
--- /dev/null
+++ b/mod/src/main/java/moe/ymc/acron/config/json/ConfigDeserializer.java
@@ -0,0 +1,27 @@
+package moe.ymc.acron.config.json;
+
+import com.google.gson.Gson;
+import moe.ymc.acron.config.Config;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+
+public class ConfigDeserializer {
+ public static @NotNull Config deserialize(@NotNull File file, boolean startup)
+ throws ConfigDeserializationException, IOException {
+ final Reader reader = new FileReader(file);
+ final moe.ymc.acron.config.json.Config config;
+ try {
+ config = new Gson()
+ .fromJson(reader, moe.ymc.acron.config.json.Config.class);
+ } catch (Throwable e) {
+ throw new ConfigDeserializationException("Cannot parse JSON: " + e.getMessage(),
+ true);
+ }
+ reader.close();
+ return config.create(startup);
+ }
+}
diff --git a/mod/src/main/java/moe/ymc/acron/config/json/ConfigJsonObject.java b/mod/src/main/java/moe/ymc/acron/config/json/ConfigJsonObject.java
new file mode 100644
index 0000000..0efd9a9
--- /dev/null
+++ b/mod/src/main/java/moe/ymc/acron/config/json/ConfigJsonObject.java
@@ -0,0 +1,7 @@
+package moe.ymc.acron.config.json;
+
+import org.jetbrains.annotations.NotNull;
+
+public interface ConfigJsonObject<T> {
+ @NotNull T create(boolean startup) throws ConfigDeserializationException;
+}
diff --git a/mod/src/main/java/moe/ymc/acron/config/json/Rule.java b/mod/src/main/java/moe/ymc/acron/config/json/Rule.java
new file mode 100644
index 0000000..114e17d
--- /dev/null
+++ b/mod/src/main/java/moe/ymc/acron/config/json/Rule.java
@@ -0,0 +1,35 @@
+package moe.ymc.acron.config.json;
+
+import com.google.gson.annotations.SerializedName;
+import moe.ymc.acron.auth.Action;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.regex.Pattern;
+
+class Rule implements ConfigJsonObject<moe.ymc.acron.auth.Rule> {
+ @SerializedName("regex")
+ private final String regex;
+
+ @SerializedName("action")
+ private final Action action;
+
+ @SerializedName("display")
+ private final boolean display;
+
+ private Rule(String regex,
+ Action action,
+ boolean display) {
+ this.regex = regex;
+ this.action = action;
+ this.display = display;
+ }
+
+ public @NotNull moe.ymc.acron.auth.Rule create(boolean startup) throws ConfigDeserializationException {
+ if (regex == null || regex.trim().equals("") ||
+ action == null) throw new ConfigDeserializationException(".clients.[]rules.regex or .clients.[]rules.action is" +
+ "not specified.");
+ return new moe.ymc.acron.auth.Rule(Pattern.compile(regex),
+ action,
+ display);
+ }
+}