diff --git a/kit/config/config.go b/kit/config/config.go index 32d93bb..699a3a4 100755 --- a/kit/config/config.go +++ b/kit/config/config.go @@ -7,10 +7,13 @@ import ( ) type Config struct { - Secret string `yaml:"secret"` - Port int `yaml:"port"` - BinaryPath string `yaml:"binary_path"` - ScriptPath string `yaml:"script_path"` + Secret string `yaml:"secret"` + Port int `yaml:"port"` + Scripts map[string]ConfigScript `yaml:"scripts"` +} +type ConfigScript struct { + BinaryPath string `yaml:"binary"` + ScriptPath string `yaml:"script"` } func LoadConfig(path string) (*Config, error) { diff --git a/main.go b/main.go index e418d49..ace9d0b 100644 --- a/main.go +++ b/main.go @@ -1,31 +1,32 @@ package main import ( - "crypto/hmac" - "crypto/sha256" - "encoding/hex" "encoding/json" "fmt" "io" + "log" "net/http" "os" "os/exec" + "path" + "runtime" "gitea.urkob.com/urko/gitea-webhook-listener/kit/config" ) func main() { - cfg, err := config.LoadConfig(".configs/app.yml") + // Get root path + _, filename, _, _ := runtime.Caller(0) + cfg, err := config.LoadConfig(path.Join(path.Dir(filename), "configs", "app.yml")) if err != nil { - panic(err) + log.Fatalf("Error loading config: %v", err) } - http.HandleFunc("/payload", handlePayload(cfg.Secret, cfg.BinaryPath, cfg.ScriptPath)) + http.HandleFunc("/", handlePayload(cfg.Secret, cfg.Scripts)) http.ListenAndServe(fmt.Sprintf(":%d", cfg.Port), nil) } -func handlePayload(secret, binaryPath, scriptPath string) func(w http.ResponseWriter, r *http.Request) { +func handlePayload(secret string, scripts map[string]config.ConfigScript) func(w http.ResponseWriter, r *http.Request) { return (func(w http.ResponseWriter, r *http.Request) { - // Read the request body body, err := io.ReadAll(r.Body) if err != nil { @@ -34,12 +35,26 @@ func handlePayload(secret, binaryPath, scriptPath string) func(w http.ResponseWr } defer r.Body.Close() - // Verify the signature - if !verifySignature(body, r.Header.Get("X-Hub-Signature-256"), []byte(secret)) { + authHeader := r.Header.Get("Authorization") + log.Println("authHeader", authHeader) + if authHeader != secret { http.Error(w, "Signatures didn't match", http.StatusUnauthorized) return } + if !r.URL.Query().Has("project") { + http.Error(w, "", http.StatusBadRequest) + return + } + + project := r.URL.Query().Get("project") + scr, found := scripts[project] + if !found { + http.Error(w, "not found", http.StatusNotFound) + return + } + + log.Println("body", body) // Parse the JSON payload var payload interface{} err = json.Unmarshal(body, &payload) @@ -51,7 +66,7 @@ func handlePayload(secret, binaryPath, scriptPath string) func(w http.ResponseWr // TODO: Do something with the payload fmt.Fprintf(w, "I got some JSON: %v", payload) - if err := execute(binaryPath, scriptPath); err != nil { + if err := execute(scr.BinaryPath, scr.ScriptPath); err != nil { panic(err) } }) @@ -68,13 +83,3 @@ func execute(binaryPath, scriptPath string) error { return nil } - -func verifySignature(payload []byte, signature string, secret []byte) bool { - // Compute the expected signature - mac := hmac.New(sha256.New, secret) - mac.Write(payload) - expectedSignature := hex.EncodeToString(mac.Sum(nil)) - - // Compare the expected signature with the actual signature - return hmac.Equal([]byte(signature), []byte("sha256="+expectedSignature)) -}