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

Add DatabaseTenancyBootstrapper::$harden

Since It's possible to update tenant's db_name to the central DB or the DB of another tenant. Setting $harden to true prevents tenants from connecting to the wrong databases.
This commit is contained in:
lukinovec 2026-05-01 11:44:56 +02:00
parent 1a01164b87
commit 665404e7fa
2 changed files with 88 additions and 2 deletions

View file

@ -5,14 +5,23 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Bootstrappers;
use Exception;
use Illuminate\Support\Facades\Schema;
use RuntimeException;
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
use Stancl\Tenancy\Contracts\Tenant;
use Stancl\Tenancy\Database\Contracts\TenantWithDatabase;
use Stancl\Tenancy\Database\DatabaseManager;
use Stancl\Tenancy\Database\Exceptions\TenantDatabaseDoesNotExistException;
use Illuminate\Database\Eloquent\Model;
class DatabaseTenancyBootstrapper implements TenancyBootstrapper
{
/**
* When true, throw an exception if a tenant gets connected to
* another tenant's database or to the central database.
*/
public static bool $harden = false;
/** @var DatabaseManager */
protected $database;
@ -41,10 +50,30 @@ class DatabaseTenancyBootstrapper implements TenancyBootstrapper
}
$this->database->connectToTenant($tenant);
if (static::$harden) $this->harden($tenant);
}
public function revert(): void
{
$this->database->reconnectToCentral();
}
protected function harden(Tenant $tenant): void
{
/** @var TenantWithDatabase&Model $tenant */
$dbName = $tenant->database()->getName();
// Check if the current database is unique (i.e. no other tenant uses this database)
if ($tenant::where($tenant->getTenantKeyName(), '!=', $tenant->getTenantKey())
->where('data->tenancy_db_name', $dbName)
->exists()) {
throw new RuntimeException("Tenant cannot use a database of another tenant.");
}
// Check if the current database doesn't have the tenants table (i.e. it's not the central database)
if (Schema::hasTable($tenant->getTable())) {
throw new RuntimeException('Tenant cannot use the central database.');
}
}
}