+Github webhooks

This commit is contained in:
Simon Martens
2025-09-28 18:13:26 +02:00
parent 3b19ea94b6
commit 2bf6315f50
5 changed files with 27 additions and 18 deletions

View File

@@ -188,15 +188,7 @@ func (k *KGPZ) Routes(srv *fiber.App) error {
srv.Get(CITATION_URL, controllers.Get(CITATION_URL)) srv.Get(CITATION_URL, controllers.Get(CITATION_URL))
if k.Config.WebHookSecret != "" && k.Config.WebHookEndpoint != "" { if k.Config.WebHookSecret != "" && k.Config.WebHookEndpoint != "" {
handler, rc := controllers.PostWebhook(k.Config.WebHookSecret) srv.Post(k.Config.WebHookEndpoint, controllers.PostWebhook(k))
srv.Post(k.Config.WebHookEndpoint, handler)
go func() {
for signal := range rc {
if signal {
k.Pull()
}
}
}()
} }
return nil return nil
@@ -594,6 +586,10 @@ func (k *KGPZ) IsDebug() bool {
return k.Config.Debug return k.Config.Debug
} }
func (k *KGPZ) GetWebHookSecret() string {
return k.Config.WebHookSecret
}
func (k *KGPZ) Pull() { func (k *KGPZ) Pull() {
if k.Repo == nil { if k.Repo == nil {
return return

View File

@@ -38,9 +38,11 @@ func GetAgents(kgpz *xmlmodels.Library) fiber.Handler {
// Build available letters list (same logic as AgentsView) // Build available letters list (same logic as AgentsView)
av := make(map[string]bool) av := make(map[string]bool)
kgpz.Agents.Lock()
for _, agent := range kgpz.Agents.Array { for _, agent := range kgpz.Agents.Array {
av[strings.ToUpper(agent.ID[:1])] = true av[strings.ToUpper(agent.ID[:1])] = true
} }
kgpz.Agents.Unlock()
availableLetters := make([]string, 0, len(av)) availableLetters := make([]string, 0, len(av))
for letter := range av { for letter := range av {
availableLetters = append(availableLetters, letter) availableLetters = append(availableLetters, letter)

View File

@@ -69,6 +69,7 @@ func GetCategory(kgpz *xmlmodels.Library) fiber.Handler {
func findFirstYearForCategory(categoryID string, kgpz *xmlmodels.Library) int { func findFirstYearForCategory(categoryID string, kgpz *xmlmodels.Library) int {
categoryYears := make([]int, 0) categoryYears := make([]int, 0)
kgpz.Pieces.Lock()
for _, piece := range kgpz.Pieces.Array { for _, piece := range kgpz.Pieces.Array {
matchesCategory := false matchesCategory := false
@@ -100,6 +101,7 @@ func findFirstYearForCategory(categoryID string, kgpz *xmlmodels.Library) int {
} }
} }
} }
kgpz.Pieces.Unlock()
if len(categoryYears) == 0 { if len(categoryYears) == 0 {
return 0 // No pieces found for this category return 0 // No pieces found for this category

View File

@@ -11,11 +11,10 @@ import (
const SIGNATURE_PREFIX = "sha256=" const SIGNATURE_PREFIX = "sha256="
func PostWebhook(secret string) (fiber.Handler, chan bool) { func PostWebhook(kgpz WebhookInterface) func(c *fiber.Ctx) error {
devchan := make(chan bool)
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
body := c.Body() body := c.Body()
if !verifySignature256([]byte(secret), body, c.Get("X-Hub-Signature-256")) { if !verifySignature256([]byte(kgpz.GetWebHookSecret()), body, c.Get("X-Hub-Signature-256")) {
return c.SendStatus(fiber.StatusUnauthorized) return c.SendStatus(fiber.StatusUnauthorized)
} }
@@ -23,13 +22,17 @@ func PostWebhook(secret string) (fiber.Handler, chan bool) {
return c.SendStatus(fiber.StatusBadRequest) return c.SendStatus(fiber.StatusBadRequest)
} }
go func() { // Respond with 200 immediately, then process asynchronously
devchan <- true go kgpz.Pull()
}()
c.SendStatus(fiber.StatusOK) return c.SendStatus(fiber.StatusOK)
return nil }
}, devchan }
// KGPZInterface defines the interface needed by the webhook
type WebhookInterface interface {
GetWebHookSecret() string
Pull()
} }
func sign256(secret, body []byte) []byte { func sign256(secret, body []byte) []byte {

View File

@@ -72,6 +72,12 @@ func (c *ConfigProvider) Validate() error {
if strings.TrimSpace(c.Config.BaseDIR) == "" { if strings.TrimSpace(c.Config.BaseDIR) == "" {
return fmt.Errorf("Base directory path not set") return fmt.Errorf("Base directory path not set")
} }
// Validate webhook configuration: if endpoint is set, secret must also be set
if strings.TrimSpace(c.Config.WebHookEndpoint) != "" && strings.TrimSpace(c.Config.WebHookSecret) == "" {
return fmt.Errorf("WebHookSecret must be configured when WebHookEndpoint is set")
}
return nil return nil
} }