chore: establish local platform baseline
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
package identity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
const (
|
||||
localIssuer = "http://localhost:58180/realms/voice-local"
|
||||
ownerSubject = "00000000-0000-0000-0000-000000000101"
|
||||
outsiderSubject = "00000000-0000-0000-0000-000000000103"
|
||||
firstHouseholdID = "10000000-0000-0000-0000-000000000211"
|
||||
secondHouseholdID = "20000000-0000-0000-0000-000000000211"
|
||||
)
|
||||
|
||||
func TestRepositoryEnforcesTenantAndRoleBoundaries(t *testing.T) {
|
||||
databaseURL := os.Getenv("TEST_DATABASE_URL")
|
||||
if databaseURL == "" {
|
||||
t.Skip("TEST_DATABASE_URL is not set")
|
||||
}
|
||||
ctx := context.Background()
|
||||
pool, err := pgxpool.New(ctx, databaseURL)
|
||||
if err != nil {
|
||||
t.Fatalf("connect integration database: %v", err)
|
||||
}
|
||||
defer pool.Close()
|
||||
repository := NewRepository(pool)
|
||||
|
||||
owner := Principal{Issuer: localIssuer, Subject: ownerSubject}
|
||||
currentUser, err := repository.CurrentUser(ctx, owner)
|
||||
if err != nil {
|
||||
t.Fatalf("load owner: %v", err)
|
||||
}
|
||||
if len(currentUser.Accounts) != 1 || len(currentUser.Accounts[0].Memberships) != 1 {
|
||||
t.Fatalf("unexpected owner account: %#v", currentUser)
|
||||
}
|
||||
if currentUser.Accounts[0].Memberships[0].Role != RoleOwner {
|
||||
t.Fatalf("owner role not resolved: %#v", currentUser.Accounts[0].Memberships[0])
|
||||
}
|
||||
if _, err := repository.RequireHouseholdCapability(ctx, owner, firstHouseholdID, CapabilityHouseholdManage); err != nil {
|
||||
t.Fatalf("owner should manage own household: %v", err)
|
||||
}
|
||||
|
||||
outsider := Principal{Issuer: localIssuer, Subject: outsiderSubject}
|
||||
if _, err := repository.RequireHouseholdCapability(ctx, outsider, firstHouseholdID, CapabilityHouseholdRead); !errors.Is(err, ErrAccessDenied) {
|
||||
t.Fatalf("cross-tenant access error = %v, want ErrAccessDenied", err)
|
||||
}
|
||||
if _, err := repository.RequireHouseholdCapability(ctx, outsider, secondHouseholdID, CapabilityHouseholdRead); err != nil {
|
||||
t.Fatalf("viewer should read own household: %v", err)
|
||||
}
|
||||
if _, err := repository.RequireHouseholdCapability(ctx, outsider, secondHouseholdID, CapabilityHouseholdManage); !errors.Is(err, ErrAccessDenied) {
|
||||
t.Fatalf("viewer manage error = %v, want ErrAccessDenied", err)
|
||||
}
|
||||
if _, err := repository.RequireHouseholdCapability(ctx, owner, firstHouseholdID, CapabilityRecordingPlay); !errors.Is(err, ErrAccessDenied) {
|
||||
t.Fatalf("owner recording access error = %v, want ErrAccessDenied", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user