check / check (push) Waiting to run
A refused save on the target edit page now shows the edit form again, with the reason above it and every value submitted, instead of a bare text page; the status codes are unchanged. The webhook edit page keeps the submitted name, description and retention the same way, while the page still reports the stored retention. Target edits are validated by setTargetFromForm, which newTarget now uses too, so the add and edit forms accept and refuse the same things. An empty max_retries keeps the target's own count. The browser test also saves both edit pages with refused values. Its seeding and its table of target types move into helpers, leaving the test function a plain list of check calls. Model: opus-5-5
123 lines
3.1 KiB
Go
123 lines
3.1 KiB
Go
package handlers_test
|
|
|
|
import (
|
|
"html"
|
|
"net/http"
|
|
"net/url"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"sneak.berlin/go/webhooker/internal/database"
|
|
)
|
|
|
|
// privateRefusalHint is the sentence that tells an operator a private
|
|
// destination is refused on purpose, and how to allow one.
|
|
const privateRefusalHint = "Private and reserved addresses are " +
|
|
"refused by default; the server's ALLOWED_EGRESS_CIDRS setting " +
|
|
"allows named networks (see \"Allowing egress to your own " +
|
|
"network\" in the README)."
|
|
|
|
// TestTargetRefusal_PrivateDestinationSaysHowToAllowIt covers both
|
|
// target types that take a URL, on add and on edit.
|
|
func TestTargetRefusal_PrivateDestinationSaysHowToAllowIt(
|
|
t *testing.T,
|
|
) {
|
|
t.Parallel()
|
|
|
|
env := setupSourceTest(t)
|
|
|
|
targetTypes := []database.TargetType{
|
|
database.TargetTypeHTTP,
|
|
database.TargetTypeSlack,
|
|
}
|
|
|
|
for _, targetType := range targetTypes {
|
|
t.Run(string(targetType), func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
webhook := seedWebhookWithRetention(t, env.db, 30)
|
|
targetsPath := "/hook/" + webhook.ID + "/targets"
|
|
|
|
form := url.Values{}
|
|
form.Set("name", "private")
|
|
form.Set("type", string(targetType))
|
|
form.Set("url", editBlockedURL)
|
|
|
|
// A refused add shows the webhook page again, and a
|
|
// refused edit the edit page, where the hint is
|
|
// HTML-escaped.
|
|
added := serveTarget(
|
|
env, http.MethodPost, targetsPath, form,
|
|
)
|
|
assert.Equal(t, http.StatusBadRequest, added.Code)
|
|
assert.Contains(
|
|
t, added.Body.String(),
|
|
html.EscapeString(privateRefusalHint),
|
|
)
|
|
|
|
form.Set("url", editOriginalURL)
|
|
|
|
created := serveTarget(
|
|
env, http.MethodPost, targetsPath, form,
|
|
)
|
|
require.Equal(
|
|
t, http.StatusSeeOther, created.Code,
|
|
created.Body.String(),
|
|
)
|
|
|
|
targets := targetsForWebhook(t, env.db, webhook.ID)
|
|
require.Len(t, targets, 1)
|
|
|
|
form.Set("url", editBlockedURL)
|
|
|
|
edited := submitTargetEdit(
|
|
env, webhook.ID, targets[0].ID, form,
|
|
)
|
|
assert.Equal(t, http.StatusBadRequest, edited.Code)
|
|
assert.Contains(
|
|
t, edited.Body.String(),
|
|
html.EscapeString(privateRefusalHint),
|
|
)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestTargetRefusal_MetadataDestinationDoesNotSayHowToAllowIt: no
|
|
// setting opens a link-local address, and Azure's WireServer hands out
|
|
// VM credentials, so neither refusal points at the setting.
|
|
func TestTargetRefusal_MetadataDestinationDoesNotSayHowToAllowIt(
|
|
t *testing.T,
|
|
) {
|
|
t.Parallel()
|
|
|
|
env := setupSourceTest(t)
|
|
|
|
metadataURLs := map[string]string{
|
|
"link-local": "http://169.254.169.254/latest/meta-data/",
|
|
"wireserver": "http://168.63.129.16/?comp=versions",
|
|
}
|
|
|
|
for name, metadataURL := range metadataURLs {
|
|
t.Run(name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
webhook := seedWebhookWithRetention(t, env.db, 30)
|
|
|
|
form := url.Values{}
|
|
form.Set("name", "metadata")
|
|
form.Set("type", string(database.TargetTypeHTTP))
|
|
form.Set("url", metadataURL)
|
|
|
|
w := serveTarget(
|
|
env, http.MethodPost,
|
|
"/hook/"+webhook.ID+"/targets", form,
|
|
)
|
|
assert.Equal(t, http.StatusBadRequest, w.Code)
|
|
assert.NotContains(
|
|
t, w.Body.String(), privateRefusalHint,
|
|
)
|
|
})
|
|
}
|
|
}
|