mirror of
https://github.com/archtechx/tenancy.git
synced 2026-02-05 05:14:03 +00:00
Add test that makes the bypassrls/forceRls behavior clear
This commit is contained in:
parent
12786a36db
commit
b48826cc33
1 changed files with 58 additions and 1 deletions
|
|
@ -768,7 +768,59 @@ test('table manager ignores recursive relationship if the foreign key responsibl
|
||||||
expect(fn () => app(TableRLSManager::class)->generateTrees())->not()->toThrow(RecursiveRelationshipException::class);
|
expect(fn () => app(TableRLSManager::class)->generateTrees())->not()->toThrow(RecursiveRelationshipException::class);
|
||||||
});
|
});
|
||||||
|
|
||||||
function createPostgresUser(string $username, string $password = 'password'): array
|
test('users with BYPASSRLS privilege can bypass RLS regardless of forceRls setting', function(bool $forceRls, bool $bypassRls) {
|
||||||
|
CreateUserWithRLSPolicies::$forceRls = $forceRls;
|
||||||
|
|
||||||
|
// Drop all tables created in beforeEach
|
||||||
|
DB::statement("DROP TABLE authors, categories, posts, comments, reactions, articles;");
|
||||||
|
|
||||||
|
[$username, $password] = createPostgresUser('administrator', 'password', $bypassRls);
|
||||||
|
|
||||||
|
config(['database.connections.central' => array_merge(
|
||||||
|
config('database.connections.pgsql'),
|
||||||
|
['username' => $username, 'password' => $password]
|
||||||
|
)]);
|
||||||
|
|
||||||
|
DB::reconnect();
|
||||||
|
|
||||||
|
Schema::create('orders', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('name');
|
||||||
|
|
||||||
|
$table->string('tenant_id')->comment('rls');
|
||||||
|
$table->foreign('tenant_id')->references('id')->on('tenants')->onUpdate('cascade')->onDelete('cascade');
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
|
||||||
|
$tenant1 = Tenant::create();
|
||||||
|
|
||||||
|
// Create RLS policy for the orders table
|
||||||
|
pest()->artisan('tenants:rls');
|
||||||
|
|
||||||
|
$tenant1->run(fn () => Order::create(['name' => 'order1', 'tenant_id' => $tenant1->getTenantKey()]));
|
||||||
|
|
||||||
|
if ($bypassRls) {
|
||||||
|
// Users with BYPASSRLS can always query tables regardless of forceRls setting
|
||||||
|
// This is the normal production setup behavior
|
||||||
|
expect(Order::first())->not()->toBeNull();
|
||||||
|
expect(Order::first()->name)->toBe('order1');
|
||||||
|
} else {
|
||||||
|
// Users without BYPASSRLS are subject to RLS policies even if they're table owners when forceRls is true
|
||||||
|
// OR they can bypass as table owners (when forceRls=false)
|
||||||
|
if ($forceRls) {
|
||||||
|
// Even table owners need session variable
|
||||||
|
expect(fn () => Order::first())->toThrow(QueryException::class, 'unrecognized configuration parameter');
|
||||||
|
} else {
|
||||||
|
// Table owners can bypass RLS automatically
|
||||||
|
expect(Order::first())->not()->toBeNull();
|
||||||
|
expect(Order::first()->name)->toBe('order1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})->with([true, false])
|
||||||
|
->with([true, false]);
|
||||||
|
|
||||||
|
function createPostgresUser(string $username, string $password = 'password', bool $bypassRls = false): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
DB::statement("DROP OWNED BY {$username};");
|
DB::statement("DROP OWNED BY {$username};");
|
||||||
|
|
@ -780,6 +832,11 @@ function createPostgresUser(string $username, string $password = 'password'): ar
|
||||||
DB::statement("ALTER USER {$username} CREATEDB");
|
DB::statement("ALTER USER {$username} CREATEDB");
|
||||||
DB::statement("ALTER USER {$username} CREATEROLE");
|
DB::statement("ALTER USER {$username} CREATEROLE");
|
||||||
|
|
||||||
|
// Grant BYPASSRLS privilege if requested
|
||||||
|
if ($bypassRls) {
|
||||||
|
DB::statement("ALTER USER {$username} BYPASSRLS");
|
||||||
|
}
|
||||||
|
|
||||||
// Grant privileges to the new central user
|
// Grant privileges to the new central user
|
||||||
DB::statement("GRANT ALL PRIVILEGES ON DATABASE main to {$username}");
|
DB::statement("GRANT ALL PRIVILEGES ON DATABASE main to {$username}");
|
||||||
DB::statement("GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO {$username}");
|
DB::statement("GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO {$username}");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue