mirror of
https://github.com/archtechx/tenancy.git
synced 2026-02-04 19:24:02 +00:00
Move reusable methods to Tenancy, get rid of tenancy.models.rls
This commit is contained in:
parent
bad5c693ab
commit
cc28d1813a
3 changed files with 49 additions and 36 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue