From f7ff87e88cb869a1affc5f283f2f56f34b910a19 Mon Sep 17 00:00:00 2001 From: noe Date: Tue, 25 Jun 2024 16:52:27 -0400 Subject: [PATCH] big first commit --- .direnv/bin/nix-direnv-reload | 19 ++++++++ .envrc | 2 + .gitignore | 2 + flake.lock | 58 ++++++++++++++++++++++ flake.nix | 15 ++++++ go.mod | 3 ++ hook_handler.go | 90 +++++++++++++++++++++++++++++++++++ main.go | 63 ++++++++++++++++++++++++ shell.nix | 7 +++ 9 files changed, 259 insertions(+) create mode 100755 .direnv/bin/nix-direnv-reload create mode 100644 .envrc create mode 100644 .gitignore create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 go.mod create mode 100644 hook_handler.go create mode 100644 main.go create mode 100644 shell.nix diff --git a/.direnv/bin/nix-direnv-reload b/.direnv/bin/nix-direnv-reload new file mode 100755 index 0000000..4a0c2b7 --- /dev/null +++ b/.direnv/bin/nix-direnv-reload @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -e +if [[ ! -d "/home/noe/dev/git.sapphic.engineer/noe/plapkit" ]]; then + echo "Cannot find source directory; Did you move it?" + echo "(Looking for "/home/noe/dev/git.sapphic.engineer/noe/plapkit")" + echo 'Cannot force reload with this script - use "direnv reload" manually and then try again' + exit 1 +fi + +# rebuild the cache forcefully +_nix_direnv_force_reload=1 direnv exec "/home/noe/dev/git.sapphic.engineer/noe/plapkit" true + +# Update the mtime for .envrc. +# This will cause direnv to reload again - but without re-building. +touch "/home/noe/dev/git.sapphic.engineer/noe/plapkit/.envrc" + +# Also update the timestamp of whatever profile_rc we have. +# This makes sure that we know we are up to date. +touch -r "/home/noe/dev/git.sapphic.engineer/noe/plapkit/.envrc" "/home/noe/dev/git.sapphic.engineer/noe/plapkit/.direnv"/*.rc diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..fb4b158 --- /dev/null +++ b/.envrc @@ -0,0 +1,2 @@ +dotenv; +use flake; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d136290 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.direnv +.env \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..6846000 --- /dev/null +++ b/flake.lock @@ -0,0 +1,58 @@ +{ + "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1717285511, + "narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1719075281, + "narHash": "sha256-CyyxvOwFf12I91PBWz43iGT1kjsf5oi6ax7CrvaMyAo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a71e967ef3694799d0c418c98332f7ff4cc5f6af", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1717284937, + "narHash": "sha256-lIbdfCsf8LMFloheeE6N31+BMIeixqyQWbSr2vk79EQ=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..b0b6c25 --- /dev/null +++ b/flake.nix @@ -0,0 +1,15 @@ +{ + description = "saerro"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-parts.url = "github:hercules-ci/flake-parts"; + }; + + outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ "x86_64-linux" "aarch64-linux" ]; + perSystem = { config, self', pkgs, lib, system, ... }: { + devShells.default = import ./shell.nix { inherit pkgs; }; + }; + }; +} \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..52fa425 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.sapphic.engineer/noe/plapkit + +go 1.22.3 diff --git a/hook_handler.go b/hook_handler.go new file mode 100644 index 0000000..b5e3d4b --- /dev/null +++ b/hook_handler.go @@ -0,0 +1,90 @@ +package main + +import ( + "encoding/json" + "log" + "net/http" +) + +type HookPayload[D HookPayloadData] struct { + Type string `json:"type"` + SigningToken string `json:"signing_token"` + SystemID string `json:"system_id"` + ID string `json:"id,omitempty"` + Data D `json:"data,omitempty"` +} + +type Switch struct { + ID string `json:"id"` + Timestamp string `json:"timestamp"` + Members []string `json:"members"` +} + +type Message struct { + ID string `json:"id"` + Timestamp string `json:"timestamp"` + Member string `json:"member"` +} + +type HookPayloadData interface { + Switch | Message | interface{} +} + +type hookHandler[D HookPayloadData] func(h HookPayload[D]) + +var ( + hookHandlers map[string]hookHandler[HookPayloadData] = map[string]hookHandler[HookPayloadData]{ + "CREATE_SWITCH": handleHookCreateSwitch, + "CREATE_MESSAGE": handleHookCreateMessage, + } +) + +func postGetHookToken(rw http.ResponseWriter, req *http.Request) { + if req.Method != "POST" { + errMethodNotAllowed(rw) + return + } + + var payload HookPayload[HookPayloadData] + err := json.NewDecoder(req.Body).Decode(&payload) + if err != nil { + errBadRequest(rw) + return + } + + if payload.SigningToken != SigningToken { + errUnauthorized(rw) + return + } + + if payload.Type == "PING" { + basicOk(rw) + return + } + + handler, ok := hookHandlers[payload.Type] + if !ok { + basicNoContent(rw) + return + } + + go handler(payload) +} + +func handleHookCreateSwitch(h HookPayload[HookPayloadData]) { + hook, ok := h.Data.(Switch) + if !ok { + log.Printf("[handleHookCreateSwitch] could not cast hook payload data to Switch, got: %v\n", h) + } + + log.Printf("[handleHookCreateSwitch] got hook: %v\n", hook) +} + +func handleHookCreateMessage(h HookPayload[HookPayloadData]) { + hook, ok := h.Data.(Message) + if !ok { + log.Printf("[handleHookCreateMessage] could not cast hook payload data to Message, got: %v\n", h) + } + + log.Printf("[handleHookCreateMessage] got hook: %v\n", hook) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..361aea0 --- /dev/null +++ b/main.go @@ -0,0 +1,63 @@ +package main + +import ( + "log" + "net/http" + "os" +) + +var ( + SigningToken = os.Getenv("SIGNING_TOKEN") +) + +func main() { + listenAddr := os.Getenv("LISTEN_ADDR") + if listenAddr == "" { + listenAddr = "0.0.0.0:8555" + } + + mux := http.NewServeMux() + mux.HandleFunc("/hook/{token}", postGetHookToken) + + log.Println("[main] http server listening on", listenAddr) + err := http.ListenAndServe(listenAddr, mux) + if err != nil { + log.Fatalln("[main] http server errored", err) + } +} + +func errMethodNotAllowed(rw http.ResponseWriter) { + rw.Header().Add("content-type", "text/plain") + rw.WriteHeader(http.StatusMethodNotAllowed) + rw.Write([]byte("405 Method Not Allowed")) +} + +func errStatusInternalServerError(rw http.ResponseWriter) { + rw.Header().Add("content-type", "text/plain") + rw.WriteHeader(http.StatusInternalServerError) + rw.Write([]byte("500 Internal Server Error")) +} + +func errUnauthorized(rw http.ResponseWriter) { + rw.Header().Add("content-type", "text/plain") + rw.WriteHeader(http.StatusUnauthorized) + rw.Write([]byte("401 Unauthorized")) +} + +func errBadRequest(rw http.ResponseWriter) { + rw.Header().Add("content-type", "text/plain") + rw.WriteHeader(http.StatusBadRequest) + rw.Write([]byte("401 Bad Request")) +} + +func basicOk(rw http.ResponseWriter) { + rw.Header().Add("content-type", "text/plain") + rw.WriteHeader(http.StatusOK) + rw.Write([]byte("200 Aight Request")) +} + +func basicNoContent(rw http.ResponseWriter) { + rw.Header().Add("content-type", "text/plain") + rw.WriteHeader(http.StatusNoContent) + rw.Write([]byte("204 No Content (debug: likely not handled)")) +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..7210e41 --- /dev/null +++ b/shell.nix @@ -0,0 +1,7 @@ +{ pkgs ? import {} }: pkgs.mkShell { + buildInputs = with pkgs; [ + go + just + sqlite + ]; +}