From 514e5821d2ca5a497d3c010bfdc7cb0935cb0a98 Mon Sep 17 00:00:00 2001 From: PinkGoosik Date: Fri, 17 May 2024 21:27:01 +0400 Subject: [PATCH] github webhooks test --- .../pinkgoosik/kitsun/http/GithubWebhook.java | 42 +++++++++ .../kitsun/http/KitsunHttpHandler.java | 77 ++++++++++++++++ .../kitsun/http/KitsunHttpServer.java | 89 +------------------ .../kitsun/http/ModUpdateWebhook.java | 40 +++++++++ 4 files changed, 161 insertions(+), 87 deletions(-) create mode 100644 src/main/java/ru/pinkgoosik/kitsun/http/GithubWebhook.java create mode 100644 src/main/java/ru/pinkgoosik/kitsun/http/KitsunHttpHandler.java create mode 100644 src/main/java/ru/pinkgoosik/kitsun/http/ModUpdateWebhook.java diff --git a/src/main/java/ru/pinkgoosik/kitsun/http/GithubWebhook.java b/src/main/java/ru/pinkgoosik/kitsun/http/GithubWebhook.java new file mode 100644 index 0000000..13d9027 --- /dev/null +++ b/src/main/java/ru/pinkgoosik/kitsun/http/GithubWebhook.java @@ -0,0 +1,42 @@ +package ru.pinkgoosik.kitsun.http; + +import com.sun.net.httpserver.HttpExchange; +import ru.pinkgoosik.kitsun.Bot; +import ru.pinkgoosik.kitsun.feature.KitsunDebugger; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; + +public class GithubWebhook extends KitsunHttpHandler { + + @Override + public void handle(HttpExchange exchange) { + var map = parseParams(exchange); + + if(map.containsKey("token") && Bot.secrets.get().http.token.equals(map.get("token")) && exchange.getRequestMethod().equals("POST") && exchange.getRequestHeaders().containsKey("x-github-event")) { + var event = exchange.getRequestHeaders().get("x-github-event").get(0); + var is = exchange.getRequestBody(); + StringBuilder textBuilder = new StringBuilder(); + + try (Reader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { + int c; + while ((c = reader.read()) != -1) { + textBuilder.append((char) c); + } + } + catch (Exception e) { + Bot.LOGGER.info("Failed to handle github webhook due to an exception: " + e); + } + String body = textBuilder.toString(); + + KitsunDebugger.info(event + ": \n" + body); + + success(exchange, "Accepted", 202); + return; + } + + notFound(exchange); + } +} diff --git a/src/main/java/ru/pinkgoosik/kitsun/http/KitsunHttpHandler.java b/src/main/java/ru/pinkgoosik/kitsun/http/KitsunHttpHandler.java new file mode 100644 index 0000000..cf49d88 --- /dev/null +++ b/src/main/java/ru/pinkgoosik/kitsun/http/KitsunHttpHandler.java @@ -0,0 +1,77 @@ +package ru.pinkgoosik.kitsun.http; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import ru.pinkgoosik.kitsun.Bot; + +import java.io.OutputStream; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.LinkedHashMap; +import java.util.Map; + +public abstract class KitsunHttpHandler implements HttpHandler { + + static Map parseParams(HttpExchange exchange) { + String[] split = exchange.getRequestURI().toString().split("\\?"); + if (split.length >= 2) { + return splitParams(split[1]); + } + return new LinkedHashMap<>(); + } + + static Map splitParams(String params) { + Map queryPairs = new LinkedHashMap<>(); + + try { + String[] pairs = params.split("&"); + for (String pair : pairs) { + int idx = pair.indexOf("="); + queryPairs.put(URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8), URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8)); + } + } + catch (Exception e) { + Bot.LOGGER.error("Failed to split parameters: " + params + ", " + e); + } + return queryPairs; + } + + static void notFound(HttpExchange exchange) { + try { + String text = "

404 Not Found

No context found for request"; + exchange.sendResponseHeaders(404, text.length()); + OutputStream os = exchange.getResponseBody(); + + os.write(text.getBytes()); + os.flush(); + exchange.close(); + } + catch (Exception e) { + Bot.LOGGER.error("Failed to send not found response " + e); + } + } + + static void success(HttpExchange exchange, String text) { + try { + exchange.sendResponseHeaders(200, text.length()); + OutputStream os = exchange.getResponseBody(); + os.write(text.getBytes()); + os.close(); + } + catch (Exception e) { + Bot.LOGGER.error("Failed to send success response " + e); + } + } + + static void success(HttpExchange exchange, String text, int status) { + try { + exchange.sendResponseHeaders(status, text.length()); + OutputStream os = exchange.getResponseBody(); + os.write(text.getBytes()); + os.close(); + } + catch (Exception e) { + Bot.LOGGER.error("Failed to send success response " + e); + } + } +} diff --git a/src/main/java/ru/pinkgoosik/kitsun/http/KitsunHttpServer.java b/src/main/java/ru/pinkgoosik/kitsun/http/KitsunHttpServer.java index ba8006d..66106b3 100644 --- a/src/main/java/ru/pinkgoosik/kitsun/http/KitsunHttpServer.java +++ b/src/main/java/ru/pinkgoosik/kitsun/http/KitsunHttpServer.java @@ -1,17 +1,8 @@ package ru.pinkgoosik.kitsun.http; -import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpServer; import ru.pinkgoosik.kitsun.Bot; -import ru.pinkgoosik.kitsun.cache.ServerData; -import ru.pinkgoosik.kitsun.util.ServerUtils; - -import java.io.OutputStream; import java.net.InetSocketAddress; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.util.LinkedHashMap; -import java.util.Map; public class KitsunHttpServer { public static HttpServer server; @@ -20,35 +11,9 @@ public static void init() { if(Bot.secrets.get().http.port > 0) { try { HttpServer server = HttpServer.create(new InetSocketAddress(Bot.secrets.get().http.port), 0); - server.createContext("/mod_update", exchange -> { - var map = parseParams(exchange); - - if (map.containsKey("token") && Bot.secrets.get().http.token.equals(map.get("token"))) { - if(map.containsKey("server") && map.containsKey("project")) { - if (!ServerUtils.exist(map.get("server"))) { - success(exchange, "Server not found"); - return; - } - var data = ServerData.get(map.get("server")); - - for(var publisher : data.modUpdates.get()) { - if(publisher.project.equals(map.get("project"))) { - success(exchange, "Success"); - try { - Thread.sleep(5 * 1000); - publisher.check(0); - } - catch (Exception ignored) {} - return; - } - } - success(exchange, "Project not found"); - return; - } - } - notFound(exchange); - }); + server.createContext("/github", new GithubWebhook()); + server.createContext("/mod_update", new ModUpdateWebhook()); server.setExecutor(command -> new Thread(command).start()); server.start(); @@ -60,54 +25,4 @@ public static void init() { } } - static Map parseParams(HttpExchange exchange) { - String[] split = exchange.getRequestURI().toString().split("\\?"); - if (split.length >= 2) { - return splitParams(split[1]); - } - return new LinkedHashMap<>(); - } - - static Map splitParams(String params) { - Map queryPairs = new LinkedHashMap<>(); - - try { - String[] pairs = params.split("&"); - for (String pair : pairs) { - int idx = pair.indexOf("="); - queryPairs.put(URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8), URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8)); - } - } - catch (Exception e) { - Bot.LOGGER.error("Failed to split parameters: " + params + ", " + e); - } - return queryPairs; - } - - static void notFound(HttpExchange exchange) { - try { - String text = "

404 Not Found

No context found for request"; - exchange.sendResponseHeaders(404, text.length()); - OutputStream os = exchange.getResponseBody(); - - os.write(text.getBytes()); - os.flush(); - exchange.close(); - } - catch (Exception e) { - Bot.LOGGER.error("Failed to send not found response " + e); - } - } - - static void success(HttpExchange exchange, String text) { - try { - exchange.sendResponseHeaders(200, text.length()); - OutputStream os = exchange.getResponseBody(); - os.write(text.getBytes()); - os.close(); - } - catch (Exception e) { - Bot.LOGGER.error("Failed to send success response " + e); - } - } } diff --git a/src/main/java/ru/pinkgoosik/kitsun/http/ModUpdateWebhook.java b/src/main/java/ru/pinkgoosik/kitsun/http/ModUpdateWebhook.java new file mode 100644 index 0000000..91076f9 --- /dev/null +++ b/src/main/java/ru/pinkgoosik/kitsun/http/ModUpdateWebhook.java @@ -0,0 +1,40 @@ +package ru.pinkgoosik.kitsun.http; + +import com.sun.net.httpserver.HttpExchange; +import ru.pinkgoosik.kitsun.Bot; +import ru.pinkgoosik.kitsun.cache.ServerData; +import ru.pinkgoosik.kitsun.util.ServerUtils; + +public class ModUpdateWebhook extends KitsunHttpHandler { + + @Override + public void handle(HttpExchange exchange) { + var map = parseParams(exchange); + + if (map.containsKey("token") && Bot.secrets.get().http.token.equals(map.get("token"))) { + if(map.containsKey("server") && map.containsKey("project")) { + if (!ServerUtils.exist(map.get("server"))) { + success(exchange, "Server not found"); + return; + } + var data = ServerData.get(map.get("server")); + + for(var publisher : data.modUpdates.get()) { + if(publisher.project.equals(map.get("project"))) { + success(exchange, "Success"); + try { + Thread.sleep(5 * 1000); + publisher.check(0); + } + catch (Exception ignored) {} + return; + } + } + success(exchange, "Project not found"); + return; + } + } + + notFound(exchange); + } +}