1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-05-06 15:24:03 +00:00
tenancy/src/Database/TenantDatabaseManagers/PermissionControlledMySQLDatabaseManager.php
lukinovec 0fdb8b2041 Validate user passwords in DB managers
Also, make the validateParameter method ignore null parameters, e.g. for cases when tenants are created using Tenant::make() without tenancy_db_username set -- $databaseConfig->getUsername() allows null, same should go for the validate method whose only concern is checking strings for invalid characters.
2026-04-29 17:35:11 +02:00

63 lines
2.3 KiB
PHP

<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Database\TenantDatabaseManagers;
use Stancl\Tenancy\Database\Concerns\CreatesDatabaseUsers;
use Stancl\Tenancy\Database\Contracts\ManagesDatabaseUsers;
use Stancl\Tenancy\Database\DatabaseConfig;
class PermissionControlledMySQLDatabaseManager extends MySQLDatabaseManager implements ManagesDatabaseUsers
{
use CreatesDatabaseUsers;
/** @var string[] */
public static array $grants = [
'ALTER', 'ALTER ROUTINE', 'CREATE', 'CREATE ROUTINE', 'CREATE TEMPORARY TABLES', 'CREATE VIEW',
'DELETE', 'DROP', 'EVENT', 'EXECUTE', 'INDEX', 'INSERT', 'LOCK TABLES', 'REFERENCES', 'SELECT',
'SHOW VIEW', 'TRIGGER', 'UPDATE',
];
public function createUser(DatabaseConfig $databaseConfig): bool
{
$database = $databaseConfig->getName();
$username = $databaseConfig->getUsername();
$password = $databaseConfig->getPassword();
$this->validateParameter([$database, $username]);
$this->validatePassword($password);
$this->connection()->statement("CREATE USER `{$username}`@`%` IDENTIFIED BY '{$password}'");
$grants = implode(', ', static::$grants);
if ($this->isVersion8()) { // MySQL 8+
$grantQuery = "GRANT $grants ON `$database`.* TO `$username`@`%`";
} else { // MySQL 5.7
$grantQuery = "GRANT $grants ON `$database`.* TO `$username`@`%` IDENTIFIED BY '$password'";
}
return $this->connection()->statement($grantQuery);
}
protected function isVersion8(): bool
{
$versionSelect = (string) $this->connection()->raw('select version()')->getValue($this->connection()->getQueryGrammar());
$version = $this->connection()->select($versionSelect)[0]->{'version()'};
return version_compare($version, '8.0.0') >= 0;
}
public function deleteUser(DatabaseConfig $databaseConfig): bool
{
$username = $this->validateParameter($databaseConfig->getUsername());
return $this->connection()->statement("DROP USER IF EXISTS '{$username}'");
}
public function userExists(string $username): bool
{
return (bool) $this->connection()->select('SELECT count(*) FROM mysql.user WHERE user = ?', [$username])[0]->{'count(*)'};
}
}