forgejo-tickets/internal/forgejo/webhook.go

53 lines
1.1 KiB
Go

package forgejo
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/http"
)
type WebhookPayload struct {
Action string `json:"action"`
Issue WebhookIssue `json:"issue"`
}
type WebhookIssue struct {
Number int64 `json:"number"`
Title string `json:"title"`
State string `json:"state"`
}
func VerifyWebhookSignature(r *http.Request, secret string) ([]byte, error) {
signature := r.Header.Get("X-Forgejo-Signature")
if signature == "" {
return nil, fmt.Errorf("missing X-Forgejo-Signature header")
}
body, err := io.ReadAll(r.Body)
if err != nil {
return nil, fmt.Errorf("read body: %w", err)
}
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
expectedMAC := hex.EncodeToString(mac.Sum(nil))
if !hmac.Equal([]byte(signature), []byte(expectedMAC)) {
return nil, fmt.Errorf("invalid signature")
}
return body, nil
}
func ParseWebhookPayload(data []byte) (*WebhookPayload, error) {
var payload WebhookPayload
if err := json.Unmarshal(data, &payload); err != nil {
return nil, fmt.Errorf("parse webhook payload: %w", err)
}
return &payload, nil
}