cloudflare-native port of the tangled knot server
22

Configure Feed

Select the types of activity you want to include in your feed.

rbac: thread dbdrv.Config through NewEnforcer

Patch category: aerie-distribution

Jer Miller (May 27, 2026, 8:25 PM -0600) 4f022ee7 62392270

+88 -11
+2 -1
appview/ingester_repo_test.go
··· 18 18 "tangled.org/core/appview/models" 19 19 "tangled.org/core/appview/notify" 20 20 "tangled.org/core/appview/repoverify" 21 + "tangled.org/core/dbdrv" 21 22 "tangled.org/core/orm" 22 23 "tangled.org/core/rbac" 23 24 ) ··· 70 71 t.Fatalf("db.Make: %v", err) 71 72 } 72 73 t.Cleanup(func() { d.Close() }) 73 - enforcer, err := rbac.NewEnforcer(path) 74 + enforcer, err := rbac.NewEnforcer(dbdrv.Config{Backend: "sqlite", Path: path}) 74 75 if err != nil { 75 76 t.Fatalf("rbac.NewEnforcer: %v", err) 76 77 }
+2 -1
appview/state/state.go
··· 33 33 "tangled.org/core/appview/validator" 34 34 xrpcclient "tangled.org/core/appview/xrpcclient" 35 35 "tangled.org/core/consts" 36 + "tangled.org/core/dbdrv" 36 37 "tangled.org/core/eventconsumer" 37 38 "tangled.org/core/idresolver" 38 39 "tangled.org/core/jetstream" ··· 86 87 return nil, fmt.Errorf("failed to create indexer: %w", err) 87 88 } 88 89 89 - enforcer, err := rbac.NewEnforcer(config.Core.DbPath) 90 + enforcer, err := rbac.NewEnforcer(dbdrv.Config{Backend: "sqlite", Path: config.Core.DbPath}) 90 91 if err != nil { 91 92 return nil, fmt.Errorf("failed to create enforcer: %w", err) 92 93 }
+1 -1
knotserver/git_receive_pack_test.go
··· 58 58 } 59 59 commits := seedBareRepo(t, repoPath) 60 60 61 - enforcer, err := rbac.NewEnforcer(dbPath) 61 + enforcer, err := rbac.NewEnforcer(dbConfig) 62 62 if err != nil { 63 63 t.Fatalf("rbac.NewEnforcer: %v", err) 64 64 }
+3 -2
knotserver/ingester_repo_test.go
··· 77 77 t.Helper() 78 78 scanPath := t.TempDir() 79 79 dbPath := filepath.Join(scanPath, "knot.db") 80 - d, err := db.Setup(context.Background(), dbdrv.Config{Backend: "sqlite", Path: dbPath}, "") 80 + dbConfig := dbdrv.Config{Backend: "sqlite", Path: dbPath} 81 + d, err := db.Setup(context.Background(), dbConfig, "") 81 82 if err != nil { 82 83 t.Fatalf("db.Setup: %v", err) 83 84 } 84 85 85 - e, err := rbac.NewEnforcer(dbPath) 86 + e, err := rbac.NewEnforcer(dbConfig) 86 87 if err != nil { 87 88 t.Fatalf("rbac.NewEnforcer: %v", err) 88 89 }
+1 -1
knotserver/server.go
··· 81 81 return fmt.Errorf("failed to load db: %w", err) 82 82 } 83 83 84 - e, err := rbac.NewEnforcer(c.Server.DBPath) 84 + e, err := rbac.NewEnforcer(dbConfig) 85 85 if err != nil { 86 86 return fmt.Errorf("failed to setup rbac enforcer: %w", err) 87 87 }
+63
rbac/d1_spike_test.go
··· 1 + package rbac 2 + 3 + import ( 4 + "context" 5 + "testing" 6 + 7 + "tangled.org/core/dbdrv" 8 + "tangled.org/core/dbdrv/testfake" 9 + knotdb "tangled.org/core/knotserver/db" 10 + ) 11 + 12 + func TestCasbinD1Spike(t *testing.T) { 13 + ctx := context.Background() 14 + fake := testfake.New(t) 15 + cfg := dbdrv.Config{Backend: "d1", URL: fake.URL} 16 + 17 + if _, err := knotdb.Setup(ctx, cfg, "did:plc:test-owner"); err != nil { 18 + t.Fatalf("db.Setup: %v", err) 19 + } 20 + 21 + e, err := NewEnforcer(cfg) 22 + if err != nil { 23 + t.Fatalf("NewEnforcer: %v", err) 24 + } 25 + e.E.EnableAutoSave(true) 26 + 27 + const ( 28 + knot = "did:plc:knot" 29 + owner = "did:plc:test-owner" 30 + ) 31 + if err := e.AddKnot(knot); err != nil { 32 + t.Fatalf("AddKnot: %v", err) 33 + } 34 + if err := e.AddKnotOwner(knot, owner); err != nil { 35 + t.Fatalf("AddKnotOwner: %v", err) 36 + } 37 + if err := e.E.SavePolicy(); err != nil { 38 + t.Fatalf("SavePolicy: %v", err) 39 + } 40 + 41 + fresh, err := NewEnforcer(cfg) 42 + if err != nil { 43 + t.Fatalf("fresh NewEnforcer: %v", err) 44 + } 45 + if err := fresh.E.LoadPolicy(); err != nil { 46 + t.Fatalf("LoadPolicy: %v", err) 47 + } 48 + isOwner, err := fresh.IsKnotOwner(owner, knot) 49 + if err != nil { 50 + t.Fatalf("IsKnotOwner: %v", err) 51 + } 52 + if !isOwner { 53 + t.Fatalf("IsKnotOwner(%q, %q) = false, want true", owner, knot) 54 + } 55 + 56 + var exists int 57 + if err := fake.DB.QueryRow(`SELECT count(*) FROM sqlite_master WHERE type = 'table' AND name = 'acl'`).Scan(&exists); err != nil { 58 + t.Fatalf("query acl table: %v", err) 59 + } 60 + if exists != 1 { 61 + t.Fatalf("acl table count = %d, want 1", exists) 62 + } 63 + }
+13 -3
rbac/rbac.go
··· 1 1 package rbac 2 2 3 3 import ( 4 + "context" 5 + "fmt" 4 6 "slices" 5 7 "strings" 6 8 ··· 37 39 E *casbin.SyncedEnforcer 38 40 } 39 41 40 - func NewEnforcer(path string) (*Enforcer, error) { 42 + // NewEnforcer opens the RBAC policy store for cfg. D1 mode depends on 43 + // knotserver/db.Setup pre-creating acl and idx_acl; otherwise sql-adapter's 44 + // multi-statement CREATE TABLE path fails under D1's single-statement prepare. 45 + func NewEnforcer(cfg dbdrv.Config) (*Enforcer, error) { 41 46 m, err := model.NewModelFromString(Model) 42 47 if err != nil { 43 48 return nil, err 44 49 } 45 50 46 - db, err := dbdrv.Open(path, "foreign_keys=1") 51 + db, err := dbdrv.OpenConfig(context.Background(), cfg, "foreign_keys=1") 47 52 if err != nil { 48 53 return nil, err 49 54 } 50 55 51 - a, err := adapter.NewAdapter(db, dbdrv.Name, "acl") 56 + dialect := dbdrv.DialectName(cfg) 57 + if dialect == "" { 58 + return nil, fmt.Errorf("rbac: unknown database backend %q", cfg.Backend) 59 + } 60 + 61 + a, err := adapter.NewAdapter(db, dialect, "acl") 52 62 if err != nil { 53 63 return nil, err 54 64 }
+2 -1
spindle/server.go
··· 13 13 "github.com/bluesky-social/indigo/atproto/syntax" 14 14 "github.com/go-chi/chi/v5" 15 15 "tangled.org/core/api/tangled" 16 + "tangled.org/core/dbdrv" 16 17 "tangled.org/core/eventconsumer" 17 18 "tangled.org/core/eventconsumer/cursor" 18 19 "tangled.org/core/idresolver" ··· 67 68 return nil, fmt.Errorf("failed to setup db: %w", err) 68 69 } 69 70 70 - e, err := rbac.NewEnforcer(cfg.Server.DBPath) 71 + e, err := rbac.NewEnforcer(dbdrv.Config{Backend: "sqlite", Path: cfg.Server.DBPath}) 71 72 if err != nil { 72 73 return nil, fmt.Errorf("failed to setup rbac enforcer: %w", err) 73 74 }
+1 -1
spindle/startup_migrations_test.go
··· 84 84 t.Fatalf("db.Make: %v", err) 85 85 } 86 86 t.Cleanup(func() { d.Close() }) 87 - e, err := rbac.NewEnforcer(p) 87 + e, err := rbac.NewEnforcer(dbdrv.Config{Backend: "sqlite", Path: p}) 88 88 if err != nil { 89 89 t.Fatalf("rbac.NewEnforcer: %v", err) 90 90 }