1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-02-04 22:04:03 +00:00

When a foreign key has no-rls comment (or no comment when scopeByDefault is false), skip path generation earlier

This commit is contained in:
lukinovec 2025-05-15 09:08:11 +02:00
parent 27685ffe5a
commit 2197214516
2 changed files with 20 additions and 9 deletions

View file

@ -108,6 +108,12 @@ class TableRLSManager implements RLSPolicyManager
protected function generatePaths(string $table, array $foreign, array &$paths, array $currentPath = []): void protected function generatePaths(string $table, array $foreign, array &$paths, array $currentPath = []): void
{ {
// If the foreign key has a comment of 'no-rls', we skip it
// Also skip the foreign key if implicit scoping is off and the foreign key has no comment
if ($foreign['comment'] === 'no-rls' || (! static::$scopeByDefault && $foreign['comment'] === null)) {
return;
}
if (in_array($foreign['foreignTable'], array_column($currentPath, 'foreignTable'))) { if (in_array($foreign['foreignTable'], array_column($currentPath, 'foreignTable'))) {
throw new RecursiveRelationshipException; throw new RecursiveRelationshipException;
} }
@ -115,15 +121,7 @@ class TableRLSManager implements RLSPolicyManager
$currentPath[] = $foreign; $currentPath[] = $foreign;
if ($foreign['foreignTable'] === tenancy()->model()->getTable()) { if ($foreign['foreignTable'] === tenancy()->model()->getTable()) {
$comments = array_column($currentPath, 'comment'); $paths[] = $currentPath;
$pathCanUseRls = static::$scopeByDefault ?
! in_array('no-rls', $comments) :
! in_array('no-rls', $comments) && ! in_array(null, $comments);
if ($pathCanUseRls) {
// If the foreign table is the tenants table, add the current path to $paths
$paths[] = $currentPath;
}
} else { } else {
// If not, recursively generate paths for the foreign table // If not, recursively generate paths for the foreign table
foreach ($this->database->getSchemaBuilder()->getForeignKeys($foreign['foreignTable']) as $nextConstraint) { foreach ($this->database->getSchemaBuilder()->getForeignKeys($foreign['foreignTable']) as $nextConstraint) {

View file

@ -650,6 +650,19 @@ test('table manager throws an exception when encountering a recursive relationsh
expect(fn () => app(TableRLSManager::class)->generateTrees())->toThrow(RecursiveRelationshipException::class); expect(fn () => app(TableRLSManager::class)->generateTrees())->toThrow(RecursiveRelationshipException::class);
}); });
test('table manager ignores recursive relationship if the foreign key responsible for the recursion has no-rls comment', function() {
Schema::create('recursive_posts', function (Blueprint $table) {
$table->id();
$table->foreignId('highlighted_comment_id')->nullable()->comment('no-rls')->constrained('comments');
});
Schema::table('comments', function (Blueprint $table) {
$table->foreignId('recursive_post_id')->comment('rls')->constrained('recursive_posts');
});
expect(fn () => app(TableRLSManager::class)->generateTrees())->not()->toThrow(RecursiveRelationshipException::class);
});
class Post extends Model class Post extends Model
{ {
protected $guarded = []; protected $guarded = [];