From 52cce14797d62afb66aab0cafdac22bb08a123bf Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Tue, 13 Sep 2022 16:02:42 +0500 Subject: [PATCH] purge connection and add more tests --- src/Database/DatabaseConfig.php | 27 ++++++++++++++++--- .../TenantDatabaseManager.php | 4 --- tests/TenantDatabaseManagerTest.php | 25 +++++++++++++++-- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/Database/DatabaseConfig.php b/src/Database/DatabaseConfig.php index b41dd75a..67b1cd42 100644 --- a/src/Database/DatabaseConfig.php +++ b/src/Database/DatabaseConfig.php @@ -6,6 +6,7 @@ namespace Stancl\Tenancy\Database; use Closure; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Str; use Stancl\Tenancy\Database\Contracts\TenantWithDatabase as Tenant; @@ -129,6 +130,9 @@ class DatabaseConfig $templateConnection = config("database.connections.{$template}"); if ($this->manager() instanceof Contracts\ManagesDatabaseUsers) { + // We don't need username and password for database creation/deletion + // Username and password will be saved in Tenant's config + // and used for connecting to tenant Database unset($config['username']); unset($config['password']); } @@ -140,6 +144,19 @@ class DatabaseConfig return array_replace($templateConnection, $config); } + /** + * Purge host database connection. + */ + public function purgeHostConnection(): void + { + $tenantHostConnectionName = $this->getTenantHostConnectionName(); + if (array_key_exists($tenantHostConnectionName, config('database.connections'))) { + DB::purge($tenantHostConnectionName); + } + + config(["database.connections.{$tenantHostConnectionName}" => null]); + } + /** * Additional config for the database connection, specific to this tenant. */ @@ -188,10 +205,12 @@ class DatabaseConfig /** Get the TenantDatabaseManager for this tenant's connection. */ public function hostManager(): Contracts\TenantDatabaseManager { - $tenantHostConnection = $this->getTenantHostConnectionName(); - config(["database.connections.{$tenantHostConnection}" => $this->hostConnection()]); + $this->purgeHostConnection(); - $driver = config("database.connections.{$tenantHostConnection}.driver"); + $tenantHostConnectionName = $this->getTenantHostConnectionName(); + config(["database.connections.{$tenantHostConnectionName}" => $this->hostConnection()]); + + $driver = config("database.connections.{$tenantHostConnectionName}.driver"); $databaseManagers = config('tenancy.database.managers'); if (! array_key_exists($driver, $databaseManagers)) { @@ -201,7 +220,7 @@ class DatabaseConfig /** @var Contracts\TenantDatabaseManager $databaseManager */ $databaseManager = app($databaseManagers[$driver]); - $databaseManager->setConnection($tenantHostConnection); + $databaseManager->setConnection($tenantHostConnectionName); return $databaseManager; } diff --git a/src/Database/TenantDatabaseManagers/TenantDatabaseManager.php b/src/Database/TenantDatabaseManagers/TenantDatabaseManager.php index 9b6f55c3..2e39aadd 100644 --- a/src/Database/TenantDatabaseManagers/TenantDatabaseManager.php +++ b/src/Database/TenantDatabaseManagers/TenantDatabaseManager.php @@ -20,10 +20,6 @@ abstract class TenantDatabaseManager implements Contract // todo better naming? throw new NoConnectionSetException(static::class); } - if (config("database.connections.{$this->getTenantHostConnectionName()}")) { - // DB::purge($this->getTenantHostConnectionName()); - } - return DB::connection($this->connection); } diff --git a/tests/TenantDatabaseManagerTest.php b/tests/TenantDatabaseManagerTest.php index fce66a20..5399f3de 100644 --- a/tests/TenantDatabaseManagerTest.php +++ b/tests/TenantDatabaseManagerTest.php @@ -100,8 +100,6 @@ test('the tenant connection is fully removed', function () { $tenant = Tenant::create(); - // Connections array can contain other connections built runtime like 'tenant_host_connection' - // So check if tenant connection does not exist in connections expect(array_keys(app('db')->getConnections()))->not()->toContain('tenant'); pest()->assertArrayNotHasKey('tenant', config('database.connections')); @@ -229,6 +227,29 @@ test('tenant database can be created and deleted on a foreign server', function expect($manager->databaseExists($name))->toBeFalse(); }); +test('using permission controller MySQL manager creates the database user', function () { + config([ + 'tenancy.database.managers.mysql' => PermissionControlledMySQLDatabaseManager::class, + ]); + + Event::listen(TenantCreated::class, JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) { + return $event->tenant; + })->toListener()); + + $name = 'foo' . Str::random(8); + + $tenant = Tenant::create([ + 'tenancy_db_name' => $name, + ]); + $dbUser = $tenant->tenancy_db_username; + + /** @var PermissionControlledMySQLDatabaseManager $manager */ + $manager = $tenant->database()->manager(); + $manager->setConnection('mysql'); + + expect($manager->userExists($dbUser))->toBeTrue(); +}); + test('tenant database can be created on template tenant connection', function () { config([ 'tenancy.database.managers.mysql' => MySQLDatabaseManager::class,