summaryrefslogtreecommitdiffstats
path: root/internal/config/config.go
diff options
context:
space:
mode:
authorbndw <ben@bdw.to>2026-02-14 12:14:19 -0800
committerbndw <ben@bdw.to>2026-02-14 12:14:19 -0800
commitea4f508f5ee91b370c6912cde26b1a432380d037 (patch)
tree79081398bc0da1db76c28de6de04ed88a5e53bc3 /internal/config/config.go
parent4fc493e6d8cc20137f920f8647e39fc5051bb245 (diff)
feat: integrate config system into relay main.go
Add support for loading configuration from YAML file via -config flag. Wire up auth, rate limiting, and metrics interceptors based on config. Changes: - Add -config flag to relay command - Use config types directly in auth package (AuthOperationConfig) - Add conversion methods: RateLimitConfig.ToRateLimiter(), MetricsConfig.ToMetrics() - Add Metrics.Serve() method for prometheus HTTP endpoint - Update main.go to initialize interceptors from config - Fix type naming: OperationAuthConfig -> AuthOperationConfig for consistency Config now supports complete relay setup including auth read/write allowlists, rate limiting, and prometheus metrics.
Diffstat (limited to 'internal/config/config.go')
-rw-r--r--internal/config/config.go75
1 files changed, 61 insertions, 14 deletions
diff --git a/internal/config/config.go b/internal/config/config.go
index 36c8be5..dcceade 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -7,6 +7,9 @@ import (
7 "time" 7 "time"
8 8
9 "gopkg.in/yaml.v3" 9 "gopkg.in/yaml.v3"
10 "northwest.io/muxstr/internal/auth"
11 "northwest.io/muxstr/internal/metrics"
12 "northwest.io/muxstr/internal/ratelimit"
10 "northwest.io/nostr" 13 "northwest.io/nostr"
11) 14)
12 15
@@ -33,18 +36,10 @@ type DatabaseConfig struct {
33} 36}
34 37
35type AuthConfig struct { 38type AuthConfig struct {
36 Read AuthOperationConfig `yaml:"read"` 39 Read auth.AuthOperationConfig `yaml:"read"`
37 Write AuthOperationConfig `yaml:"write"` 40 Write auth.AuthOperationConfig `yaml:"write"`
38 TimestampWindow int64 `yaml:"timestamp_window"` 41 TimestampWindow int64 `yaml:"timestamp_window"`
39 SkipMethods []string `yaml:"skip_methods"` 42 SkipMethods []string `yaml:"skip_methods"`
40}
41
42// AuthOperationConfig configures auth for read or write operations.
43// Three states: disabled (allow all), enabled with empty list (require auth),
44// enabled with npubs (whitelist only). Npubs normalized to hex at load time.
45type AuthOperationConfig struct {
46 Enabled bool `yaml:"enabled"`
47 AllowedNpubs []string `yaml:"allowed_npubs"`
48} 43}
49 44
50type RateLimitConfig struct { 45type RateLimitConfig struct {
@@ -105,11 +100,11 @@ func Default() *Config {
105 Path: "relay.db", 100 Path: "relay.db",
106 }, 101 },
107 Auth: AuthConfig{ 102 Auth: AuthConfig{
108 Read: AuthOperationConfig{ 103 Read: auth.AuthOperationConfig{
109 Enabled: false, 104 Enabled: false,
110 AllowedNpubs: nil, 105 AllowedNpubs: nil,
111 }, 106 },
112 Write: AuthOperationConfig{ 107 Write: auth.AuthOperationConfig{
113 Enabled: false, 108 Enabled: false,
114 AllowedNpubs: nil, 109 AllowedNpubs: nil,
115 }, 110 },
@@ -349,3 +344,55 @@ func (c *Config) Save(filename string) error {
349 344
350 return nil 345 return nil
351} 346}
347
348func (r *RateLimitConfig) ToRateLimiter() *ratelimit.Config {
349 rlConfig := &ratelimit.Config{
350 RequestsPerSecond: r.DefaultRPS,
351 BurstSize: r.DefaultBurst,
352 IPRequestsPerSecond: r.IPRPS,
353 IPBurstSize: r.IPBurst,
354 SkipMethods: r.SkipMethods,
355 SkipUsers: r.SkipUsers,
356 CleanupInterval: r.CleanupInterval,
357 MaxIdleTime: r.MaxIdleTime,
358 }
359
360 if r.Methods != nil {
361 rlConfig.MethodLimits = make(map[string]ratelimit.MethodLimit, len(r.Methods))
362 for method, limit := range r.Methods {
363 rlConfig.MethodLimits[method] = ratelimit.MethodLimit{
364 RequestsPerSecond: limit.RPS,
365 BurstSize: limit.Burst,
366 }
367 }
368 }
369
370 if r.Users != nil {
371 rlConfig.UserLimits = make(map[string]ratelimit.UserLimit, len(r.Users))
372 for user, limit := range r.Users {
373 userLimit := ratelimit.UserLimit{
374 RequestsPerSecond: limit.RPS,
375 BurstSize: limit.Burst,
376 }
377 if limit.Methods != nil {
378 userLimit.MethodLimits = make(map[string]ratelimit.MethodLimit, len(limit.Methods))
379 for method, methodLimit := range limit.Methods {
380 userLimit.MethodLimits[method] = ratelimit.MethodLimit{
381 RequestsPerSecond: methodLimit.RPS,
382 BurstSize: methodLimit.Burst,
383 }
384 }
385 }
386 rlConfig.UserLimits[user] = userLimit
387 }
388 }
389
390 return rlConfig
391}
392
393func (m *MetricsConfig) ToMetrics() *metrics.Config {
394 return &metrics.Config{
395 Namespace: m.Namespace,
396 Subsystem: m.Subsystem,
397 }
398}