e2e/webhookweb_test.go
52 lines · 1906 bytes
1package e2e
2
3import (
4 "crypto/hmac"
5 "crypto/sha256"
6 "encoding/hex"
7 "net/url"
8 "strings"
9 "testing"
10)
11
12// TestWebhookSecretFromTheSettingsPage adds a webhook from the settings
13// page with a secret. The secret signs deliveries, and appears nowhere on
14// the resulting pages or in the command's listing (#296).
15func TestWebhookSecretFromTheSettingsPage(t *testing.T) {
16 t.Parallel()
17 inst := startInstanceWith(t, "[web]\nmode = \"accounts\"\n[webhooks]\nallow_local = true\n")
18 aliceKey := inst.newKey(t, "alice")
19 inst.admin(t, "admin", "user", "create", "alice",
20 "--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
21 if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/proj"); code != 0 {
22 t.Fatalf("repo create: %s", errOut)
23 }
24 alice := inst.login(t, aliceKey)
25 recv := startHookReceiver(t)
26 const secret = "form-secret-9d2f"
27
28 status, body := browserPost(t, alice, inst.base()+"/alice/proj/settings", url.Values{
29 "field": {"webhook-add"}, "url": {"http://" + recv.addr + "/hook"},
30 "events": {"issue.created"}, "secret": {secret},
31 })
32 if status != 200 || strings.Contains(body, secret) || !strings.Contains(body, "signed") {
33 t.Fatalf("add: %d\n%s", status, body)
34 }
35 if _, body = browserGet(t, alice, inst.base()+"/alice/proj/settings"); strings.Contains(body, secret) {
36 t.Fatal("secret on the settings page")
37 }
38 out, _, _ := inst.ssh(t, aliceKey, "", "webhook", "list", "alice/proj", "--json")
39 if strings.Contains(out, secret) {
40 t.Fatalf("secret in webhook list: %s", out)
41 }
42
43 if _, errOut, code := inst.ssh(t, aliceKey, "", "issue", "create", "alice/proj", "--title", "'hook me'"); code != 0 {
44 t.Fatalf("issue create: %s", errOut)
45 }
46 h := recv.waitN(t, 1)[0]
47 mac := hmac.New(sha256.New, []byte(secret))
48 mac.Write(h.body)
49 if h.signature != "sha256="+hex.EncodeToString(mac.Sum(nil)) {
50 t.Fatalf("HMAC mismatch: %s", h.signature)
51 }
52}