mirror of
https://github.com/archtechx/tenancy.git
synced 2026-06-21 03:04:04 +00:00
refactor: only accept single values in validateParameter()
this is to make handling null easier (previous Arr::wrap() approach turned null into an empty array rather than [null] requiring two separate null checks) and testing easier (we use empty arrays as examples of invalid values in some tests which would previously be accepted when passed individually as validateParameter([]) rather than being part of a wider [something, [], ...] array) also restrict passing null to validatePassword() also minor grammar fix in the validateParameter() docblock
This commit is contained in:
parent
0fdc59dc5d
commit
a7aa03158d
6 changed files with 33 additions and 27 deletions
|
|
@ -38,23 +38,16 @@ trait ValidatesDatabaseParameters
|
||||||
public static string $allowedPasswordCharacters = ' !#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~';
|
public static string $allowedPasswordCharacters = ' !#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure that parameters (database names, usernames, etc.)
|
* Ensure that parameter (database name, username, etc.)
|
||||||
* only contain allowed characters before used in SQL statements
|
* only contains allowed characters before being used in SQL statements
|
||||||
* (or paths in the case of SQLiteDatabaseManager).
|
* (or paths in the case of SQLiteDatabaseManager).
|
||||||
*
|
*
|
||||||
* By default, only the characters in allowedParameterCharacters() are allowed.
|
* By default, only the characters in allowedParameterCharacters() are allowed.
|
||||||
*
|
*
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
protected function validateParameter(string|array|null $parameters, string|null $allowedCharacters = null): void
|
protected function validateParameter(mixed $parameter, string|null $allowedCharacters = null): void
|
||||||
{
|
{
|
||||||
if ($parameters === null) {
|
|
||||||
throw new InvalidArgumentException('Parameter cannot be null.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$allowedCharacters ??= static::$allowedParameterCharacters;
|
|
||||||
|
|
||||||
foreach (Arr::wrap($parameters) as $parameter) {
|
|
||||||
if (is_null($parameter)) {
|
if (is_null($parameter)) {
|
||||||
throw new InvalidArgumentException('Parameter cannot be null.');
|
throw new InvalidArgumentException('Parameter cannot be null.');
|
||||||
}
|
}
|
||||||
|
|
@ -68,13 +61,14 @@ trait ValidatesDatabaseParameters
|
||||||
throw new InvalidArgumentException('Parameter has to be a string.');
|
throw new InvalidArgumentException('Parameter has to be a string.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$allowedCharacters ??= static::$allowedParameterCharacters;
|
||||||
|
|
||||||
foreach (str_split($parameter) as $character) {
|
foreach (str_split($parameter) as $character) {
|
||||||
if (! str_contains($allowedCharacters, $character)) {
|
if (! str_contains($allowedCharacters, $character)) {
|
||||||
throw new InvalidArgumentException("Forbidden character '{$character}' in parameter.");
|
throw new InvalidArgumentException("Forbidden character '{$character}' in parameter.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure password only contains allowed characters (allowedPasswordCharacters())
|
* Ensure password only contains allowed characters (allowedPasswordCharacters())
|
||||||
|
|
@ -87,6 +81,10 @@ trait ValidatesDatabaseParameters
|
||||||
*/
|
*/
|
||||||
protected function validatePassword(string|null $password): void
|
protected function validatePassword(string|null $password): void
|
||||||
{
|
{
|
||||||
|
if (is_null($password)) {
|
||||||
|
throw new InvalidArgumentException('Parameter cannot be null.');
|
||||||
|
}
|
||||||
|
|
||||||
$this->validateParameter($password, allowedCharacters: static::$allowedPasswordCharacters);
|
$this->validateParameter($password, allowedCharacters: static::$allowedPasswordCharacters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ class MySQLDatabaseManager extends TenantDatabaseManager
|
||||||
$charset = $this->connection()->getConfig('charset');
|
$charset = $this->connection()->getConfig('charset');
|
||||||
$collation = $this->connection()->getConfig('collation');
|
$collation = $this->connection()->getConfig('collation');
|
||||||
|
|
||||||
$this->validateParameter(array_filter([$database, $charset, $collation], fn ($param) => $param !== null));
|
$this->validateParameter($database);
|
||||||
|
|
||||||
// MySQL defaults to the server's charset and collation
|
// MySQL defaults to the server's charset and collation
|
||||||
// if charset and collation are not specified.
|
// if charset and collation are not specified.
|
||||||
|
|
@ -23,10 +23,12 @@ class MySQLDatabaseManager extends TenantDatabaseManager
|
||||||
$statement = "CREATE DATABASE `{$database}`";
|
$statement = "CREATE DATABASE `{$database}`";
|
||||||
|
|
||||||
if ($charset !== null) {
|
if ($charset !== null) {
|
||||||
|
$this->validateParameter($charset);
|
||||||
$statement .= " CHARACTER SET `{$charset}`";
|
$statement .= " CHARACTER SET `{$charset}`";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($collation !== null) {
|
if ($collation !== null) {
|
||||||
|
$this->validateParameter($collation);
|
||||||
$statement .= " COLLATE `{$collation}`";
|
$statement .= " COLLATE `{$collation}`";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ class PermissionControlledMicrosoftSQLServerDatabaseManager extends MicrosoftSQL
|
||||||
$username = $databaseConfig->getUsername();
|
$username = $databaseConfig->getUsername();
|
||||||
$password = $databaseConfig->getPassword();
|
$password = $databaseConfig->getPassword();
|
||||||
|
|
||||||
$this->validateParameter([$database, $username]);
|
$this->validateParameter($database);
|
||||||
|
$this->validateParameter($username);
|
||||||
$this->validatePassword($password);
|
$this->validatePassword($password);
|
||||||
|
|
||||||
// Create login
|
// Create login
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ class PermissionControlledMySQLDatabaseManager extends MySQLDatabaseManager impl
|
||||||
$username = $databaseConfig->getUsername();
|
$username = $databaseConfig->getUsername();
|
||||||
$password = $databaseConfig->getPassword();
|
$password = $databaseConfig->getPassword();
|
||||||
|
|
||||||
$this->validateParameter([$database, $username]);
|
$this->validateParameter($database);
|
||||||
|
$this->validateParameter($username);
|
||||||
$this->validatePassword($password);
|
$this->validatePassword($password);
|
||||||
|
|
||||||
$this->connection()->statement("CREATE USER `{$username}`@`%` IDENTIFIED BY '{$password}'");
|
$this->connection()->statement("CREATE USER `{$username}`@`%` IDENTIFIED BY '{$password}'");
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,9 @@ class PermissionControlledPostgreSQLDatabaseManager extends PostgreSQLDatabaseMa
|
||||||
$username = $databaseConfig->getUsername();
|
$username = $databaseConfig->getUsername();
|
||||||
$schema = $databaseConfig->connection()['search_path'];
|
$schema = $databaseConfig->connection()['search_path'];
|
||||||
|
|
||||||
$this->validateParameter([$database, $username, $schema]);
|
$this->validateParameter($database);
|
||||||
|
$this->validateParameter($username);
|
||||||
|
$this->validateParameter($schema);
|
||||||
|
|
||||||
// Host config
|
// Host config
|
||||||
$connectionName = $this->connection()->getConfig('name');
|
$connectionName = $this->connection()->getConfig('name');
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@ class PermissionControlledPostgreSQLSchemaManager extends PostgreSQLSchemaManage
|
||||||
// Central database name
|
// Central database name
|
||||||
$database = DB::connection(config('tenancy.database.central_connection'))->getDatabaseName();
|
$database = DB::connection(config('tenancy.database.central_connection'))->getDatabaseName();
|
||||||
|
|
||||||
$this->validateParameter([$username, $schema, $database]);
|
$this->validateParameter($username);
|
||||||
|
$this->validateParameter($schema);
|
||||||
|
$this->validateParameter($database);
|
||||||
|
|
||||||
$this->connection()->statement("GRANT CONNECT ON DATABASE \"{$database}\" TO \"{$username}\"");
|
$this->connection()->statement("GRANT CONNECT ON DATABASE \"{$database}\" TO \"{$username}\"");
|
||||||
$this->connection()->statement("GRANT USAGE, CREATE ON SCHEMA \"{$schema}\" TO \"{$username}\"");
|
$this->connection()->statement("GRANT USAGE, CREATE ON SCHEMA \"{$schema}\" TO \"{$username}\"");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue