Remove what is about deploying behind Gitea (closes #209)
check / check (push) Successful in 3m30s
check / check (push) Successful in 3m30s
Delete the Gitea compose setup, its document, its two scripts and their make targets. Documents and tests no longer use Gitea as the example deployment. The Core Rule Set exclusions for Gitea's false positives in internal/waf stay, with their comments and tests. Model: opus-5-5
This commit is contained in:
@@ -39,7 +39,7 @@ const (
|
||||
ntfyURL = "https://ntfy.example/smallwebwaf-alerts"
|
||||
ntfyToken = "tk_0123456789abcdefghijklmnopq"
|
||||
// instance is the instance name every alert gives.
|
||||
instance = "fsn1app1/gitea"
|
||||
instance = "fsn1app1/blog"
|
||||
// started is when each test starts, as an alert gives it, and
|
||||
// anHourOn an hour later.
|
||||
started = "2000-01-01T00:00:00Z"
|
||||
@@ -965,8 +965,8 @@ func TestEachDestinationIsSentOnlyTheAlertsWaitingForIt(t *testing.T) {
|
||||
synctest.Wait()
|
||||
|
||||
wantBodies(t, standIns[alerts.DestinationSlack],
|
||||
`{"text":"*fsn1app1/gitea: file_error*\nsecond"}`,
|
||||
`{"text":"*fsn1app1/gitea: file_error*\nthird"}`)
|
||||
`{"text":"*fsn1app1/blog: file_error*\nsecond"}`,
|
||||
`{"text":"*fsn1app1/blog: file_error*\nthird"}`)
|
||||
wantBodies(t, standIns[alerts.DestinationNtfy], "fourth")
|
||||
|
||||
// alerts.json then lists Slack and ntfy alone, with no alert waiting.
|
||||
@@ -1265,7 +1265,7 @@ func anAlertForEachEvent() []eventMessage {
|
||||
Reason: "requests per hour over the limit of 10000",
|
||||
Detail: map[string]any{"mode": "observe"},
|
||||
},
|
||||
"fsn1app1/gitea: ban", "default no_entry",
|
||||
"fsn1app1/blog: ban", "default no_entry",
|
||||
"requests per hour over the limit of 10000\nclient: 203.0.113.9\n" +
|
||||
"netblock: 203.0.113.0/24\ncountry: DE\nmode: observe",
|
||||
},
|
||||
@@ -1275,7 +1275,7 @@ func anAlertForEachEvent() []eventMessage {
|
||||
Netblock: netip.MustParsePrefix("198.51.100.7/32"), Country: "FR",
|
||||
Reason: "matched the rule env-file",
|
||||
},
|
||||
"fsn1app1/gitea: permanent_ban", "high no_entry",
|
||||
"fsn1app1/blog: permanent_ban", "high no_entry",
|
||||
"matched the rule env-file\nclient: 198.51.100.7\n" +
|
||||
"netblock: 198.51.100.7/32\ncountry: FR",
|
||||
},
|
||||
@@ -1286,7 +1286,7 @@ func anAlertForEachEvent() []eventMessage {
|
||||
Reason: "refused by the Core Rule Set",
|
||||
Host: "app.example",
|
||||
},
|
||||
"fsn1app1/gitea: waf_block", "default shield",
|
||||
"fsn1app1/blog: waf_block", "default shield",
|
||||
"refused by the Core Rule Set\nhost: app.example\nclient: 192.0.2.1\n" +
|
||||
"netblock: 192.0.2.1/32",
|
||||
},
|
||||
@@ -1295,7 +1295,7 @@ func anAlertForEachEvent() []eventMessage {
|
||||
Event: alerts.EventAnomaly, Netblock: netip.MustParsePrefix("192.0.2.0/24"),
|
||||
Reason: "requests per minute over the threshold of 5000",
|
||||
},
|
||||
"fsn1app1/gitea: anomaly", "high chart_with_upwards_trend",
|
||||
"fsn1app1/blog: anomaly", "high chart_with_upwards_trend",
|
||||
"requests per minute over the threshold of 5000\nnetblock: 192.0.2.0/24",
|
||||
},
|
||||
{
|
||||
@@ -1304,7 +1304,7 @@ func anAlertForEachEvent() []eventMessage {
|
||||
Netblock: netip.MustParsePrefix("192.0.2.2/32"),
|
||||
Reason: "listed by a DNS blocklist",
|
||||
},
|
||||
"fsn1app1/gitea: reputation_hit", "low label",
|
||||
"fsn1app1/blog: reputation_hit", "low label",
|
||||
"listed by a DNS blocklist\nclient: 192.0.2.2\nnetblock: 192.0.2.2/32",
|
||||
},
|
||||
{
|
||||
@@ -1312,7 +1312,7 @@ func anAlertForEachEvent() []eventMessage {
|
||||
Event: alerts.EventSourceFailure, Reason: "asking GeoJS failed",
|
||||
Detail: map[string]any{"source": "geojs"},
|
||||
},
|
||||
"fsn1app1/gitea: source_failure", "high warning",
|
||||
"fsn1app1/blog: source_failure", "high warning",
|
||||
"asking GeoJS failed\nsource: geojs",
|
||||
},
|
||||
{
|
||||
@@ -1323,7 +1323,7 @@ func anAlertForEachEvent() []eventMessage {
|
||||
"file": "/etc/smallwebwaf/rules.d/50-app.rules", "error": "line 2: no action",
|
||||
},
|
||||
},
|
||||
"fsn1app1/gitea: file_error", "high warning",
|
||||
"fsn1app1/blog: file_error", "high warning",
|
||||
"a rule file has an error, and the rules stay as they were\n" +
|
||||
"file: /etc/smallwebwaf/rules.d/50-app.rules\nerror: line 2: no action",
|
||||
},
|
||||
|
||||
@@ -409,7 +409,7 @@ var (
|
||||
errNoCertificate = errors.New("holds no PEM certificate")
|
||||
errNotFacility = errors.New("is not a syslog facility such as local0 or daemon")
|
||||
errNotAppName = errors.New(
|
||||
"is not 1 to 48 printable ASCII characters without a space, such as gitea")
|
||||
"is not 1 to 48 printable ASCII characters without a space, such as blog")
|
||||
errSetTwice = errors.New("set only one of them")
|
||||
errNotWebhookURL = errors.New(
|
||||
"is not an http or https URL without a user or a fragment, " +
|
||||
|
||||
@@ -197,7 +197,7 @@ const (
|
||||
// instance is an SWWAF_INSTANCE_NAME that is a valid app name too, and
|
||||
// remoteURL an SWWAF_LOG_REMOTE_URL, for the tests that send the lines.
|
||||
const (
|
||||
instance = "fsn1app1/gitea"
|
||||
instance = "fsn1app1/blog"
|
||||
remoteURL = "syslog+udp://192.0.2.1:514"
|
||||
)
|
||||
|
||||
@@ -650,11 +650,11 @@ func TestInstanceNameAndLoggedHeadersAsSet(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg := fromEnvironment(t, environment{
|
||||
instanceName: "fsn1app1/gitea",
|
||||
instanceName: "fsn1app1/blog",
|
||||
logRequestHeaders: " Accept , X-Custom",
|
||||
})
|
||||
|
||||
if cfg.InstanceName != "fsn1app1/gitea" ||
|
||||
if cfg.InstanceName != "fsn1app1/blog" ||
|
||||
!slices.Equal(cfg.LogRequestHeaders, []string{"accept", "x-custom"}) {
|
||||
t.Errorf("%s is %q and %s gives %v", instanceName, cfg.InstanceName,
|
||||
logRequestHeaders, cfg.LogRequestHeaders)
|
||||
@@ -797,7 +797,7 @@ func TestInstanceNameNotAnAppNameStopsTheStartOnlyWhileSending(t *testing.T) {
|
||||
|
||||
want := logRemoteAppName + `: is unset, and ` + instanceName +
|
||||
` "fsn1 app1", its default, is not 1 to 48 printable ASCII characters ` +
|
||||
`without a space, such as gitea`
|
||||
`without a space, such as blog`
|
||||
if err == nil || err.Error() != want {
|
||||
t.Errorf("error %v, want %s", err, want)
|
||||
}
|
||||
@@ -826,7 +826,7 @@ func TestAppNameSetStopsTheStartWhileSending(t *testing.T) {
|
||||
}.lookupEnv)
|
||||
|
||||
want := logRemoteAppName + `: "my app" is not 1 to 48 printable ASCII ` +
|
||||
`characters without a space, such as gitea`
|
||||
`characters without a space, such as blog`
|
||||
if err == nil || err.Error() != want {
|
||||
t.Errorf("error %v, want %s", err, want)
|
||||
}
|
||||
@@ -2166,7 +2166,7 @@ func TestSettingFromFileIsCheckedAsTheSettingItself(t *testing.T) {
|
||||
}.lookupEnv)
|
||||
|
||||
want = logRemoteAppName + `: "my app" is not 1 to 48 printable ASCII ` +
|
||||
`characters without a space, such as gitea`
|
||||
`characters without a space, such as blog`
|
||||
if err == nil || err.Error() != want {
|
||||
t.Errorf("error %v, want %s", err, want)
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ import (
|
||||
const (
|
||||
// started is the time a record made as a test starts gives.
|
||||
started = "2000-01-01T00:00:00.000Z"
|
||||
appName = "fsn1app1/gitea"
|
||||
appName = "fsn1app1/blog"
|
||||
// local0 is the number of the default facility, and local0Info the
|
||||
// priority of its records.
|
||||
local0 = 16
|
||||
@@ -94,7 +94,7 @@ func TestRecordsOverTCPAreOctetCountedWithTheirFacility(t *testing.T) {
|
||||
endpoint := listen(t)
|
||||
endpointParams := params(remotelog.SchemeTCP, endpoint.Addr())
|
||||
endpointParams.Facility = 19 // local3
|
||||
endpointParams.AppName = "gitea"
|
||||
endpointParams.AppName = "blog"
|
||||
sender, _, _ := run(t, endpointParams)
|
||||
|
||||
_, _ = sender.Write([]byte("first\nsecond\n"))
|
||||
@@ -103,8 +103,8 @@ func TestRecordsOverTCPAreOctetCountedWithTheirFacility(t *testing.T) {
|
||||
wantCounts(t, sender, 2, 0, 0)
|
||||
|
||||
frames := bufio.NewReader(accept(t, endpoint))
|
||||
wantFrame(t, frames, record(t, "<158>", "gitea", "first"))
|
||||
wantFrame(t, frames, record(t, "<158>", "gitea", "second"))
|
||||
wantFrame(t, frames, record(t, "<158>", "blog", "first"))
|
||||
wantFrame(t, frames, record(t, "<158>", "blog", "second"))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ func TestProcessLinesAreMarkedProcessAndGiveTheInstance(t *testing.T) {
|
||||
|
||||
var out bytes.Buffer
|
||||
|
||||
requestlog.NewProcessLogger(&out, "fsn1app1/gitea", slog.LevelInfo).Info("starting",
|
||||
requestlog.NewProcessLogger(&out, "fsn1app1/blog", slog.LevelInfo).Info("starting",
|
||||
"version", "v1")
|
||||
|
||||
var fields map[string]any
|
||||
@@ -104,7 +104,7 @@ func TestProcessLinesAreMarkedProcessAndGiveTheInstance(t *testing.T) {
|
||||
t.Fatalf("decode %q: %v", out.String(), err)
|
||||
}
|
||||
|
||||
if fields["type"] != "process" || fields["instance"] != "fsn1app1/gitea" ||
|
||||
if fields["type"] != "process" || fields["instance"] != "fsn1app1/blog" ||
|
||||
fields["msg"] != "starting" || fields["level"] != "INFO" ||
|
||||
fields["version"] != "v1" {
|
||||
t.Errorf("process line %v", fields)
|
||||
@@ -133,7 +133,7 @@ func TestProcessLoggerWritesTheMessagesAtItsLevelOrMoreSevere(t *testing.T) {
|
||||
|
||||
var out bytes.Buffer
|
||||
|
||||
processLog := requestlog.NewProcessLogger(&out, "fsn1app1/gitea", level)
|
||||
processLog := requestlog.NewProcessLogger(&out, "fsn1app1/blog", level)
|
||||
for _, at := range levels {
|
||||
processLog.Log(t.Context(), at, "message")
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ const (
|
||||
alertWebhookURL = "SWWAF_ALERT_WEBHOOK_URL"
|
||||
alertMaxPerHour = "SWWAF_ALERT_MAX_PER_HOUR"
|
||||
// alertInstance is the instance every alert of these tests gives.
|
||||
alertInstance = "fsn1app1/gitea"
|
||||
alertInstance = "fsn1app1/blog"
|
||||
)
|
||||
|
||||
func TestBanForABrokenLimitRaisesABanAlertWithItsNotes(t *testing.T) {
|
||||
|
||||
@@ -19,7 +19,7 @@ const (
|
||||
// requestIDHeader carries the request's id.
|
||||
requestIDHeader = "X-Request-ID"
|
||||
// instance is the SWWAF_INSTANCE_NAME a test sets.
|
||||
instance = "fsn1app1/gitea"
|
||||
instance = "fsn1app1/blog"
|
||||
// ipv6Client is a client on IPv6, and ipv6Group the netblock the rate
|
||||
// limits count it as.
|
||||
ipv6Client = "2001:db8::7"
|
||||
|
||||
@@ -49,7 +49,7 @@ const (
|
||||
adminSecret = "fedcba9876543210fedcba9876543210"
|
||||
// instance is the SWWAF_INSTANCE_NAME the tests set where they look at
|
||||
// it.
|
||||
instance = "fsn1app1/gitea"
|
||||
instance = "fsn1app1/blog"
|
||||
// greeting is what the tests' app answers.
|
||||
greeting = "hello from the app"
|
||||
// placed is the client the tests' lookup databases place.
|
||||
@@ -341,8 +341,8 @@ func TestEveryLogLineAndMetricCarriesTheInstanceName(t *testing.T) {
|
||||
// the comments.
|
||||
for line := range strings.Lines(metrics) {
|
||||
if !strings.HasPrefix(line, "#") &&
|
||||
!strings.Contains(line, `instance="fsn1app1/gitea"`) {
|
||||
t.Errorf("series %q, without instance=\"fsn1app1/gitea\"", line)
|
||||
!strings.Contains(line, `instance="fsn1app1/blog"`) {
|
||||
t.Errorf("series %q, without instance=\"fsn1app1/blog\"", line)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -610,9 +610,9 @@ func TestLookupDatabaseReplacedWhileRunningTakesEffect(t *testing.T) {
|
||||
rename(t, replacement, path)
|
||||
|
||||
metrics := metricsWith(t, url+"_smallwebwaf/metrics", token,
|
||||
`smallwebwaf_lookup_database_read_failures_total{instance="fsn1app1/gitea"} 1`)
|
||||
`smallwebwaf_lookup_database_read_failures_total{instance="fsn1app1/blog"} 1`)
|
||||
lastRead = seriesValue(t, metrics,
|
||||
`smallwebwaf_lookup_database_last_read_timestamp_seconds{instance="fsn1app1/gitea"}`)
|
||||
`smallwebwaf_lookup_database_last_read_timestamp_seconds{instance="fsn1app1/blog"}`)
|
||||
|
||||
wantStatus(t, url, placed, http.StatusOK)
|
||||
})
|
||||
@@ -668,7 +668,7 @@ func TestBlocklistTriesAndCopiesKeptInReputationJSONAcrossRestarts(t *testing.T)
|
||||
// too.
|
||||
rateLimitExemptNets: placed + "," + localhost,
|
||||
}
|
||||
failures := `smallwebwaf_reputation_failures_total{instance="fsn1app1/gitea",` +
|
||||
failures := `smallwebwaf_reputation_failures_total{instance="fsn1app1/blog",` +
|
||||
`source="` + torURL + `"} `
|
||||
|
||||
// tor.txt cannot be fetched at first, which is counted.
|
||||
@@ -909,8 +909,8 @@ func TestStalledRemoteLogEndpointHoldsUpNoRequest(t *testing.T) {
|
||||
// last.
|
||||
metrics := metricsText(t, url+"_smallwebwaf/metrics", token)
|
||||
for _, series := range []string{
|
||||
`smallwebwaf_remote_log_lines_sent_total{instance="fsn1app1/gitea"} 0`,
|
||||
`smallwebwaf_remote_log_buffer_depth{instance="fsn1app1/gitea"} 1`,
|
||||
`smallwebwaf_remote_log_lines_sent_total{instance="fsn1app1/blog"} 0`,
|
||||
`smallwebwaf_remote_log_buffer_depth{instance="fsn1app1/blog"} 1`,
|
||||
} {
|
||||
if !strings.Contains(metrics, "\n"+series+"\n") {
|
||||
t.Errorf("no %q in the metrics:\n%s", series, metrics)
|
||||
@@ -918,7 +918,7 @@ func TestStalledRemoteLogEndpointHoldsUpNoRequest(t *testing.T) {
|
||||
}
|
||||
|
||||
const dropped = "\nsmallwebwaf_remote_log_lines_dropped_total" +
|
||||
`{instance="fsn1app1/gitea"} `
|
||||
`{instance="fsn1app1/blog"} `
|
||||
if strings.Contains(metrics, dropped+"0\n") || !strings.Contains(metrics, dropped) {
|
||||
t.Errorf("no line dropped in the metrics:\n%s", metrics)
|
||||
}
|
||||
@@ -1011,7 +1011,7 @@ func TestBanIsAlertedAndAnAlertNotSentIsKeptAcrossARestart(t *testing.T) {
|
||||
runUntilStopped(t, env, func(url string) {
|
||||
webhook.waitFor(t, "permanent_ban", true)
|
||||
|
||||
const ofWebhook = `{destination="webhook",instance="fsn1app1/gitea"}`
|
||||
const ofWebhook = `{destination="webhook",instance="fsn1app1/blog"}`
|
||||
|
||||
metrics := metricsWith(t, url+"_smallwebwaf/metrics", token,
|
||||
"\nsmallwebwaf_alerts_sent_total"+ofWebhook+" 1\n")
|
||||
@@ -1062,13 +1062,13 @@ func TestBanIsAlertedToSlackAndNtfy(t *testing.T) {
|
||||
slackPost := slack.firstPost(t)
|
||||
err := json.Unmarshal([]byte(slackPost.body), &message)
|
||||
|
||||
if err != nil || !strings.HasPrefix(message.Text, "*fsn1app1/gitea: ban*\n") ||
|
||||
if err != nil || !strings.HasPrefix(message.Text, "*fsn1app1/blog: ban*\n") ||
|
||||
!strings.Contains(message.Text, "\nclient: "+client+"\n") {
|
||||
t.Errorf("Slack was sent %s", slackPost.body)
|
||||
}
|
||||
|
||||
ntfyPost := ntfy.firstPost(t)
|
||||
if ntfyPost.header.Get("Title") != "fsn1app1/gitea: ban" ||
|
||||
if ntfyPost.header.Get("Title") != "fsn1app1/blog: ban" ||
|
||||
ntfyPost.header.Get("Authorization") != "Bearer "+ntfyToken ||
|
||||
!strings.Contains(ntfyPost.body, "\nclient: "+client+"\n") {
|
||||
t.Errorf("ntfy was sent %s, with the headers %v", ntfyPost.body,
|
||||
@@ -1080,9 +1080,9 @@ func TestBanIsAlertedToSlackAndNtfy(t *testing.T) {
|
||||
// test process cannot fail the test.
|
||||
sent := []string{
|
||||
"\nsmallwebwaf_alerts_sent_total{destination=\"slack\"," +
|
||||
"instance=\"fsn1app1/gitea\"} 1\n",
|
||||
"instance=\"fsn1app1/blog\"} 1\n",
|
||||
"\nsmallwebwaf_alerts_sent_total{destination=\"ntfy\"," +
|
||||
"instance=\"fsn1app1/gitea\"} 1\n",
|
||||
"instance=\"fsn1app1/blog\"} 1\n",
|
||||
}
|
||||
|
||||
metrics := metricsWith(t, url+"_smallwebwaf/metrics", token, sent...)
|
||||
|
||||
@@ -143,7 +143,7 @@ const filledAlertsJSON = `{
|
||||
"waiting": {
|
||||
"webhook": [
|
||||
{
|
||||
"instance": "fsn1app1/gitea",
|
||||
"instance": "fsn1app1/blog",
|
||||
"time": "2026-10-06T00:00:00Z",
|
||||
"event": "ban",
|
||||
"client": "203.0.113.9",
|
||||
@@ -158,7 +158,7 @@ const filledAlertsJSON = `{
|
||||
"suppressed_repeats": 0
|
||||
},
|
||||
{
|
||||
"instance": "fsn1app1/gitea",
|
||||
"instance": "fsn1app1/blog",
|
||||
"time": "2026-10-06T00:00:00Z",
|
||||
"event": "file_error",
|
||||
"client": "",
|
||||
@@ -1721,7 +1721,7 @@ func newParams(dir string) state.Params {
|
||||
Events: alerts.Events(),
|
||||
Cooldown: 15 * time.Minute,
|
||||
MaxPerHour: 2,
|
||||
Instance: "fsn1app1/gitea",
|
||||
Instance: "fsn1app1/blog",
|
||||
Now: midnight,
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user