summaryrefslogtreecommitdiffstats
path: root/internal/config/config_test.go
diff options
context:
space:
mode:
authorbndw <ben@bdw.to>2026-02-14 10:11:16 -0800
committerbndw <ben@bdw.to>2026-02-14 10:11:16 -0800
commit606e0a3329a3534a00889eee19c25e7d432f7d2d (patch)
tree526b1419eaa6b9b91126adbfa5990ec47f5d3a07 /internal/config/config_test.go
parenta90009e6b887a8a7ca67f49566af2caffb807776 (diff)
refactor: restructure auth config for better UX
Changed from flat structure to hierarchical read/write config: Before: auth: enabled: bool required: bool allowed_npubs_read: [] allowed_npubs_write: [] After: auth: read: enabled: bool allowed_npubs: [] write: enabled: bool allowed_npubs: [] Three states per operation: - enabled=false: no auth, allow all - enabled=true, allowed_npubs=[]: auth required, any valid signature - enabled=true, allowed_npubs=[...]: auth required, whitelist only Much clearer semantics and easier to reason about.
Diffstat (limited to 'internal/config/config_test.go')
-rw-r--r--internal/config/config_test.go102
1 files changed, 63 insertions, 39 deletions
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index c0d4555..65a742a 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -40,8 +40,10 @@ database:
40 path: "test.db" 40 path: "test.db"
41 41
42auth: 42auth:
43 enabled: true 43 read:
44 required: true 44 enabled: true
45 write:
46 enabled: true
45 timestamp_window: 120 47 timestamp_window: 120
46 48
47rate_limit: 49rate_limit:
@@ -75,12 +77,12 @@ metrics:
75 t.Errorf("expected db path test.db, got %s", cfg.Database.Path) 77 t.Errorf("expected db path test.db, got %s", cfg.Database.Path)
76 } 78 }
77 79
78 if !cfg.Auth.Enabled { 80 if !cfg.Auth.Read.Enabled {
79 t.Error("expected auth enabled") 81 t.Error("expected auth read enabled")
80 } 82 }
81 83
82 if !cfg.Auth.Required { 84 if !cfg.Auth.Write.Enabled {
83 t.Error("expected auth required") 85 t.Error("expected auth write enabled")
84 } 86 }
85 87
86 if cfg.Auth.TimestampWindow != 120 { 88 if cfg.Auth.TimestampWindow != 120 {
@@ -99,11 +101,13 @@ metrics:
99func TestEnvOverrides(t *testing.T) { 101func TestEnvOverrides(t *testing.T) {
100 // Set environment variables 102 // Set environment variables
101 os.Setenv("MUXSTR_SERVER_GRPC_ADDR", ":7777") 103 os.Setenv("MUXSTR_SERVER_GRPC_ADDR", ":7777")
102 os.Setenv("MUXSTR_AUTH_ENABLED", "true") 104 os.Setenv("MUXSTR_AUTH_READ_ENABLED", "true")
105 os.Setenv("MUXSTR_AUTH_WRITE_ENABLED", "true")
103 os.Setenv("MUXSTR_RATE_LIMIT_DEFAULT_RPS", "200") 106 os.Setenv("MUXSTR_RATE_LIMIT_DEFAULT_RPS", "200")
104 defer func() { 107 defer func() {
105 os.Unsetenv("MUXSTR_SERVER_GRPC_ADDR") 108 os.Unsetenv("MUXSTR_SERVER_GRPC_ADDR")
106 os.Unsetenv("MUXSTR_AUTH_ENABLED") 109 os.Unsetenv("MUXSTR_AUTH_READ_ENABLED")
110 os.Unsetenv("MUXSTR_AUTH_WRITE_ENABLED")
107 os.Unsetenv("MUXSTR_RATE_LIMIT_DEFAULT_RPS") 111 os.Unsetenv("MUXSTR_RATE_LIMIT_DEFAULT_RPS")
108 }() 112 }()
109 113
@@ -118,8 +122,12 @@ func TestEnvOverrides(t *testing.T) {
118 t.Errorf("expected env override :7777, got %s", cfg.Server.GrpcAddr) 122 t.Errorf("expected env override :7777, got %s", cfg.Server.GrpcAddr)
119 } 123 }
120 124
121 if !cfg.Auth.Enabled { 125 if !cfg.Auth.Read.Enabled {
122 t.Error("expected auth enabled from env") 126 t.Error("expected auth read enabled from env")
127 }
128
129 if !cfg.Auth.Write.Enabled {
130 t.Error("expected auth write enabled from env")
123 } 131 }
124 132
125 if cfg.RateLimit.DefaultRPS != 200 { 133 if cfg.RateLimit.DefaultRPS != 200 {
@@ -206,7 +214,8 @@ func TestSaveAndLoad(t *testing.T) {
206 // Create config 214 // Create config
207 cfg := Default() 215 cfg := Default()
208 cfg.Server.GrpcAddr = ":9999" 216 cfg.Server.GrpcAddr = ":9999"
209 cfg.Auth.Enabled = true 217 cfg.Auth.Read.Enabled = true
218 cfg.Auth.Write.Enabled = true
210 cfg.RateLimit.DefaultRPS = 100 219 cfg.RateLimit.DefaultRPS = 100
211 220
212 // Save to temp file 221 // Save to temp file
@@ -232,8 +241,12 @@ func TestSaveAndLoad(t *testing.T) {
232 t.Errorf("expected grpc_addr :9999, got %s", loaded.Server.GrpcAddr) 241 t.Errorf("expected grpc_addr :9999, got %s", loaded.Server.GrpcAddr)
233 } 242 }
234 243
235 if !loaded.Auth.Enabled { 244 if !loaded.Auth.Read.Enabled {
236 t.Error("expected auth enabled") 245 t.Error("expected auth read enabled")
246 }
247
248 if !loaded.Auth.Write.Enabled {
249 t.Error("expected auth write enabled")
237 } 250 }
238 251
239 if loaded.RateLimit.DefaultRPS != 100 { 252 if loaded.RateLimit.DefaultRPS != 100 {
@@ -259,12 +272,15 @@ database:
259 path: "test.db" 272 path: "test.db"
260 273
261auth: 274auth:
262 enabled: true 275 read:
263 allowed_npubs_read: 276 enabled: true
264 - npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6 277 allowed_npubs:
265 - npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqutajft 278 - npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6
266 allowed_npubs_write: 279 - npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqutajft
267 - npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6 280 write:
281 enabled: true
282 allowed_npubs:
283 - npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6
268` 284`
269 285
270 if _, err := tmpfile.Write([]byte(configData)); err != nil { 286 if _, err := tmpfile.Write([]byte(configData)); err != nil {
@@ -278,17 +294,17 @@ auth:
278 } 294 }
279 295
280 // Verify read npubs were normalized to hex 296 // Verify read npubs were normalized to hex
281 if len(cfg.Auth.AllowedNpubsRead) != 2 { 297 if len(cfg.Auth.Read.AllowedNpubs) != 2 {
282 t.Errorf("expected 2 allowed npubs for read, got %d", len(cfg.Auth.AllowedNpubsRead)) 298 t.Errorf("expected 2 allowed npubs for read, got %d", len(cfg.Auth.Read.AllowedNpubs))
283 } 299 }
284 300
285 // Verify write npubs were normalized to hex 301 // Verify write npubs were normalized to hex
286 if len(cfg.Auth.AllowedNpubsWrite) != 1 { 302 if len(cfg.Auth.Write.AllowedNpubs) != 1 {
287 t.Errorf("expected 1 allowed npub for write, got %d", len(cfg.Auth.AllowedNpubsWrite)) 303 t.Errorf("expected 1 allowed npub for write, got %d", len(cfg.Auth.Write.AllowedNpubs))
288 } 304 }
289 305
290 // Check that they're hex format (64 chars, not npub1...) 306 // Check that they're hex format (64 chars, not npub1...)
291 for i, pubkey := range cfg.Auth.AllowedNpubsRead { 307 for i, pubkey := range cfg.Auth.Read.AllowedNpubs {
292 if len(pubkey) != 64 { 308 if len(pubkey) != 64 {
293 t.Errorf("read npub %d: expected 64 hex chars, got %d", i, len(pubkey)) 309 t.Errorf("read npub %d: expected 64 hex chars, got %d", i, len(pubkey))
294 } 310 }
@@ -297,7 +313,7 @@ auth:
297 } 313 }
298 } 314 }
299 315
300 for i, pubkey := range cfg.Auth.AllowedNpubsWrite { 316 for i, pubkey := range cfg.Auth.Write.AllowedNpubs {
301 if len(pubkey) != 64 { 317 if len(pubkey) != 64 {
302 t.Errorf("write npub %d: expected 64 hex chars, got %d", i, len(pubkey)) 318 t.Errorf("write npub %d: expected 64 hex chars, got %d", i, len(pubkey))
303 } 319 }
@@ -310,14 +326,14 @@ auth:
310 expectedHex1 := "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d" 326 expectedHex1 := "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"
311 expectedHex2 := "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52" 327 expectedHex2 := "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"
312 328
313 if cfg.Auth.AllowedNpubsRead[0] != expectedHex1 { 329 if cfg.Auth.Read.AllowedNpubs[0] != expectedHex1 {
314 t.Errorf("read npub 0: expected %s, got %s", expectedHex1, cfg.Auth.AllowedNpubsRead[0]) 330 t.Errorf("read npub 0: expected %s, got %s", expectedHex1, cfg.Auth.Read.AllowedNpubs[0])
315 } 331 }
316 if cfg.Auth.AllowedNpubsRead[1] != expectedHex2 { 332 if cfg.Auth.Read.AllowedNpubs[1] != expectedHex2 {
317 t.Errorf("read npub 1: expected %s, got %s", expectedHex2, cfg.Auth.AllowedNpubsRead[1]) 333 t.Errorf("read npub 1: expected %s, got %s", expectedHex2, cfg.Auth.Read.AllowedNpubs[1])
318 } 334 }
319 if cfg.Auth.AllowedNpubsWrite[0] != expectedHex1 { 335 if cfg.Auth.Write.AllowedNpubs[0] != expectedHex1 {
320 t.Errorf("write npub 0: expected %s, got %s", expectedHex1, cfg.Auth.AllowedNpubsWrite[0]) 336 t.Errorf("write npub 0: expected %s, got %s", expectedHex1, cfg.Auth.Write.AllowedNpubs[0])
321 } 337 }
322} 338}
323 339
@@ -337,8 +353,10 @@ server:
337database: 353database:
338 path: "test.db" 354 path: "test.db"
339auth: 355auth:
340 allowed_npubs_read: 356 read:
341 - 3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d 357 enabled: true
358 allowed_npubs:
359 - 3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d
342`, 360`,
343 expectError: true, 361 expectError: true,
344 errorMsg: "must start with 'npub1'", 362 errorMsg: "must start with 'npub1'",
@@ -352,8 +370,10 @@ server:
352database: 370database:
353 path: "test.db" 371 path: "test.db"
354auth: 372auth:
355 allowed_npubs_write: 373 write:
356 - 3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d 374 enabled: true
375 allowed_npubs:
376 - 3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d
357`, 377`,
358 expectError: true, 378 expectError: true,
359 errorMsg: "must start with 'npub1'", 379 errorMsg: "must start with 'npub1'",
@@ -367,10 +387,14 @@ server:
367database: 387database:
368 path: "test.db" 388 path: "test.db"
369auth: 389auth:
370 allowed_npubs_read: 390 read:
371 - npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6 391 enabled: true
372 allowed_npubs_write: 392 allowed_npubs:
373 - npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqutajft 393 - npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6
394 write:
395 enabled: true
396 allowed_npubs:
397 - npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqutajft
374`, 398`,
375 expectError: false, 399 expectError: false,
376 }, 400 },