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)
 | 
						|
}
 |