From a4d7170facb77b85af34c841b928911973abb840 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 10 Oct 2020 18:17:04 -0700 Subject: [PATCH] Don't allow creation of a database with an identical name for the same server; closes #2447 --- .../Databases/StoreDatabaseRequest.php | 28 ++++++++++++- ...ue_database_name_to_account_for_server.php | 41 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 database/migrations/2020_10_10_165437_change_unique_database_name_to_account_for_server.php diff --git a/app/Http/Requests/Api/Client/Servers/Databases/StoreDatabaseRequest.php b/app/Http/Requests/Api/Client/Servers/Databases/StoreDatabaseRequest.php index 3f2fe29eb..dc85467aa 100644 --- a/app/Http/Requests/Api/Client/Servers/Databases/StoreDatabaseRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Databases/StoreDatabaseRequest.php @@ -2,7 +2,11 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Databases; +use Webmozart\Assert\Assert; +use Pterodactyl\Models\Server; +use Illuminate\Validation\Rule; use Pterodactyl\Models\Permission; +use Illuminate\Database\Query\Builder; use Pterodactyl\Contracts\Http\ClientPermissionsRequest; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; @@ -21,9 +25,31 @@ class StoreDatabaseRequest extends ClientApiRequest implements ClientPermissions */ public function rules(): array { + $server = $this->route()->parameter('server'); + + Assert::isInstanceOf($server, Server::class); + return [ - 'database' => 'required|alpha_dash|min:3|max:48', + 'database' => [ + 'required', + 'alpha_dash', + 'min:3', + 'max:48', + // Yes, I am aware that you could have the same database name across two unique hosts. However, + // I don't really care about that for this validation. We just want to make sure it is unique to + // the server itself. No need for complexity. + Rule::unique('databases', 'database')->where(function (Builder $query) use ($server) { + $query->where('server_id', $server->id); + }), + ], 'remote' => 'required|string|regex:/^[0-9%.]{1,15}$/', ]; } + + public function messages() + { + return [ + 'database.unique' => 'The database name you have selected is already in use by this server.', + ]; + } } diff --git a/database/migrations/2020_10_10_165437_change_unique_database_name_to_account_for_server.php b/database/migrations/2020_10_10_165437_change_unique_database_name_to_account_for_server.php new file mode 100644 index 000000000..a32d52e6e --- /dev/null +++ b/database/migrations/2020_10_10_165437_change_unique_database_name_to_account_for_server.php @@ -0,0 +1,41 @@ +dropUnique(['database_host_id', 'database']); + }); + + Schema::table('databases', function (Blueprint $table) { + $table->unique(['database_host_id', 'server_id', 'database']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('databases', function (Blueprint $table) { + $table->dropUnique(['database_host_id', 'server_id', 'database']); + }); + + Schema::table('databases', function (Blueprint $table) { + $table->unique(['database_host_id', 'database']); + }); + + } +}