1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-13 17:24:03 +00:00

Postgres RLS + permission controlled database managers (#33)

This PR adds Postgres RLS (trait manager + table manager approach) and permission controlled managers for PostgreSQL.

---------

Co-authored-by: lukinovec <lukinovec@gmail.com>
Co-authored-by: PHP CS Fixer <phpcsfixer@example.com>
This commit is contained in:
Samuel Štancl 2024-04-24 22:32:49 +02:00 committed by GitHub
parent 34297d3e1a
commit 7317d2638a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 2511 additions and 112 deletions

View file

@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Bootstrappers;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Database\DatabaseManager;
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
use Stancl\Tenancy\Contracts\Tenant;
use Stancl\Tenancy\Database\DatabaseManager as TenantConnectionManager;
/**
* When initializing tenancy, use the tenant connection with the configured RLS user credentials
* and set the configured session variable to the current tenant's key.
*
* When ending tenancy, reset the session variable (to invalidate the connection)
* and switch back to the central connection again.
*
* This bootstrapper is intended to be used with Postgres RLS.
*
* @see \Stancl\Tenancy\Commands\CreateUserWithRLSPolicies
*/
class PostgresRLSBootstrapper implements TenancyBootstrapper
{
public function __construct(
protected Repository $config,
protected DatabaseManager $database,
protected TenantConnectionManager $tenantConnectionManager,
) {}
public function bootstrap(Tenant $tenant): void
{
$this->connectToTenant();
$tenantSessionKey = $this->config->get('tenancy.rls.session_variable_name');
$this->database->statement("SET {$tenantSessionKey} = '{$tenant->getTenantKey()}'");
}
public function revert(): void
{
$this->database->statement("RESET {$this->config->get('tenancy.rls.session_variable_name')}");
$this->tenantConnectionManager->reconnectToCentral();
}
protected function connectToTenant(): void
{
$centralConnection = $this->config->get('tenancy.database.central_connection');
$this->tenantConnectionManager->purgeTenantConnection();
$tenantConnection = array_merge($this->config->get('database.connections.' . $centralConnection), [
'username' => $this->config->get('tenancy.rls.user.username'),
'password' => $this->config->get('tenancy.rls.user.password'),
]);
$this->config['database.connections.tenant'] = $tenantConnection;
$this->tenantConnectionManager->setDefaultConnection('tenant');
}
}

View file

@ -105,7 +105,7 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
if (tenancy()->initialized) {
// Tenancy is already initialized
if (tenant()->getTenantKey() === $tenantId) {
// It's initialized for the same tenant (e.g. dispatchNow was used, or the previous job also ran for this tenant)
// It's initialized for the same tenant (e.g. dispatchSync was used, or the previous job also ran for this tenant)
return;
}
}