check / check (push) Successful in 3m16s
Refusing an http or slack target whose address is private or reserved, on add or edit, now adds one sentence: such addresses are refused by default, and the server's ALLOWED_EGRESS_CIDRS setting allows named networks, with a pointer to the README section. It suggests no value, so it never points at allowing everything. Metadata refusals get no such sentence. To tell them apart, the default blocklist's public addresses now have their own list, blockedPublicNetworks, still checked after the allowlist; a test pins which addresses each list refuses and how listing opens them, unchanged from before. Model: opus-5-5
117 rindas
2.9 KiB
Go
117 rindas
2.9 KiB
Go
package handlers_test
|
|
|
|
import (
|
|
"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)
|
|
|
|
added := serveTarget(
|
|
env, http.MethodPost, targetsPath, form,
|
|
)
|
|
assert.Equal(t, http.StatusBadRequest, added.Code)
|
|
assert.Contains(
|
|
t, added.Body.String(), 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(), 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,
|
|
)
|
|
})
|
|
}
|
|
}
|