76 lines
1.7 KiB
Go
76 lines
1.7 KiB
Go
package handlers
|
|
|
|
import (
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
"git.eeqj.de/sneak/upaas/internal/models"
|
|
)
|
|
|
|
// maxWebhookBodySize is the maximum allowed size of a webhook request body (1MB).
|
|
const maxWebhookBodySize = 1 << 20
|
|
|
|
// HandleWebhook handles incoming Gitea webhooks.
|
|
func (h *Handlers) HandleWebhook() http.HandlerFunc {
|
|
return func(writer http.ResponseWriter, request *http.Request) {
|
|
secret := chi.URLParam(request, "secret")
|
|
if secret == "" {
|
|
http.NotFound(writer, request)
|
|
|
|
return
|
|
}
|
|
|
|
// Find app by webhook secret
|
|
application, findErr := models.FindAppByWebhookSecret(
|
|
request.Context(),
|
|
h.db,
|
|
secret,
|
|
)
|
|
if findErr != nil {
|
|
h.log.Error("failed to find app by webhook secret", "error", findErr)
|
|
http.Error(writer, "Internal Server Error", http.StatusInternalServerError)
|
|
|
|
return
|
|
}
|
|
|
|
if application == nil {
|
|
http.NotFound(writer, request)
|
|
|
|
return
|
|
}
|
|
|
|
// Read request body with size limit to prevent memory exhaustion
|
|
body, readErr := io.ReadAll(io.LimitReader(request.Body, maxWebhookBodySize))
|
|
if readErr != nil {
|
|
h.log.Error("failed to read webhook body", "error", readErr)
|
|
http.Error(writer, "Bad Request", http.StatusBadRequest)
|
|
|
|
return
|
|
}
|
|
|
|
// Get event type from header
|
|
eventType := request.Header.Get("X-Gitea-Event")
|
|
if eventType == "" {
|
|
eventType = "push"
|
|
}
|
|
|
|
// Process webhook
|
|
webhookErr := h.webhook.HandleWebhook(
|
|
request.Context(),
|
|
application,
|
|
eventType,
|
|
body,
|
|
)
|
|
if webhookErr != nil {
|
|
h.log.Error("failed to process webhook", "error", webhookErr)
|
|
http.Error(writer, "Internal Server Error", http.StatusInternalServerError)
|
|
|
|
return
|
|
}
|
|
|
|
writer.WriteHeader(http.StatusOK)
|
|
}
|
|
}
|