From 1affc4d3bc30a54234b88d849f5404eda0444b90 Mon Sep 17 00:00:00 2001 From: YouHaveTrouble Date: Fri, 11 Jul 2025 20:09:14 +0200 Subject: [PATCH] endpoint returning invites based on hostname --- .../java/me/youhavetrouble/inviter/Main.java | 4 ++ .../inviter/discord/GuildSettings.java | 1 + .../endpoints/GetDiscordInviteByGuildId.java | 4 +- .../inviter/http/endpoints/HandlerKernel.java | 3 +- .../inviter/http/endpoints/MainEndpoint.java | 49 +++++++++++++++++++ .../inviter/storage/SqliteStorage.java | 26 +++++++++- .../inviter/storage/Storage.java | 2 + 7 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 src/main/java/me/youhavetrouble/inviter/http/endpoints/MainEndpoint.java diff --git a/src/main/java/me/youhavetrouble/inviter/Main.java b/src/main/java/me/youhavetrouble/inviter/Main.java index d00064e..132a95d 100644 --- a/src/main/java/me/youhavetrouble/inviter/Main.java +++ b/src/main/java/me/youhavetrouble/inviter/Main.java @@ -109,4 +109,8 @@ public class Main { return discordInviteManager; } + public static Storage getStorage() { + return storage; + } + } diff --git a/src/main/java/me/youhavetrouble/inviter/discord/GuildSettings.java b/src/main/java/me/youhavetrouble/inviter/discord/GuildSettings.java index eb10d21..94f3f67 100644 --- a/src/main/java/me/youhavetrouble/inviter/discord/GuildSettings.java +++ b/src/main/java/me/youhavetrouble/inviter/discord/GuildSettings.java @@ -3,6 +3,7 @@ package me.youhavetrouble.inviter.discord; import org.jetbrains.annotations.Nullable; public record GuildSettings( + long guildId, boolean apiEnabled, @Nullable String apiHostname ) { diff --git a/src/main/java/me/youhavetrouble/inviter/http/endpoints/GetDiscordInviteByGuildId.java b/src/main/java/me/youhavetrouble/inviter/http/endpoints/GetDiscordInviteByGuildId.java index 247cbdf..39db464 100644 --- a/src/main/java/me/youhavetrouble/inviter/http/endpoints/GetDiscordInviteByGuildId.java +++ b/src/main/java/me/youhavetrouble/inviter/http/endpoints/GetDiscordInviteByGuildId.java @@ -38,8 +38,8 @@ public class GetDiscordInviteByGuildId implements EndpointHandler { return; } - DiscordInviteManager storage = Main.getDiscordInviteMenager(); - DiscordInvite invite = storage.getInvite(guildIdLong); + DiscordInviteManager inviteManager = Main.getDiscordInviteMenager(); + DiscordInvite invite = inviteManager.getInvite(guildIdLong); if (invite == null) { exchange.sendResponseHeaders(404, -1); // Not Found diff --git a/src/main/java/me/youhavetrouble/inviter/http/endpoints/HandlerKernel.java b/src/main/java/me/youhavetrouble/inviter/http/endpoints/HandlerKernel.java index ba5fd58..4478bf2 100644 --- a/src/main/java/me/youhavetrouble/inviter/http/endpoints/HandlerKernel.java +++ b/src/main/java/me/youhavetrouble/inviter/http/endpoints/HandlerKernel.java @@ -13,6 +13,7 @@ public class HandlerKernel implements HttpHandler { private final Set handlers = new HashSet<>(); public HandlerKernel() { + handlers.add(new MainEndpoint()); handlers.add(new GetDiscordInviteByGuildId()); } @@ -20,7 +21,7 @@ public class HandlerKernel implements HttpHandler { public void handle(HttpExchange exchange) throws IOException { String path = exchange.getRequestURI().getPath(); - if (path.endsWith("/")) path = path.substring(0, path.length() - 1); + if (path.endsWith("/") && path.length() > 1) path = path.substring(0, path.length() - 1); exchange.getResponseHeaders().set("Access-Control-Allow-Origin", "*"); exchange.getResponseHeaders().set("Access-Control-Allow-Methods", "*"); exchange.getResponseHeaders().set("Access-Control-Allow-Headers", "Content-Type"); diff --git a/src/main/java/me/youhavetrouble/inviter/http/endpoints/MainEndpoint.java b/src/main/java/me/youhavetrouble/inviter/http/endpoints/MainEndpoint.java new file mode 100644 index 0000000..aa7af60 --- /dev/null +++ b/src/main/java/me/youhavetrouble/inviter/http/endpoints/MainEndpoint.java @@ -0,0 +1,49 @@ +package me.youhavetrouble.inviter.http.endpoints; + +import com.sun.net.httpserver.HttpExchange; +import me.youhavetrouble.inviter.Main; +import me.youhavetrouble.inviter.discord.DiscordInvite; +import me.youhavetrouble.inviter.discord.DiscordInviteManager; +import me.youhavetrouble.inviter.discord.GuildSettings; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.util.regex.Pattern; + +public class MainEndpoint implements EndpointHandler { + + private final Pattern pathPattern = Pattern.compile("^/$"); + + @NotNull + @Override + public Pattern pathPattern() { + return pathPattern; + } + + @Override + public void handle(@NotNull HttpExchange exchange) throws IOException { + if (!exchange.getRequestMethod().equals("GET")) { + exchange.sendResponseHeaders(405, -1); // Method Not Allowed + return; + } + + String host = exchange.getRemoteAddress().getHostName(); + + GuildSettings guildSettings = Main.getStorage().getGuildSettings(host); + if (guildSettings == null) { + exchange.sendResponseHeaders(404, -1); // Not Found + return; + } + + DiscordInviteManager inviteManager = Main.getDiscordInviteMenager(); + DiscordInvite invite = inviteManager.getInvite(guildSettings.guildId()); + + if (invite == null) { + exchange.sendResponseHeaders(404, -1); // Not Found + return; + } + + exchange.getResponseHeaders().set("Location", "https://discord.gg/" + invite.code()); + exchange.sendResponseHeaders(307, -1); + } +} diff --git a/src/main/java/me/youhavetrouble/inviter/storage/SqliteStorage.java b/src/main/java/me/youhavetrouble/inviter/storage/SqliteStorage.java index a273ebb..15de796 100644 --- a/src/main/java/me/youhavetrouble/inviter/storage/SqliteStorage.java +++ b/src/main/java/me/youhavetrouble/inviter/storage/SqliteStorage.java @@ -64,15 +64,37 @@ public class SqliteStorage implements Storage { if (resultSet.next()) { boolean apiEnabled = resultSet.getBoolean("api_enabled"); String apiHostname = resultSet.getString("api_hostname"); - return new GuildSettings(apiEnabled, apiHostname); + return new GuildSettings(guildId, apiEnabled, apiHostname); } - return new GuildSettings(false, null); + return new GuildSettings(guildId,false, null); } catch (SQLException e) { throw new RuntimeException("Failed to retrieve guild settings", e); } } + @Nullable + @Override + public GuildSettings getGuildSettings(@NotNull String hostname) { + + try (Connection connection = dataSource.getConnection()) { + var statement = connection.prepareStatement( + "SELECT * FROM guild_settings WHERE api_hostname = ?" + ); + statement.setString(1, hostname); + ResultSet resultSet = statement.executeQuery(); + + if (resultSet.next()) { + long guildId = resultSet.getLong("guild_id"); + boolean apiEnabled = resultSet.getBoolean("api_enabled"); + return new GuildSettings(guildId, apiEnabled, hostname); + } + return null; // No settings found for the given hostname + } catch (SQLException e) { + throw new RuntimeException("Failed to retrieve guild settings by hostname", e); + } + } + @Override public void saveDefaultGuildSettings(long guildId) { try (Connection connection = dataSource.getConnection()) { diff --git a/src/main/java/me/youhavetrouble/inviter/storage/Storage.java b/src/main/java/me/youhavetrouble/inviter/storage/Storage.java index 72e8322..2305d6c 100644 --- a/src/main/java/me/youhavetrouble/inviter/storage/Storage.java +++ b/src/main/java/me/youhavetrouble/inviter/storage/Storage.java @@ -9,6 +9,8 @@ public interface Storage { @NotNull GuildSettings getGuildSettings(long guildId); + @Nullable GuildSettings getGuildSettings(@NotNull String hostname); + void saveDefaultGuildSettings(long guildId); void updateDiscordApiEnabled(long guildId, boolean enabled);