92 lines
2.3 KiB
Go
92 lines
2.3 KiB
Go
// Copyright (C) 2024 Umorpha Systems
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"os/exec"
|
|
"sort"
|
|
|
|
"git.mothstuff.lol/lukeshu/eclipse/lib/apikeys"
|
|
)
|
|
|
|
type Webhooks struct {
|
|
pubKey apikeys.PublicKey
|
|
cfgFile string
|
|
}
|
|
|
|
func (o *Webhooks) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
if err := o.serveHTTP(w, r); err != nil {
|
|
if err.Code != -100 {
|
|
http.Error(w, err.Error(), err.Code)
|
|
}
|
|
if err.Code/100 == 5 {
|
|
log.Printf("error: %q: %v", r.URL, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
var webhooks = map[string]func(cfg *Webhooks, w http.ResponseWriter, r *http.Request) *_httpError{
|
|
"from-gitea": func(cfg *Webhooks, w http.ResponseWriter, r *http.Request) *_httpError {
|
|
if r.Method != http.MethodPost {
|
|
return httpError(errors.New("only POST is supported"), http.StatusMethodNotAllowed)
|
|
}
|
|
if err := requireAuthorization(cfg.pubKey, w, r); err != nil {
|
|
return err
|
|
}
|
|
payloadBytes, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
return httpError(err, http.StatusBadRequest)
|
|
}
|
|
var payload struct {
|
|
Repository struct {
|
|
SSHURL string `json:"ssh_url"`
|
|
CloneURL string `json:"clone_url"`
|
|
} `json:"repository"`
|
|
}
|
|
if err := json.Unmarshal(payloadBytes, &payload); err != nil {
|
|
return httpError(err, http.StatusBadRequest)
|
|
}
|
|
|
|
cmd := exec.CommandContext(r.Context(), "eclipse-trigger",
|
|
"--config="+cfg.cfgFile,
|
|
"--",
|
|
payload.Repository.SSHURL,
|
|
payload.Repository.CloneURL)
|
|
cmd.Stdout = w
|
|
cmd.Stderr = w
|
|
if err := cmd.Run(); err != nil {
|
|
return httpError(err, http.StatusInternalServerError)
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var tmplWebhooks = pageTemplate("webhooks.html.tmpl")
|
|
|
|
func (o *Webhooks) serveHTTP(w http.ResponseWriter, r *http.Request) *_httpError {
|
|
if r.URL.Path == "" {
|
|
if r.Method != http.MethodGet {
|
|
return httpError(errors.New("only GET is supported"), http.StatusMethodNotAllowed)
|
|
}
|
|
names := make([]string, 0, len(webhooks))
|
|
for name := range webhooks {
|
|
names = append(names, name)
|
|
}
|
|
sort.Strings(names)
|
|
if err := tmplWebhooks.Execute(w, map[string]any{"Webhooks": names}); err != nil {
|
|
return writeOrServerError(err)
|
|
}
|
|
}
|
|
callback := webhooks[r.URL.Path]
|
|
if callback == nil {
|
|
return httpNotFound()
|
|
}
|
|
return callback(o, w, r)
|
|
}
|