diff --git a/extensions/lib/noattach.dll b/extensions/lib/noattach.dll index 6767a4ce..5334d2ab 100644 Binary files a/extensions/lib/noattach.dll and b/extensions/lib/noattach.dll differ diff --git a/src/Commands/CreateUserWithRLSPolicies.php b/src/Commands/CreateUserWithRLSPolicies.php index aa171d58..c6abf8ab 100644 --- a/src/Commands/CreateUserWithRLSPolicies.php +++ b/src/Commands/CreateUserWithRLSPolicies.php @@ -105,34 +105,36 @@ protected function createTablePolicies(): void $createdPolicies = []; - foreach ($rlsQueries as $table => $query) { - [$hash, $policyQuery] = $this->hashPolicy($query); - $expectedName = $table . '_rls_policy_' . $hash; + foreach ($rlsQueries as $table => $queries) { + foreach ($queries as $type => $query) { + [$hash, $policyQuery] = $this->hashPolicy($query); + $expectedName = $table . '_' . $type . '_rls_policy_' . $hash; - $tableRLSPolicy = $this->findTableRLSPolicy($table); - $olderPolicyExists = $tableRLSPolicy && $tableRLSPolicy->policyname !== $expectedName; + $tableRLSPolicy = $this->findTableRLSPolicy($table, $type); + $olderPolicyExists = $tableRLSPolicy && $tableRLSPolicy->policyname !== $expectedName; - // Drop the policy if an outdated version exists - // or if it exists (even in the current form) and the --force option is used - $dropPolicy = $olderPolicyExists || ($tableRLSPolicy && $this->option('force')); + // Drop the policy if an outdated version exists + // or if it exists (even in the current form) and the --force option is used + $dropPolicy = $olderPolicyExists || ($tableRLSPolicy && $this->option('force')); - if ($tableRLSPolicy && $dropPolicy) { - DB::statement("DROP POLICY {$tableRLSPolicy->policyname} ON {$table}"); + if ($tableRLSPolicy && $dropPolicy) { + DB::statement("DROP POLICY {$tableRLSPolicy->policyname} ON {$table}"); - $this->components->info("RLS policy for table '{$table}' dropped."); - } + $this->components->info("RLS policy for table '{$table}' for '{$type}' dropped."); + } - // Create RLS policy if the table doesn't have it or if the --force option is used - $createPolicy = $dropPolicy || ! $tableRLSPolicy || $this->option('force'); + // Create RLS policy if the table doesn't have it or if the --force option is used + $createPolicy = $dropPolicy || ! $tableRLSPolicy || $this->option('force'); - if ($createPolicy) { - DB::statement($policyQuery); + if ($createPolicy) { + DB::statement($policyQuery); - $this->enableRLS($table); + $this->enableRLS($table); - $createdPolicies[] = $table . " ($hash)"; - } else { - $this->components->info("Table '{$table}' already has an up to date RLS policy."); + $createdPolicies[] = $table . " ($hash)"; + } else { + $this->components->info("Table '{$table}' for '{$type}' already has an up to date RLS policy."); + } } } @@ -143,19 +145,19 @@ protected function createTablePolicies(): void $this->components->bulletList($createdPolicies); - $this->components->success('RLS policies updated successfully.'); + $this->components->info('RLS policies updated successfully.'); } else { - $this->components->success('All RLS policies are up to date.'); + $this->components->info('All RLS policies are up to date.'); } } /** @return \stdClass|null */ - protected function findTableRLSPolicy(string $table): object|null + protected function findTableRLSPolicy(string $table, string $type): object|null { return DB::selectOne(<<database->getConfig('username'); foreach ($trees ?: $this->shortestPaths() as $table => $path) { - $queries[$table] = $this->generateQuery($table, $path); + $queries[$table] = [ + 'tenant' => $this->generateQuery($table, $path), + 'central' => "CREATE POLICY {$table}_central_rls_policy ON {$table} AS PERMISSIVE TO {$centralUserName} USING (true);", + ]; } return $queries; @@ -209,8 +215,9 @@ protected function formatForeignKey(array $foreignKey, string $table): array /** Generates a query that creates a row-level security policy for the passed table. */ protected function generateQuery(string $table, array $path): string { + $role = $this->config->get('tenancy.rls.user.username'); // Generate the SQL conditions recursively - $query = "CREATE POLICY {$table}_rls_policy ON {$table} USING (\n"; + $query = "CREATE POLICY {$table}_tenant_rls_policy ON {$table} TO {$role} USING (\n"; $sessionTenantKey = config('tenancy.rls.session_variable_name'); foreach ($path as $index => $relation) {