Add Gitea, Cloudflare DNS, and Kubernetes deployer adapters following hexagonal architecture. These enable automated project provisioning: - Git repository creation/management via Gitea - DNS record management via Cloudflare - Container deployment to Kubernetes Includes domain models, ports, handlers, and Woodpecker CI webhook integration for automated deployments on push. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
86 lines
2.6 KiB
Go
86 lines
2.6 KiB
Go
package handlers
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"testing"
|
|
)
|
|
|
|
func TestVerifySignature_ValidSignature(t *testing.T) {
|
|
h := &WoodpeckerWebhookHandler{webhookSecret: "test-secret"}
|
|
body := []byte(`{"event":"push","repo":{"name":"test"},"build":{"status":"success"}}`)
|
|
|
|
// Generate a valid signature
|
|
mac := hmac.New(sha256.New, []byte("test-secret"))
|
|
mac.Write(body)
|
|
signature := "sha256=" + hex.EncodeToString(mac.Sum(nil))
|
|
|
|
if !h.verifySignature(body, signature) {
|
|
t.Error("expected valid signature to pass verification")
|
|
}
|
|
}
|
|
|
|
func TestVerifySignature_InvalidSignature(t *testing.T) {
|
|
h := &WoodpeckerWebhookHandler{webhookSecret: "test-secret"}
|
|
body := []byte(`{"event":"push","repo":{"name":"test"},"build":{"status":"success"}}`)
|
|
|
|
if h.verifySignature(body, "sha256=invalid") {
|
|
t.Error("expected invalid signature to fail verification")
|
|
}
|
|
}
|
|
|
|
func TestVerifySignature_EmptySignature(t *testing.T) {
|
|
h := &WoodpeckerWebhookHandler{webhookSecret: "test-secret"}
|
|
body := []byte(`{"event":"push"}`)
|
|
|
|
if h.verifySignature(body, "") {
|
|
t.Error("expected empty signature to fail verification")
|
|
}
|
|
}
|
|
|
|
func TestVerifySignature_WrongSecret(t *testing.T) {
|
|
h := &WoodpeckerWebhookHandler{webhookSecret: "test-secret"}
|
|
body := []byte(`{"event":"push"}`)
|
|
|
|
// Generate signature with different secret
|
|
mac := hmac.New(sha256.New, []byte("wrong-secret"))
|
|
mac.Write(body)
|
|
signature := "sha256=" + hex.EncodeToString(mac.Sum(nil))
|
|
|
|
if h.verifySignature(body, signature) {
|
|
t.Error("expected signature with wrong secret to fail verification")
|
|
}
|
|
}
|
|
|
|
func TestVerifySignature_WithoutPrefix(t *testing.T) {
|
|
h := &WoodpeckerWebhookHandler{webhookSecret: "test-secret"}
|
|
body := []byte(`{"event":"push"}`)
|
|
|
|
// Generate valid signature without sha256= prefix
|
|
mac := hmac.New(sha256.New, []byte("test-secret"))
|
|
mac.Write(body)
|
|
signature := hex.EncodeToString(mac.Sum(nil))
|
|
|
|
// Should still work - we strip the prefix
|
|
if !h.verifySignature(body, signature) {
|
|
t.Error("expected signature without prefix to pass verification")
|
|
}
|
|
}
|
|
|
|
func TestVerifySignature_TamperedBody(t *testing.T) {
|
|
h := &WoodpeckerWebhookHandler{webhookSecret: "test-secret"}
|
|
originalBody := []byte(`{"event":"push","repo":{"name":"test"}}`)
|
|
tamperedBody := []byte(`{"event":"push","repo":{"name":"hacked"}}`)
|
|
|
|
// Generate signature for original body
|
|
mac := hmac.New(sha256.New, []byte("test-secret"))
|
|
mac.Write(originalBody)
|
|
signature := "sha256=" + hex.EncodeToString(mac.Sum(nil))
|
|
|
|
// Verify against tampered body should fail
|
|
if h.verifySignature(tamperedBody, signature) {
|
|
t.Error("expected tampered body to fail verification")
|
|
}
|
|
}
|