feat(config): add WEIGH action allowing admins to adjust request weight

Signed-off-by: Xe Iaso <me@xeiaso.net>
This commit is contained in:
Xe Iaso
2025-05-15 08:29:37 -04:00
parent 6a12efee08
commit 6e964e6449
6 changed files with 48 additions and 8 deletions

View File

@@ -39,6 +39,7 @@ const (
RuleAllow Rule = "ALLOW" RuleAllow Rule = "ALLOW"
RuleDeny Rule = "DENY" RuleDeny Rule = "DENY"
RuleChallenge Rule = "CHALLENGE" RuleChallenge Rule = "CHALLENGE"
RuleWeigh Rule = "WEIGH"
RuleBenchmark Rule = "DEBUG_BENCHMARK" RuleBenchmark Rule = "DEBUG_BENCHMARK"
) )
@@ -51,14 +52,15 @@ const (
) )
type BotConfig struct { type BotConfig struct {
UserAgentRegex *string `json:"user_agent_regex"` UserAgentRegex *string `json:"user_agent_regex,omitempty"`
PathRegex *string `json:"path_regex"` PathRegex *string `json:"path_regex,omitempty"`
HeadersRegex map[string]string `json:"headers_regex"` HeadersRegex map[string]string `json:"headers_regex,omitempty"`
Expression *ExpressionOrList `json:"expression"` Expression *ExpressionOrList `json:"expression,omitempty"`
Challenge *ChallengeRules `json:"challenge,omitempty"` Challenge *ChallengeRules `json:"challenge,omitempty"`
Weight *Weight `json:"weight,omitempty"`
Name string `json:"name"` Name string `json:"name"`
Action Rule `json:"action"` Action Rule `json:"action"`
RemoteAddr []string `json:"remote_addresses"` RemoteAddr []string `json:"remote_addresses,omitempty"`
} }
func (b BotConfig) Zero() bool { func (b BotConfig) Zero() bool {
@@ -150,7 +152,7 @@ func (b BotConfig) Valid() error {
} }
switch b.Action { switch b.Action {
case RuleAllow, RuleBenchmark, RuleChallenge, RuleDeny: case RuleAllow, RuleBenchmark, RuleChallenge, RuleDeny, RuleWeigh:
// okay // okay
default: default:
errs = append(errs, fmt.Errorf("%w: %q", ErrUnknownAction, b.Action)) errs = append(errs, fmt.Errorf("%w: %q", ErrUnknownAction, b.Action))
@@ -162,6 +164,10 @@ func (b BotConfig) Valid() error {
} }
} }
if b.Action == RuleWeigh && b.Weight == nil {
b.Weight = &Weight{Adjust: 5}
}
if len(errs) != 0 { if len(errs) != 0 {
return fmt.Errorf("config: bot entry for %q is not valid:\n%w", b.Name, errors.Join(errs...)) return fmt.Errorf("config: bot entry for %q is not valid:\n%w", b.Name, errors.Join(errs...))
} }

View File

@@ -182,6 +182,25 @@ func TestBotValid(t *testing.T) {
}, },
err: nil, err: nil,
}, },
{
name: "weight rule without weight",
bot: BotConfig{
Name: "weight-adjust-if-mozilla",
Action: RuleWeigh,
UserAgentRegex: p("Mozilla"),
},
},
{
name: "weight rule with weight adjust",
bot: BotConfig{
Name: "weight-adjust-if-mozilla",
Action: RuleWeigh,
UserAgentRegex: p("Mozilla"),
Weight: &Weight{
Adjust: 5,
},
},
},
} }
for _, cs := range tests { for _, cs := range tests {

View File

@@ -14,8 +14,8 @@ var (
type ExpressionOrList struct { type ExpressionOrList struct {
Expression string `json:"-"` Expression string `json:"-"`
All []string `json:"all"` All []string `json:"all,omitempty"`
Any []string `json:"any"` Any []string `json:"any,omitempty"`
} }
func (eol ExpressionOrList) Equal(rhs *ExpressionOrList) bool { func (eol ExpressionOrList) Equal(rhs *ExpressionOrList) bool {

View File

@@ -0,0 +1,6 @@
bots:
- name: simple-weight-adjust
action: WEIGH
user_agent_regex: Mozilla
weight:
adjust: 5

View File

@@ -0,0 +1,4 @@
bots:
- name: weight
action: WEIGH
user_agent_regex: Mozilla

View File

@@ -0,0 +1,5 @@
package config
type Weight struct {
Adjust int `json:"adjust"`
}