package db import ( "database/sql" "os" "path/filepath" "testing" ) func TestAuthorizerBlocksSensitiveTables(t *testing.T) { // Create temporary database tmpDir := t.TempDir() dbPath := filepath.Join(tmpDir, "test.db") // Set environment for database path if err := os.Setenv("ATCR_UI_DATABASE_PATH", dbPath); err != nil { t.Fatalf("Failed to set environment variable: %v", err) } defer os.Unsetenv("ATCR_UI_DATABASE_PATH") // Initialize database (creates schema) database, err := InitDB(dbPath, true) if err != nil { t.Fatalf("Failed to initialize database: %v", err) } defer database.Close() // Create some test data in sensitive tables _, err = database.Exec(` INSERT INTO oauth_sessions (session_key, account_did, session_id, session_data, created_at, updated_at) VALUES ('test-key', 'did:plc:test', 'test-session', 'secret-token-data', datetime('now'), datetime('now')) `) if err != nil { t.Fatalf("Failed to insert test data: %v", err) } _, err = database.Exec(` INSERT INTO users (did, handle, pds_endpoint, avatar, last_seen) VALUES ('did:plc:test', 'test.user', 'https://pds.example.com', '', datetime('now')) `) if err != nil { t.Fatalf("Failed to insert test user: %v", err) } // Open read-only connection with authorizer (using our custom driver) readOnlyDB, err := sql.Open(ReadOnlyDriverName, "file:"+dbPath+"?mode=ro") if err != nil { t.Fatalf("Failed to open read-only database: %v", err) } defer readOnlyDB.Close() // Test 1: Should be able to read from public tables (users) t.Run("AllowPublicTableRead", func(t *testing.T) { var handle string err := readOnlyDB.QueryRow("SELECT handle FROM users WHERE did = ?", "did:plc:test").Scan(&handle) if err != nil { t.Errorf("Should be able to read from public table 'users': %v", err) } if handle != "test.user" { t.Errorf("Expected handle 'test.user', got '%s'", handle) } }) // Test 2: Should NOT be able to read from sensitive tables (oauth_sessions) t.Run("BlockSensitiveTableRead", func(t *testing.T) { var sessionData string err := readOnlyDB.QueryRow("SELECT session_data FROM oauth_sessions WHERE session_key = ?", "test-key").Scan(&sessionData) if err == nil { t.Errorf("Should NOT be able to read from sensitive table 'oauth_sessions', but got data: %s", sessionData) } // SQLite returns "not authorized" error when authorizer denies access if err != nil && err.Error() != "not authorized" { t.Logf("Got expected error (but different message): %v", err) } }) // Test 3: Should NOT be able to read from ui_sessions t.Run("BlockUISessionsTableRead", func(t *testing.T) { rows, err := readOnlyDB.Query("SELECT * FROM ui_sessions LIMIT 1") if err == nil { rows.Close() t.Error("Should NOT be able to read from sensitive table 'ui_sessions'") } }) // Test 4: Should NOT be able to read from devices t.Run("BlockDevicesTableRead", func(t *testing.T) { rows, err := readOnlyDB.Query("SELECT * FROM devices LIMIT 1") if err == nil { rows.Close() t.Error("Should NOT be able to read from sensitive table 'devices'") } }) // Test 5: Should NOT be able to write to any table (read-only mode + authorizer) t.Run("BlockAllWrites", func(t *testing.T) { _, err := readOnlyDB.Exec("INSERT INTO users (did, handle, pds_endpoint, avatar, last_seen) VALUES ('did:plc:test2', 'test2', 'https://pds.example.com', '', datetime('now'))") if err == nil { t.Error("Should NOT be able to write to any table in read-only mode") } }) }