98 lines
2.9 KiB
Go
98 lines
2.9 KiB
Go
package forgejo
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func signBody(body, secret string) string {
|
|
mac := hmac.New(sha256.New, []byte(secret))
|
|
_, _ = mac.Write([]byte(body))
|
|
return hex.EncodeToString(mac.Sum(nil))
|
|
}
|
|
|
|
func TestVerifyAndParseWithForgejoHeaders(t *testing.T) {
|
|
secret := "supersecret"
|
|
body := `{"action":"closed","issue":{"number":7,"title":"[Cairn] crash"}}`
|
|
req := httptest.NewRequest("POST", "/webhooks/forgejo", strings.NewReader(body))
|
|
req.Header.Set("X-Forgejo-Event", "issues")
|
|
req.Header.Set("X-Forgejo-Signature", signBody(body, secret))
|
|
|
|
event, eventType, err := VerifyAndParse(req, secret)
|
|
if err != nil {
|
|
t.Fatalf("VerifyAndParse returned error: %v", err)
|
|
}
|
|
if eventType != "issues" {
|
|
t.Fatalf("expected event type issues, got %q", eventType)
|
|
}
|
|
if event == nil || event.Issue == nil || event.Issue.Number != 7 {
|
|
t.Fatalf("unexpected parsed event: %#v", event)
|
|
}
|
|
}
|
|
|
|
func TestVerifyAndParseWithGiteaFallbackHeaders(t *testing.T) {
|
|
secret := "fallbacksecret"
|
|
body := `{"action":"reopened","issue":{"number":42,"title":"[Cairn] crash"}}`
|
|
req := httptest.NewRequest("POST", "/webhooks/forgejo", strings.NewReader(body))
|
|
req.Header.Set("X-Gitea-Event", "issues")
|
|
req.Header.Set("X-Gitea-Signature", signBody(body, secret))
|
|
|
|
event, eventType, err := VerifyAndParse(req, secret)
|
|
if err != nil {
|
|
t.Fatalf("VerifyAndParse returned error: %v", err)
|
|
}
|
|
if eventType != "issues" {
|
|
t.Fatalf("expected event type issues, got %q", eventType)
|
|
}
|
|
if event == nil || event.Issue == nil || event.Issue.Number != 42 {
|
|
t.Fatalf("unexpected parsed event: %#v", event)
|
|
}
|
|
}
|
|
|
|
func TestVerifyAndParseRejectsBadSignature(t *testing.T) {
|
|
secret := "supersecret"
|
|
body := `{"action":"closed"}`
|
|
req := httptest.NewRequest("POST", "/webhooks/forgejo", strings.NewReader(body))
|
|
req.Header.Set("X-Forgejo-Event", "issues")
|
|
req.Header.Set("X-Forgejo-Signature", "bad-signature")
|
|
|
|
_, _, err := VerifyAndParse(req, secret)
|
|
if err == nil {
|
|
t.Fatal("expected error for bad signature, got nil")
|
|
}
|
|
}
|
|
|
|
func TestVerifyAndParseWithoutSecretSkipsHMAC(t *testing.T) {
|
|
body := `{"action":"closed"}`
|
|
req := httptest.NewRequest("POST", "/webhooks/forgejo", strings.NewReader(body))
|
|
req.Header.Set("X-Forgejo-Event", "issues")
|
|
|
|
event, eventType, err := VerifyAndParse(req, "")
|
|
if err != nil {
|
|
t.Fatalf("VerifyAndParse returned error: %v", err)
|
|
}
|
|
if eventType != "issues" {
|
|
t.Fatalf("expected event type issues, got %q", eventType)
|
|
}
|
|
if event == nil || event.Action != "closed" {
|
|
t.Fatalf("unexpected parsed event: %#v", event)
|
|
}
|
|
}
|
|
|
|
func TestVerifyHMAC(t *testing.T) {
|
|
body := []byte("payload")
|
|
secret := "abc123"
|
|
sig := signBody(string(body), secret)
|
|
|
|
if !verifyHMAC(body, sig, secret) {
|
|
t.Fatal("expected verifyHMAC to accept valid signature")
|
|
}
|
|
if verifyHMAC(body, "invalid", secret) {
|
|
t.Fatal("expected verifyHMAC to reject invalid signature")
|
|
}
|
|
}
|