aboutsummaryrefslogtreecommitdiff
path: root/cmd/anubis/internal/config/config.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/anubis/internal/config/config.go')
-rw-r--r--cmd/anubis/internal/config/config.go99
1 files changed, 99 insertions, 0 deletions
diff --git a/cmd/anubis/internal/config/config.go b/cmd/anubis/internal/config/config.go
new file mode 100644
index 0000000..ad338ef
--- /dev/null
+++ b/cmd/anubis/internal/config/config.go
@@ -0,0 +1,99 @@
+package config
+
+import (
+ "errors"
+ "fmt"
+ "regexp"
+)
+
+type Rule string
+
+const (
+ RuleUnknown = ""
+ RuleAllow = "ALLOW"
+ RuleDeny = "DENY"
+ RuleChallenge = "CHALLENGE"
+)
+
+type Bot struct {
+ Name string `json:"name"`
+ UserAgentRegex *string `json:"user_agent_regex"`
+ PathRegex *string `json:"path_regex"`
+ Action Rule `json:"action"`
+}
+
+var (
+ ErrNoBotRulesDefined = errors.New("config: must define at least one (1) bot rule")
+ ErrBotMustHaveName = errors.New("config.Bot: must set name")
+ ErrBotMustHaveUserAgentOrPath = errors.New("config.Bot: must set either user_agent_regex, path_regex")
+ ErrBotMustHaveUserAgentOrPathNotBoth = errors.New("config.Bot: must set either user_agent_regex, path_regex, and not both")
+ ErrUnknownAction = errors.New("config.Bot: unknown action")
+ ErrInvalidUserAgentRegex = errors.New("config.Bot: invalid user agent regex")
+ ErrInvalidPathRegex = errors.New("config.Bot: invalid path regex")
+)
+
+func (b Bot) Valid() error {
+ var errs []error
+
+ if b.Name == "" {
+ errs = append(errs, ErrBotMustHaveName)
+ }
+
+ if b.UserAgentRegex == nil && b.PathRegex == nil {
+ errs = append(errs, ErrBotMustHaveUserAgentOrPath)
+ }
+
+ if b.UserAgentRegex != nil && b.PathRegex != nil {
+ errs = append(errs, ErrBotMustHaveUserAgentOrPathNotBoth)
+ }
+
+ if b.UserAgentRegex != nil {
+ if _, err := regexp.Compile(*b.UserAgentRegex); err != nil {
+ errs = append(errs, ErrInvalidUserAgentRegex, err)
+ }
+ }
+
+ if b.PathRegex != nil {
+ if _, err := regexp.Compile(*b.PathRegex); err != nil {
+ errs = append(errs, ErrInvalidPathRegex, err)
+ }
+ }
+
+ switch b.Action {
+ case RuleAllow, RuleChallenge, RuleDeny:
+ // okay
+ default:
+ errs = append(errs, fmt.Errorf("%w: %q", ErrUnknownAction, b.Action))
+ }
+
+ if len(errs) != 0 {
+ return fmt.Errorf("config: bot entry for %q is not valid:\n%w", b.Name, errors.Join(errs...))
+ }
+
+ return nil
+}
+
+type Config struct {
+ Bots []Bot `json:"bots"`
+ DNSBL bool `json:"dnsbl"`
+}
+
+func (c Config) Valid() error {
+ var errs []error
+
+ if len(c.Bots) == 0 {
+ errs = append(errs, ErrNoBotRulesDefined)
+ }
+
+ for _, b := range c.Bots {
+ if err := b.Valid(); err != nil {
+ errs = append(errs, err)
+ }
+ }
+
+ if len(errs) != 0 {
+ return fmt.Errorf("config is not valid:\n%w", errors.Join(errs...))
+ }
+
+ return nil
+}