From 23d594f6551938e4e500039721c27245343aac06 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sun, 22 Mar 2020 15:31:25 -0700 Subject: [PATCH] Update all of the permissions checking to be constant based --- .../Client/Servers/WebsocketController.php | 9 ++--- .../Databases/DeleteDatabaseRequest.php | 3 +- .../Servers/Databases/GetDatabasesRequest.php | 3 +- .../Databases/RotatePasswordRequest.php | 8 ++--- .../Databases/StoreDatabaseRequest.php | 3 +- .../Client/Servers/Files/CopyFileRequest.php | 3 +- .../Servers/Files/CreateFolderRequest.php | 8 ++--- .../Servers/Files/DeleteFileRequest.php | 3 +- .../Servers/Files/GetFileContentsRequest.php | 3 +- .../Client/Servers/Files/ListFilesRequest.php | 8 ++--- .../Servers/Files/RenameFileRequest.php | 3 +- .../Servers/Files/WriteFileContentRequest.php | 3 +- .../Servers/Network/GetNetworkRequest.php | 8 ++--- .../Api/Client/Servers/SendCommandRequest.php | 8 ++--- .../Api/Client/Servers/SendPowerRequest.php | 19 +++++++--- .../Servers/Settings/RenameServerRequest.php | 3 +- .../Servers/Subusers/GetSubuserRequest.php | 7 ++-- app/Models/Permission.php | 36 +++++++++++++++++++ 18 files changed, 98 insertions(+), 40 deletions(-) diff --git a/app/Http/Controllers/Api/Client/Servers/WebsocketController.php b/app/Http/Controllers/Api/Client/Servers/WebsocketController.php index 4468aa733..1624c75a2 100644 --- a/app/Http/Controllers/Api/Client/Servers/WebsocketController.php +++ b/app/Http/Controllers/Api/Client/Servers/WebsocketController.php @@ -4,14 +4,15 @@ namespace Pterodactyl\Http\Controllers\Api\Client\Servers; use Cake\Chronos\Chronos; use Lcobucci\JWT\Builder; -use Illuminate\Http\Request; use Lcobucci\JWT\Signer\Key; use Illuminate\Http\Response; use Pterodactyl\Models\Server; use Illuminate\Http\JsonResponse; +use Pterodactyl\Models\Permission; use Lcobucci\JWT\Signer\Hmac\Sha256; use Illuminate\Contracts\Cache\Repository; use Symfony\Component\HttpKernel\Exception\HttpException; +use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; use Pterodactyl\Http\Controllers\Api\Client\ClientApiController; class WebsocketController extends ClientApiController @@ -39,13 +40,13 @@ class WebsocketController extends ClientApiController * allows us to continually renew this token and avoid users mainitaining sessions wrongly, * as well as ensure that user's only perform actions they're allowed to. * - * @param \Illuminate\Http\Request $request + * @param \Pterodactyl\Http\Requests\Api\Client\ClientApiRequest $request * @param \Pterodactyl\Models\Server $server * @return \Illuminate\Http\JsonResponse */ - public function __invoke(Request $request, Server $server) + public function __invoke(ClientApiRequest $request, Server $server) { - if (! $request->user()->can('websocket.*', $server)) { + if ($request->user()->cannot(Permission::ACTION_WEBSOCKET, $server)) { throw new HttpException( Response::HTTP_FORBIDDEN, 'You do not have permission to connect to this server\'s websocket.' ); diff --git a/app/Http/Requests/Api/Client/Servers/Databases/DeleteDatabaseRequest.php b/app/Http/Requests/Api/Client/Servers/Databases/DeleteDatabaseRequest.php index 6d3efafb0..c2161680a 100644 --- a/app/Http/Requests/Api/Client/Servers/Databases/DeleteDatabaseRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Databases/DeleteDatabaseRequest.php @@ -4,6 +4,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Databases; use Pterodactyl\Models\Server; use Pterodactyl\Models\Database; +use Pterodactyl\Models\Permission; use Pterodactyl\Contracts\Http\ClientPermissionsRequest; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; @@ -14,7 +15,7 @@ class DeleteDatabaseRequest extends ClientApiRequest implements ClientPermission */ public function permission(): string { - return 'database.delete'; + return Permission::ACTION_DATABASE_DELETE; } /** diff --git a/app/Http/Requests/Api/Client/Servers/Databases/GetDatabasesRequest.php b/app/Http/Requests/Api/Client/Servers/Databases/GetDatabasesRequest.php index 50610d748..be78b5ebb 100644 --- a/app/Http/Requests/Api/Client/Servers/Databases/GetDatabasesRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Databases/GetDatabasesRequest.php @@ -2,6 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Databases; +use Pterodactyl\Models\Permission; use Pterodactyl\Contracts\Http\ClientPermissionsRequest; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; @@ -12,6 +13,6 @@ class GetDatabasesRequest extends ClientApiRequest implements ClientPermissionsR */ public function permission(): string { - return 'database.read'; + return Permission::ACTION_DATABASE_READ; } } diff --git a/app/Http/Requests/Api/Client/Servers/Databases/RotatePasswordRequest.php b/app/Http/Requests/Api/Client/Servers/Databases/RotatePasswordRequest.php index e07a476ba..7869cbf35 100644 --- a/app/Http/Requests/Api/Client/Servers/Databases/RotatePasswordRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Databases/RotatePasswordRequest.php @@ -2,7 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Databases; -use Pterodactyl\Models\Server; +use Pterodactyl\Models\Permission; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; class RotatePasswordRequest extends ClientApiRequest @@ -10,10 +10,10 @@ class RotatePasswordRequest extends ClientApiRequest /** * Check that the user has permission to rotate the password. * - * @return bool + * @return string */ - public function authorize(): bool + public function permission(): string { - return $this->user()->can('database.update', $this->getModel(Server::class)); + return Permission::ACTION_DATABASE_UPDATE; } } diff --git a/app/Http/Requests/Api/Client/Servers/Databases/StoreDatabaseRequest.php b/app/Http/Requests/Api/Client/Servers/Databases/StoreDatabaseRequest.php index 1f8e18c3e..ebff178c2 100644 --- a/app/Http/Requests/Api/Client/Servers/Databases/StoreDatabaseRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Databases/StoreDatabaseRequest.php @@ -2,6 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Databases; +use Pterodactyl\Models\Permission; use Pterodactyl\Contracts\Http\ClientPermissionsRequest; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; @@ -12,7 +13,7 @@ class StoreDatabaseRequest extends ClientApiRequest implements ClientPermissions */ public function permission(): string { - return 'database.create'; + return Permission::ACTION_DATABASE_CREATE; } /** diff --git a/app/Http/Requests/Api/Client/Servers/Files/CopyFileRequest.php b/app/Http/Requests/Api/Client/Servers/Files/CopyFileRequest.php index 416eaa27e..97bfc3fba 100644 --- a/app/Http/Requests/Api/Client/Servers/Files/CopyFileRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Files/CopyFileRequest.php @@ -2,6 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Files; +use Pterodactyl\Models\Permission; use Pterodactyl\Contracts\Http\ClientPermissionsRequest; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; @@ -12,7 +13,7 @@ class CopyFileRequest extends ClientApiRequest implements ClientPermissionsReque */ public function permission(): string { - return 'file.create'; + return Permission::ACTION_FILE_CREATE; } /** diff --git a/app/Http/Requests/Api/Client/Servers/Files/CreateFolderRequest.php b/app/Http/Requests/Api/Client/Servers/Files/CreateFolderRequest.php index ea4354de0..10457ffea 100644 --- a/app/Http/Requests/Api/Client/Servers/Files/CreateFolderRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Files/CreateFolderRequest.php @@ -2,7 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Files; -use Pterodactyl\Models\Server; +use Pterodactyl\Models\Permission; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; class CreateFolderRequest extends ClientApiRequest @@ -10,11 +10,11 @@ class CreateFolderRequest extends ClientApiRequest /** * Checks that the authenticated user is allowed to create files on the server. * - * @return bool + * @return string */ - public function authorize(): bool + public function permission(): string { - return $this->user()->can('file.create', $this->getModel(Server::class)); + return Permission::ACTION_FILE_CREATE; } /** diff --git a/app/Http/Requests/Api/Client/Servers/Files/DeleteFileRequest.php b/app/Http/Requests/Api/Client/Servers/Files/DeleteFileRequest.php index 3c94fd7e9..dcf1d2a95 100644 --- a/app/Http/Requests/Api/Client/Servers/Files/DeleteFileRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Files/DeleteFileRequest.php @@ -2,6 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Files; +use Pterodactyl\Models\Permission; use Pterodactyl\Contracts\Http\ClientPermissionsRequest; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; @@ -12,7 +13,7 @@ class DeleteFileRequest extends ClientApiRequest implements ClientPermissionsReq */ public function permission(): string { - return 'file.delete'; + return Permission::ACTION_FILE_DELETE; } /** diff --git a/app/Http/Requests/Api/Client/Servers/Files/GetFileContentsRequest.php b/app/Http/Requests/Api/Client/Servers/Files/GetFileContentsRequest.php index 79484d77c..25dc4f1e1 100644 --- a/app/Http/Requests/Api/Client/Servers/Files/GetFileContentsRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Files/GetFileContentsRequest.php @@ -2,6 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Files; +use Pterodactyl\Models\Permission; use Pterodactyl\Contracts\Http\ClientPermissionsRequest; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; @@ -16,7 +17,7 @@ class GetFileContentsRequest extends ClientApiRequest implements ClientPermissio */ public function permission(): string { - return 'file.read'; + return Permission::ACTION_FILE_READ; } /** diff --git a/app/Http/Requests/Api/Client/Servers/Files/ListFilesRequest.php b/app/Http/Requests/Api/Client/Servers/Files/ListFilesRequest.php index 2342360d0..4f71648c6 100644 --- a/app/Http/Requests/Api/Client/Servers/Files/ListFilesRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Files/ListFilesRequest.php @@ -2,7 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Files; -use Pterodactyl\Models\Server; +use Pterodactyl\Models\Permission; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; class ListFilesRequest extends ClientApiRequest @@ -11,11 +11,11 @@ class ListFilesRequest extends ClientApiRequest * Check that the user making this request to the API is authorized to list all * of the files that exist for a given server. * - * @return bool + * @return string */ - public function authorize(): bool + public function permission(): string { - return $this->user()->can('file.read', $this->getModel(Server::class)); + return Permission::ACTION_FILE_READ; } /** diff --git a/app/Http/Requests/Api/Client/Servers/Files/RenameFileRequest.php b/app/Http/Requests/Api/Client/Servers/Files/RenameFileRequest.php index 6aa29be6d..2e828754b 100644 --- a/app/Http/Requests/Api/Client/Servers/Files/RenameFileRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Files/RenameFileRequest.php @@ -2,6 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Files; +use Pterodactyl\Models\Permission; use Pterodactyl\Contracts\Http\ClientPermissionsRequest; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; @@ -15,7 +16,7 @@ class RenameFileRequest extends ClientApiRequest implements ClientPermissionsReq */ public function permission(): string { - return 'file.update'; + return Permission::ACTION_FILE_UPDATE; } /** diff --git a/app/Http/Requests/Api/Client/Servers/Files/WriteFileContentRequest.php b/app/Http/Requests/Api/Client/Servers/Files/WriteFileContentRequest.php index b4de3d93d..d5db8c241 100644 --- a/app/Http/Requests/Api/Client/Servers/Files/WriteFileContentRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Files/WriteFileContentRequest.php @@ -2,6 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Files; +use Pterodactyl\Models\Permission; use Pterodactyl\Contracts\Http\ClientPermissionsRequest; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; @@ -16,7 +17,7 @@ class WriteFileContentRequest extends ClientApiRequest implements ClientPermissi */ public function permission(): string { - return 'file.create'; + return Permission::ACTION_FILE_CREATE; } /** diff --git a/app/Http/Requests/Api/Client/Servers/Network/GetNetworkRequest.php b/app/Http/Requests/Api/Client/Servers/Network/GetNetworkRequest.php index 6da73b59e..bf737de72 100644 --- a/app/Http/Requests/Api/Client/Servers/Network/GetNetworkRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Network/GetNetworkRequest.php @@ -2,7 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Network; -use Pterodactyl\Models\Server; +use Pterodactyl\Models\Permission; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; class GetNetworkRequest extends ClientApiRequest @@ -11,10 +11,10 @@ class GetNetworkRequest extends ClientApiRequest * Check that the user has permission to view the allocations for * this server. * - * @return bool + * @return string */ - public function authorize(): bool + public function permission(): string { - return $this->user()->can('allocation.read', $this->getModel(Server::class)); + return Permission::ACTION_ALLOCATION_READ; } } diff --git a/app/Http/Requests/Api/Client/Servers/SendCommandRequest.php b/app/Http/Requests/Api/Client/Servers/SendCommandRequest.php index 966363ae6..fe0dd1757 100644 --- a/app/Http/Requests/Api/Client/Servers/SendCommandRequest.php +++ b/app/Http/Requests/Api/Client/Servers/SendCommandRequest.php @@ -2,18 +2,18 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers; -use Pterodactyl\Models\Server; +use Pterodactyl\Models\Permission; class SendCommandRequest extends GetServerRequest { /** * Determine if the API user has permission to perform this action. * - * @return bool + * @return string */ - public function authorize(): bool + public function permission(): string { - return $this->user()->can('control.console', $this->getModel(Server::class)); + return Permission::ACTION_CONTROL_CONSOLE; } /** diff --git a/app/Http/Requests/Api/Client/Servers/SendPowerRequest.php b/app/Http/Requests/Api/Client/Servers/SendPowerRequest.php index 1f0bff487..8686b4f67 100644 --- a/app/Http/Requests/Api/Client/Servers/SendPowerRequest.php +++ b/app/Http/Requests/Api/Client/Servers/SendPowerRequest.php @@ -2,7 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers; -use Pterodactyl\Models\Server; +use Pterodactyl\Models\Permission; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; class SendPowerRequest extends ClientApiRequest @@ -10,11 +10,22 @@ class SendPowerRequest extends ClientApiRequest /** * Determine if the user has permission to send a power command to a server. * - * @return bool + * @return string */ - public function authorize(): bool + public function permission(): string { - return $this->user()->can('control.' . $this->input('signal', ''), $this->getModel(Server::class)); + switch ($this->input('signal')) { + case 'start': + return Permission::ACTION_CONTROL_START; + case 'stop': + return Permission::ACTION_CONTROL_STOP; + case 'restart': + return Permission::ACTION_CONTROL_RESTART; + case 'kill': + return Permission::ACTION_CONTROL_KILL; + } + + return '__invalid'; } /** diff --git a/app/Http/Requests/Api/Client/Servers/Settings/RenameServerRequest.php b/app/Http/Requests/Api/Client/Servers/Settings/RenameServerRequest.php index fff2661f7..14b117211 100644 --- a/app/Http/Requests/Api/Client/Servers/Settings/RenameServerRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Settings/RenameServerRequest.php @@ -3,6 +3,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Settings; use Pterodactyl\Models\Server; +use Pterodactyl\Models\Permission; use Pterodactyl\Contracts\Http\ClientPermissionsRequest; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; @@ -17,7 +18,7 @@ class RenameServerRequest extends ClientApiRequest implements ClientPermissionsR */ public function permission(): string { - return 'settings.rename'; + return Permission::ACTION_SETTINGS_RENAME; } /** diff --git a/app/Http/Requests/Api/Client/Servers/Subusers/GetSubuserRequest.php b/app/Http/Requests/Api/Client/Servers/Subusers/GetSubuserRequest.php index 729d6d0dc..e4d548f95 100644 --- a/app/Http/Requests/Api/Client/Servers/Subusers/GetSubuserRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Subusers/GetSubuserRequest.php @@ -2,6 +2,7 @@ namespace Pterodactyl\Http\Requests\Api\Client\Servers\Subusers; +use Pterodactyl\Models\Permission; use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; class GetSubuserRequest extends ClientApiRequest @@ -9,10 +10,10 @@ class GetSubuserRequest extends ClientApiRequest /** * Confirm that a user is able to view subusers for the specified server. * - * @return bool + * @return string */ - public function authorize(): bool + public function permission(): string { - return $this->user()->can('user.read', $this->route()->parameter('server')); + return Permission::ACTION_USER_READ; } } diff --git a/app/Models/Permission.php b/app/Models/Permission.php index 14c36b788..dd3292d8b 100644 --- a/app/Models/Permission.php +++ b/app/Models/Permission.php @@ -15,11 +15,42 @@ class Permission extends Validable /** * Constants defining different permissions available. */ + const ACTION_WEBSOCKET = 'websocket.*'; + const ACTION_CONTROL_CONSOLE = 'control.console'; + const ACTION_CONTROL_START = 'control.start'; + const ACTION_CONTROL_STOP = 'control.stop'; + const ACTION_CONTROL_RESTART = 'control.restart'; + const ACTION_CONTROL_KILL = 'control.kill'; + + const ACTION_DATABASE_READ = 'database.read'; + const ACTION_DATABASE_CREATE = 'database.create'; + const ACTION_DATABASE_UPDATE = 'database.update'; + const ACTION_DATABASE_DELETE = 'database.delete'; + const ACTION_DATABASE_VIEW_PASSWORD = 'database.view_password'; + const ACTION_SCHEDULE_READ = 'schedule.read'; const ACTION_SCHEDULE_CREATE = 'schedule.create'; const ACTION_SCHEDULE_UPDATE = 'schedule.update'; const ACTION_SCHEDULE_DELETE = 'schedule.delete'; + const ACTION_USER_READ = 'user.read'; + const ACTION_USER_CREATE = 'user.create'; + const ACTION_USER_UPDATE = 'user.update'; + const ACTION_USER_DELETE = 'user.delete'; + + const ACTION_ALLOCATION_READ = 'allocation.read'; + const ACTION_ALLOCIATION_UPDATE = 'allocation.update'; + + const ACTION_FILE_READ = 'file.read'; + const ACTION_FILE_CREATE = 'file.create'; + const ACTION_FILE_UPDATE = 'file.update'; + const ACTION_FILE_DELETE = 'file.delete'; + const ACTION_FILE_ARCHIVE = 'file.archive'; + const ACTION_FILE_SFTP = 'file.sftp'; + + const ACTION_SETTINGS_RENAME = 'settings.rename'; + const ACTION_SETTINGS_REINSTALL = 'settings.reinstall'; + /** * Should timestamps be used on this model. * @@ -162,6 +193,11 @@ class Permission extends Validable 'update', // task.edit-schedule, task.queue-schedule, task.toggle-schedule 'delete', // task.delete-schedule ], + + 'settings' => [ + 'rename', + 'reinstall', + ], ]; /**