mirror of
https://github.com/archtechx/tenancy.git
synced 2026-02-05 12:54:05 +00:00
Merge branch 'may25' into cloning-refactor
This commit is contained in:
commit
3799f08c7c
12 changed files with 189 additions and 82 deletions
|
|
@ -22,6 +22,23 @@ class CreateUserWithRLSPolicies extends Command
|
|||
|
||||
protected $description = "Creates RLS policies for all tables related to the tenant table. Also creates the RLS user if it doesn't exist yet";
|
||||
|
||||
/**
|
||||
* Force, rather than just enable, the created RLS policies.
|
||||
*
|
||||
* By default, table owners bypass RLS policies. When this is enabled,
|
||||
* they also need the BYPASSRLS permission. If your setup lets you create
|
||||
* a user with BYPASSRLS, you may prefer leaving this on for additional
|
||||
* safety. Otherwise, if you can't use BYPASSRLS, you can set this to false
|
||||
* and depend on the behavior of table owners bypassing RLS automatically.
|
||||
*
|
||||
* This setting generally doesn't affect behavior at all with "default"
|
||||
* setups, however if you have a more custom setup, with additional users
|
||||
* involved (e.g. central connection user not being the same user that
|
||||
* creates tables, or the created "RLS user" creating some tables) you
|
||||
* should take care with how you configure this.
|
||||
*/
|
||||
public static bool $forceRls = true;
|
||||
|
||||
public function handle(PermissionControlledPostgreSQLSchemaManager $manager): int
|
||||
{
|
||||
$username = config('tenancy.rls.user.username');
|
||||
|
|
@ -49,14 +66,9 @@ class CreateUserWithRLSPolicies extends Command
|
|||
// Enable RLS scoping on the table (without this, queries won't be scoped using RLS)
|
||||
DB::statement("ALTER TABLE {$table} ENABLE ROW LEVEL SECURITY");
|
||||
|
||||
/**
|
||||
* Force RLS scoping on the table, so that the table owner users
|
||||
* don't bypass the scoping – table owners bypass RLS by default.
|
||||
*
|
||||
* E.g. when using a custom implementation where you create tables as the RLS user,
|
||||
* the queries won't be scoped for the RLS user unless we force the RLS scoping using this query.
|
||||
*/
|
||||
DB::statement("ALTER TABLE {$table} FORCE ROW LEVEL SECURITY");
|
||||
if (static::$forceRls) {
|
||||
DB::statement("ALTER TABLE {$table} FORCE ROW LEVEL SECURITY");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,49 +5,11 @@ declare(strict_types=1);
|
|||
namespace Stancl\Tenancy\Contracts;
|
||||
|
||||
use Exception;
|
||||
use Spatie\ErrorSolutions\Contracts\BaseSolution;
|
||||
use Spatie\ErrorSolutions\Contracts\ProvidesSolution;
|
||||
|
||||
abstract class TenantCouldNotBeIdentifiedException extends Exception implements ProvidesSolution
|
||||
abstract class TenantCouldNotBeIdentifiedException extends Exception
|
||||
{
|
||||
/** Default solution title. */
|
||||
protected string $solutionTitle = 'Tenant could not be identified';
|
||||
|
||||
/** Default solution description. */
|
||||
protected string $solutionDescription = 'Are you sure this tenant exists?';
|
||||
|
||||
/** Set the message. */
|
||||
protected function tenantCouldNotBeIdentified(string $how): static
|
||||
protected function tenantCouldNotBeIdentified(string $how): void
|
||||
{
|
||||
$this->message = 'Tenant could not be identified ' . $how;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** Set the solution title. */
|
||||
protected function title(string $solutionTitle): static
|
||||
{
|
||||
$this->solutionTitle = $solutionTitle;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** Set the solution description. */
|
||||
protected function description(string $solutionDescription): static
|
||||
{
|
||||
$this->solutionDescription = $solutionDescription;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** Get the Ignition description. */
|
||||
public function getSolution(): BaseSolution
|
||||
{
|
||||
return BaseSolution::create($this->solutionTitle)
|
||||
->setSolutionDescription($this->solutionDescription)
|
||||
->setDocumentationLinks([
|
||||
'Tenants' => 'https://tenancyforlaravel.com/docs/v3/tenants',
|
||||
'Tenant Identification' => 'https://tenancyforlaravel.com/docs/v3/tenant-identification',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ class TenantColumnNotWhitelistedException extends TenantCouldNotBeIdentifiedExce
|
|||
{
|
||||
public function __construct(int|string $tenant_id)
|
||||
{
|
||||
$this
|
||||
->tenantCouldNotBeIdentified("on path with tenant key: $tenant_id (column not whitelisted)")
|
||||
->title('Tenant could not be identified on this route because the used column is not whitelisted.')
|
||||
->description('Please add the column to the list of allowed columns in the PathTenantResolver config.');
|
||||
$this->tenantCouldNotBeIdentified("on path with tenant key: $tenant_id (column not whitelisted)");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ class TenantCouldNotBeIdentifiedByIdException extends TenantCouldNotBeIdentified
|
|||
{
|
||||
public function __construct(int|string $tenant_id)
|
||||
{
|
||||
$this
|
||||
->tenantCouldNotBeIdentified("by tenant key: $tenant_id")
|
||||
->title('Tenant could not be identified with that key')
|
||||
->description('Are you sure the key is correct and the tenant exists?');
|
||||
$this->tenantCouldNotBeIdentified("by tenant key: $tenant_id");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ class TenantCouldNotBeIdentifiedByPathException extends TenantCouldNotBeIdentifi
|
|||
{
|
||||
public function __construct(int|string $tenant_id)
|
||||
{
|
||||
$this
|
||||
->tenantCouldNotBeIdentified("on path with tenant key: $tenant_id")
|
||||
->title('Tenant could not be identified on this path')
|
||||
->description('Did you forget to create a tenant for this path?');
|
||||
$this->tenantCouldNotBeIdentified("on path with tenant key: $tenant_id");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ class TenantCouldNotBeIdentifiedByRequestDataException extends TenantCouldNotBeI
|
|||
{
|
||||
public function __construct(mixed $payload)
|
||||
{
|
||||
$this
|
||||
->tenantCouldNotBeIdentified("by request data with payload: $payload")
|
||||
->title('Tenant could not be identified using this request data')
|
||||
->description('Did you forget to create a tenant with this id?');
|
||||
$this->tenantCouldNotBeIdentified("by request data with payload: $payload");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ class TenantCouldNotBeIdentifiedOnDomainException extends TenantCouldNotBeIdenti
|
|||
{
|
||||
public function __construct(string $domain)
|
||||
{
|
||||
$this
|
||||
->tenantCouldNotBeIdentified("on domain $domain")
|
||||
->title('Tenant could not be identified on this domain')
|
||||
->description('Did you forget to create a tenant for this domain?');
|
||||
$this->tenantCouldNotBeIdentified("on domain $domain");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ if (! function_exists('tenant')) {
|
|||
return app(Tenant::class);
|
||||
}
|
||||
|
||||
// @phpstan-ignore-next-line nullsafe.neverNull
|
||||
return app(Tenant::class)?->getAttribute($key);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue