[#6410] added rate limit option to exclude IPs/CIDR subnets
This commit is contained in:
+11
-3
@@ -290,7 +290,7 @@ func (s *Settings) PostValidate(ctx context.Context, app App) error {
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
return validation.ValidateStructWithContext(ctx, s,
|
||||
validation.Field(&s.SuperuserIPs, validation.Each(validation.By(validators.IPOrSubnet))),
|
||||
validation.Field(&s.SuperuserIPs, validation.Each(validation.Required, validation.By(validators.IPOrSubnet))),
|
||||
validation.Field(&s.Meta),
|
||||
validation.Field(&s.Logs),
|
||||
validation.Field(&s.SMTP),
|
||||
@@ -604,8 +604,9 @@ func (c TrustedProxyConfig) Validate() error {
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
type RateLimitsConfig struct {
|
||||
Rules []RateLimitRule `form:"rules" json:"rules"`
|
||||
Enabled bool `form:"enabled" json:"enabled"`
|
||||
Rules []RateLimitRule `form:"rules" json:"rules"`
|
||||
ExcludedIPs []string `form:"excludedIPs" json:"excludedIPs"`
|
||||
Enabled bool `form:"enabled" json:"enabled"`
|
||||
}
|
||||
|
||||
// FindRateLimitRule returns the first matching rule based on the provided labels.
|
||||
@@ -650,6 +651,9 @@ func (c RateLimitsConfig) MarshalJSON() ([]byte, error) {
|
||||
if c.Rules == nil {
|
||||
c.Rules = []RateLimitRule{}
|
||||
}
|
||||
if c.ExcludedIPs == nil {
|
||||
c.ExcludedIPs = []string{}
|
||||
}
|
||||
|
||||
return json.Marshal(alias(c))
|
||||
}
|
||||
@@ -662,6 +666,10 @@ func (c RateLimitsConfig) Validate() error {
|
||||
validation.When(c.Enabled, validation.Required),
|
||||
validation.By(checkUniqueRuleLabel),
|
||||
),
|
||||
validation.Field(
|
||||
&c.ExcludedIPs,
|
||||
validation.Each(validation.Required, validation.By(validators.IPOrSubnet)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ func TestSettings_DBExport(t *testing.T) {
|
||||
valueStr = string(export["value"].([]byte))
|
||||
}
|
||||
|
||||
expected := `{"superuserIPs":[],"smtp":{"enabled":false,"port":0,"host":"smtp_host","username":"smtp_username","password":"","authMethod":"","tls":false,"localName":""},"backups":{"cron":"* * * * *","cronMaxKeep":0,"s3":{"enabled":true,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false}},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"s3_endpoint","accessKey":"","secret":"s3_secret","forcePathStyle":false},"meta":{"accentColor":"","appName":"test_app_name","appURL":"","senderName":"","senderAddress":"","hideControls":false},"rateLimits":{"rules":[],"enabled":true},"trustedProxy":{"headers":[],"useLeftmostIP":true},"batch":{"enabled":false,"maxRequests":0,"timeout":15,"maxBodySize":0},"logs":{"maxDays":123,"minLevel":0,"logIP":false,"logAuthId":false}}`
|
||||
expected := `{"superuserIPs":[],"smtp":{"enabled":false,"port":0,"host":"smtp_host","username":"smtp_username","password":"","authMethod":"","tls":false,"localName":""},"backups":{"cron":"* * * * *","cronMaxKeep":0,"s3":{"enabled":true,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false}},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"s3_endpoint","accessKey":"","secret":"s3_secret","forcePathStyle":false},"meta":{"accentColor":"","appName":"test_app_name","appURL":"","senderName":"","senderAddress":"","hideControls":false},"rateLimits":{"rules":[],"excludedIPs":[],"enabled":true},"trustedProxy":{"headers":[],"useLeftmostIP":true},"batch":{"enabled":false,"maxRequests":0,"timeout":15,"maxBodySize":0},"logs":{"maxDays":123,"minLevel":0,"logIP":false,"logAuthId":false}}`
|
||||
if valueStr != expected {
|
||||
t.Fatalf("Expected exported settings\n%s\ngot\n%s", expected, valueStr)
|
||||
}
|
||||
@@ -180,7 +180,7 @@ func TestSettingsMarshalJSON(t *testing.T) {
|
||||
}
|
||||
rawStr := string(raw)
|
||||
|
||||
expected := `{"superuserIPs":[],"smtp":{"enabled":false,"port":0,"host":"","username":"abc","authMethod":"","tls":false,"localName":""},"backups":{"cron":"","cronMaxKeep":0,"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false}},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false},"meta":{"accentColor":"","appName":"test123","appURL":"","senderName":"","senderAddress":"","hideControls":false},"rateLimits":{"rules":[],"enabled":false},"trustedProxy":{"headers":[],"useLeftmostIP":false},"batch":{"enabled":false,"maxRequests":0,"timeout":0,"maxBodySize":0},"logs":{"maxDays":0,"minLevel":0,"logIP":false,"logAuthId":false}}`
|
||||
expected := `{"superuserIPs":[],"smtp":{"enabled":false,"port":0,"host":"","username":"abc","authMethod":"","tls":false,"localName":""},"backups":{"cron":"","cronMaxKeep":0,"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false}},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false},"meta":{"accentColor":"","appName":"test123","appURL":"","senderName":"","senderAddress":"","hideControls":false},"rateLimits":{"rules":[],"excludedIPs":[],"enabled":false},"trustedProxy":{"headers":[],"useLeftmostIP":false},"batch":{"enabled":false,"maxRequests":0,"timeout":0,"maxBodySize":0},"logs":{"maxDays":0,"minLevel":0,"logIP":false,"logAuthId":false}}`
|
||||
|
||||
if rawStr != expected {
|
||||
t.Fatalf("Expected\n%v\ngot\n%v", expected, rawStr)
|
||||
@@ -196,7 +196,7 @@ func TestSettingsValidate(t *testing.T) {
|
||||
s := app.Settings()
|
||||
|
||||
// set invalid settings data
|
||||
s.SuperuserIPs = []string{"127.0.0.1", "invalid"}
|
||||
s.SuperuserIPs = []string{"127.0.0.1", ""}
|
||||
s.Meta.AppName = ""
|
||||
s.Logs.MaxDays = -10
|
||||
s.SMTP.Enabled = true
|
||||
@@ -597,7 +597,8 @@ func TestRateLimitsConfigValidate(t *testing.T) {
|
||||
{
|
||||
"invalid data",
|
||||
core.RateLimitsConfig{
|
||||
Enabled: true,
|
||||
Enabled: true,
|
||||
ExcludedIPs: []string{"", "127.0.0.1"},
|
||||
Rules: []core.RateLimitRule{
|
||||
{
|
||||
Label: "/123abc/",
|
||||
@@ -611,12 +612,13 @@ func TestRateLimitsConfigValidate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
[]string{"rules"},
|
||||
[]string{"rules", "excludedIPs"},
|
||||
},
|
||||
{
|
||||
"valid data",
|
||||
core.RateLimitsConfig{
|
||||
Enabled: true,
|
||||
Enabled: true,
|
||||
ExcludedIPs: []string{"127.0.0.1", "10.0.0.1/20"},
|
||||
Rules: []core.RateLimitRule{
|
||||
{
|
||||
Label: "123_abc",
|
||||
|
||||
Reference in New Issue
Block a user