mirror of
https://github.com/Theodor-Springmann-Stiftung/kgpz_web.git
synced 2025-10-29 09:05:30 +00:00
+Github webhooks
This commit is contained in:
14
app/kgpz.go
14
app/kgpz.go
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user