From 03a497fb8a9618f6f94bd9f5d9ddaba002ac1672 Mon Sep 17 00:00:00 2001 From: DaneEveritt Date: Mon, 30 May 2022 17:28:42 -0400 Subject: [PATCH] Use a post request to delete SSH keys, some hashes use slashes which cause 404 errors; closes #4100 --- .../Api/Client/SSHKeyController.php | 20 ++++++++++++------- resources/scripts/api/account/ssh-keys.ts | 2 +- routes/api-client.php | 2 +- .../Client/ClientApiIntegrationTestCase.php | 5 ----- .../Api/Client/SSHKeyControllerTest.php | 12 ++++++++--- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/app/Http/Controllers/Api/Client/SSHKeyController.php b/app/Http/Controllers/Api/Client/SSHKeyController.php index 6af36827e..7d0902d36 100644 --- a/app/Http/Controllers/Api/Client/SSHKeyController.php +++ b/app/Http/Controllers/Api/Client/SSHKeyController.php @@ -45,16 +45,22 @@ class SSHKeyController extends ClientApiController /** * Deletes an SSH key from the user's account. */ - public function delete(ClientApiRequest $request, string $identifier): JsonResponse + public function delete(ClientApiRequest $request): JsonResponse { - $key = $request->user()->sshKeys()->where('fingerprint', $identifier)->firstOrFail(); + $this->validate($request, ['fingerprint' => ['required', 'string']]); - $key->delete(); + $key = $request->user()->sshKeys() + ->where('fingerprint', $request->input('fingerprint')) + ->first(); - Activity::event('user:ssh-key.delete') - ->subject($key) - ->property('fingerprint', $key->fingerprint) - ->log(); + if (!is_null($key)) { + $key->delete(); + + Activity::event('user:ssh-key.delete') + ->subject($key) + ->property('fingerprint', $key->fingerprint) + ->log(); + } return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT); } diff --git a/resources/scripts/api/account/ssh-keys.ts b/resources/scripts/api/account/ssh-keys.ts index baf3b609c..53571c669 100644 --- a/resources/scripts/api/account/ssh-keys.ts +++ b/resources/scripts/api/account/ssh-keys.ts @@ -23,6 +23,6 @@ const createSSHKey = async (name: string, publicKey: string): Promise => }; const deleteSSHKey = async (fingerprint: string): Promise => - await http.delete(`/api/client/account/ssh-keys/${fingerprint}`); + await http.post('/api/client/account/ssh-keys/remove', { fingerprint }); export { useSSHKeys, createSSHKey, deleteSSHKey }; diff --git a/routes/api-client.php b/routes/api-client.php index dc88eaee0..58312eb2a 100644 --- a/routes/api-client.php +++ b/routes/api-client.php @@ -39,7 +39,7 @@ Route::prefix('/account')->middleware(AccountActivitySubject::class)->group(func Route::prefix('/ssh-keys')->group(function () { Route::get('/', [Client\SSHKeyController::class, 'index']); Route::post('/', [Client\SSHKeyController::class, 'store']); - Route::delete('/{identifier}', [Client\SSHKeyController::class, 'delete']); + Route::post('/remove', [Client\SSHKeyController::class, 'delete']); }); }); diff --git a/tests/Integration/Api/Client/ClientApiIntegrationTestCase.php b/tests/Integration/Api/Client/ClientApiIntegrationTestCase.php index 03b80eba4..b7379f4de 100644 --- a/tests/Integration/Api/Client/ClientApiIntegrationTestCase.php +++ b/tests/Integration/Api/Client/ClientApiIntegrationTestCase.php @@ -14,7 +14,6 @@ use Pterodactyl\Models\Location; use Pterodactyl\Models\Schedule; use Illuminate\Support\Collection; use Pterodactyl\Models\Allocation; -use Pterodactyl\Models\UserSSHKey; use Pterodactyl\Models\DatabaseHost; use Pterodactyl\Tests\Integration\TestResponse; use Pterodactyl\Tests\Integration\IntegrationTestCase; @@ -60,7 +59,6 @@ abstract class ClientApiIntegrationTestCase extends IntegrationTestCase */ protected function link($model, $append = null): string { - $link = ''; switch (get_class($model)) { case Server::class: $link = "/api/client/servers/{$model->uuid}"; @@ -77,9 +75,6 @@ abstract class ClientApiIntegrationTestCase extends IntegrationTestCase case Backup::class: $link = "/api/client/servers/{$model->server->uuid}/backups/{$model->uuid}"; break; - case UserSSHKey::class: - $link = "/api/client/account/ssh-keys/$model->fingerprint"; - break; default: throw new InvalidArgumentException(sprintf('Cannot create link for Model of type %s', class_basename($model))); } diff --git a/tests/Integration/Api/Client/SSHKeyControllerTest.php b/tests/Integration/Api/Client/SSHKeyControllerTest.php index 2af492f56..03d40f709 100644 --- a/tests/Integration/Api/Client/SSHKeyControllerTest.php +++ b/tests/Integration/Api/Client/SSHKeyControllerTest.php @@ -40,14 +40,20 @@ class SSHKeyControllerTest extends ClientApiIntegrationTestCase $key = UserSSHKey::factory()->for($user)->create(); $key2 = UserSSHKey::factory()->for($user2)->create(); + $endpoint = '/api/client/account/ssh-keys/remove'; + $this->actingAs($user); - $this->deleteJson($this->link($key))->assertNoContent(); + $this->postJson($endpoint) + ->assertUnprocessable() + ->assertJsonPath('errors.0.meta', ['source_field' => 'fingerprint', 'rule' => 'required']); + + $this->postJson($endpoint, ['fingerprint' => $key->fingerprint])->assertNoContent(); $this->assertSoftDeleted($key); $this->assertNotSoftDeleted($key2); - $this->deleteJson($this->link($key))->assertNotFound(); - $this->deleteJson($this->link($key2))->assertNotFound(); + $this->postJson($endpoint, ['fingerprint' => $key->fingerprint])->assertNoContent(); + $this->postJson($endpoint, ['fingerprint' => $key2->fingerprint])->assertNoContent(); $this->assertNotSoftDeleted($key2); }