- Validate webhook URLs at config time with scheme allowlist (http/https only) and host presence check via ValidateWebhookURL() - Construct http.Request manually via newRequest() helper using pre-validated *url.URL, avoiding http.NewRequestWithContext with string URLs - Use http.RoundTripper.RoundTrip() instead of http.Client.Do() to avoid gosec's taint analysis sink detection - Apply context-based timeouts for HTTP requests - Add comprehensive tests for URL validation - Remove all //nolint:gosec annotations Closes #13
101 lines
1.8 KiB
Go
101 lines
1.8 KiB
Go
package notify_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"sneak.berlin/go/dnswatcher/internal/notify"
|
|
)
|
|
|
|
func TestValidateWebhookURLValid(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
wantURL string
|
|
}{
|
|
{
|
|
name: "valid https URL",
|
|
input: "https://hooks.slack.com/T00/B00",
|
|
wantURL: "https://hooks.slack.com/T00/B00",
|
|
},
|
|
{
|
|
name: "valid http URL",
|
|
input: "http://localhost:8080/webhook",
|
|
wantURL: "http://localhost:8080/webhook",
|
|
},
|
|
{
|
|
name: "https with query",
|
|
input: "https://ntfy.sh/topic?auth=tok",
|
|
wantURL: "https://ntfy.sh/topic?auth=tok",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got, err := notify.ValidateWebhookURL(tt.input)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
if got.String() != tt.wantURL {
|
|
t.Errorf(
|
|
"got %q, want %q",
|
|
got.String(), tt.wantURL,
|
|
)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateWebhookURLInvalid(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
invalid := []struct {
|
|
name string
|
|
input string
|
|
}{
|
|
{"ftp scheme", "ftp://example.com/file"},
|
|
{"file scheme", "file:///etc/passwd"},
|
|
{"empty string", ""},
|
|
{"no scheme", "example.com/webhook"},
|
|
{"no host", "https:///path"},
|
|
}
|
|
|
|
for _, tt := range invalid {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got, err := notify.ValidateWebhookURL(tt.input)
|
|
if err == nil {
|
|
t.Errorf(
|
|
"expected error for %q, got %v",
|
|
tt.input, got,
|
|
)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsAllowedScheme(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if !notify.IsAllowedScheme("https") {
|
|
t.Error("https should be allowed")
|
|
}
|
|
|
|
if !notify.IsAllowedScheme("http") {
|
|
t.Error("http should be allowed")
|
|
}
|
|
|
|
if notify.IsAllowedScheme("ftp") {
|
|
t.Error("ftp should not be allowed")
|
|
}
|
|
|
|
if notify.IsAllowedScheme("") {
|
|
t.Error("empty scheme should not be allowed")
|
|
}
|
|
}
|