From cc28d1813a160a3c42292a3a3a1d5ee23fc087f1 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Mon, 5 Jun 2023 16:35:16 +0200 Subject: [PATCH] Move reusable methods to Tenancy, get rid of tenancy.models.rls --- .../CreateRLSPoliciesForTenantTables.php | 29 ++---------- src/Jobs/CreatePostgresUserForTenant.php | 12 ++--- src/Tenancy.php | 44 ++++++++++++++++++- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/Commands/CreateRLSPoliciesForTenantTables.php b/src/Commands/CreateRLSPoliciesForTenantTables.php index 5599f3be..5aef1e58 100644 --- a/src/Commands/CreateRLSPoliciesForTenantTables.php +++ b/src/Commands/CreateRLSPoliciesForTenantTables.php @@ -21,21 +21,13 @@ class CreateRLSPoliciesForTenantTables extends Command public function handle(): int { - foreach ($this->getModels() as $model) { + foreach (tenancy()->getModels() as $model) { DB::transaction(fn () => $this->useRlsOnModel($model)); } return Command::SUCCESS; } - protected function getModels(): array - { - $tables = array_map(fn ($table) => $table->tablename, Schema::getAllTables()); - $models = array_map(fn (string $table) => $this->getModelFromTable($table), $tables); - - return array_filter($models); - } - /** * Make model use RLS if it belongs to a tenant directly, or through a parent primary model. */ @@ -46,9 +38,9 @@ class CreateRLSPoliciesForTenantTables extends Command DB::statement("DROP POLICY IF EXISTS {$table}_rls_policy ON {$table}"); - if (! Schema::hasColumn($table, $tenantKey)) { + if (! tenancy()->modelBelongsToTenant($model)) { // Table is not directly related to a tenant - if (in_array(BelongsToPrimaryModel::class, class_uses_recursive($model::class))) { + if (tenancy()->modelBelongsToTenantIndirectly($model)) { $this->makeSecondaryModelUseRls($model); } else { $this->components->info("Skipping RLS policy creation – table '$table' is not related to a tenant."); @@ -93,19 +85,4 @@ class CreateRLSPoliciesForTenantTables extends Command DB::statement("ALTER TABLE {$table} ENABLE ROW LEVEL SECURITY"); DB::statement("ALTER TABLE {$table} FORCE ROW LEVEL SECURITY"); } - - protected function getModelFromTable(string $table): Model|null - { - foreach (get_declared_classes() as $class) { - if (is_subclass_of($class, Model::class)) { - $model = new $class; - - if ($model->getTable() === $table) { - return $model; - } - } - } - - return null; - } } diff --git a/src/Jobs/CreatePostgresUserForTenant.php b/src/Jobs/CreatePostgresUserForTenant.php index 55f33fc7..1d5a012d 100644 --- a/src/Jobs/CreatePostgresUserForTenant.php +++ b/src/Jobs/CreatePostgresUserForTenant.php @@ -47,17 +47,13 @@ class CreatePostgresUserForTenant implements ShouldQueue protected function grantPermissions(string $userName): void { - /** - * @var \Stancl\Tenancy\Database\Contracts\StatefulTenantDatabaseManager $databaseManager - */ + /** @var \Stancl\Tenancy\Database\Contracts\StatefulTenantDatabaseManager $databaseManager */ $databaseManager = $this->tenant->database()->manager(); - /** - * @var Model[] $rlsModels - */ - $rlsModels = array_map(fn (string $modelName) => (new $modelName), config('tenancy.models.rls')); + /** @var Model[] $tenantModels */ + $tenantModels = tenancy()->getTenantModels(); - foreach ($rlsModels as $model) { + foreach ($tenantModels as $model) { $table = $model->getTable(); $databaseManager->database()->transaction(function () use ($databaseManager, $table, $userName) { diff --git a/src/Tenancy.php b/src/Tenancy.php index 6de52c42..9fabfc1c 100644 --- a/src/Tenancy.php +++ b/src/Tenancy.php @@ -5,11 +5,13 @@ declare(strict_types=1); namespace Stancl\Tenancy; use Closure; -use Illuminate\Database\Eloquent\Builder; +use Stancl\Tenancy\Contracts\Tenant; +use Illuminate\Support\Facades\Schema; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Traits\Macroable; +use Illuminate\Database\Eloquent\Builder; use Stancl\Tenancy\Contracts\TenancyBootstrapper; -use Stancl\Tenancy\Contracts\Tenant; +use Stancl\Tenancy\Database\Concerns\BelongsToPrimaryModel; use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedByIdException; class Tenancy @@ -215,4 +217,42 @@ class Tenancy { return config('tenancy.identification.default_middleware', Middleware\InitializeTenancyByDomain::class); } + + public static function getModels(): array + { + $tables = array_map(fn ($table) => $table->tablename, Schema::getAllTables()); + $models = array_map(fn (string $table) => static::getModelFromTable($table), $tables); + + return array_filter($models); + } + + public static function getTenantModels(): array + { + return array_filter(static::getModels(), fn (Model $model) => tenancy()->modelBelongsToTenant($model) || tenancy()->modelBelongsToTenantIndirectly($model)); + } + + protected static function getModelFromTable(string $table): Model|null + { + foreach (get_declared_classes() as $class) { + if (is_subclass_of($class, Model::class)) { + $model = new $class; + + if ($model->getTable() === $table) { + return $model; + } + } + } + + return null; + } + + public static function modelBelongsToTenant(Model $model): bool + { + return Schema::hasColumn($model->getTable(), static::tenantKeyColumn()); + } + + public static function modelBelongsToTenantIndirectly(Model $model): bool + { + return in_array(BelongsToPrimaryModel::class, class_uses_recursive($model::class)); + } }