diff --git a/assets/config.php b/assets/config.php index b12cd6c4..45179135 100644 --- a/assets/config.php +++ b/assets/config.php @@ -61,6 +61,7 @@ return [ 'sqlite' => Stancl\Tenancy\TenantDatabaseManagers\SQLiteDatabaseManager::class, 'mysql' => Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager::class, 'pgsql' => Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLDatabaseManager::class, + 'sqlsrv' => Stancl\Tenancy\TenantDatabaseManagers\SQLServerDatabaseManager::class, /** * Use this database manager for MySQL to have a DB user created for each tenant database. @@ -68,7 +69,14 @@ return [ */ // 'mysql' => Stancl\Tenancy\TenantDatabaseManagers\PermissionControlledMySQLDatabaseManager::class, - /** + /** + * Use this database manager for SQlServer to have a DB user created for each tenant database. + * You can customize the grants given to these users by changing the $GrantPermissions property. + */ + + //'sqlsrv' => Stancl\Tenancy\TenantDatabaseManagers\PermissionControlledSQLServerDatabaseManager::class, + + /** * Disable the pgsql manager above, and enable the one below if you * want to separate tenant DBs by schemas rather than databases. */ diff --git a/src/TenantDatabaseManagers/PermissionControlledSQLServerDatabaseManager.php b/src/TenantDatabaseManagers/PermissionControlledSQLServerDatabaseManager.php new file mode 100644 index 00000000..4d6ba343 --- /dev/null +++ b/src/TenantDatabaseManagers/PermissionControlledSQLServerDatabaseManager.php @@ -0,0 +1,48 @@ +getDatabaseName(); + $database = $databaseConfig->getName(); + $username = $databaseConfig->getUsername(); + $password = $databaseConfig->getPassword(); + + $GrantPermissions = "Use {$database} + CREATE LOGIN {$username} WITH PASSWORD = '{$password}' + CREATE USER {$username} FOR LOGIN {$username} + ALTER ROLE db_owner ADD MEMBER {$username} Use {$central}"; + + return $this->database()->statement($GrantPermissions); + } + + public function deleteUser(DatabaseConfig $databaseConfig): bool + { + $central = DB::connection()->getDatabaseName(); + return $this->database()->statement("Use'{$databaseConfig->getName()}' + DROP USER IF EXISTS '{$databaseConfig->getUsername()}' + DROP LOGIN '{$databaseConfig->getUsername()}' + Use {$central}"); + } + public function userExists(string $username): bool + { + return (bool) $this->database()->select("SELECT sp.name as username FROM sys.server_principals sp WHERE sp.name = '{$username}'"); + } + + public function makeConnectionConfig(array $baseConfig, string $databaseName): array + { + $baseConfig['database'] = $databaseName; + + return $baseConfig; + } +} diff --git a/src/TenantDatabaseManagers/SqlServerDatabaseManager.php b/src/TenantDatabaseManagers/SqlServerDatabaseManager.php new file mode 100644 index 00000000..e8464107 --- /dev/null +++ b/src/TenantDatabaseManagers/SqlServerDatabaseManager.php @@ -0,0 +1,53 @@ +connection === null) { + throw new NoConnectionSetException(static::class); + } + + return DB::connection($this->connection); + } + + public function setConnection(string $connection): void + { + $this->connection = $connection; + } + + public function createDatabase(TenantWithDatabase $tenant): bool + { + return $this->database()->statement("CREATE DATABASE \"{$tenant->database()->getName()}\""); + } + + public function deleteDatabase(TenantWithDatabase $tenant): bool + { + return $this->database()->statement("DROP DATABASE \"{$tenant->database()->getName()}\""); + } + + public function databaseExists(string $name): bool + { + return (bool) $this->database()->select("SELECT physical_database_name FROM sys.databases WHERE physical_database_name = '$name'"); + } + + public function makeConnectionConfig(array $baseConfig, string $databaseName): array + { + $baseConfig['database'] = $databaseName; + + return $baseConfig; + } +}