Update all of the permissions checking to be constant based

This commit is contained in:
Dane Everitt 2020-03-22 15:31:25 -07:00
parent 605c154812
commit 23d594f655
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
18 changed files with 98 additions and 40 deletions

View File

@ -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.'
);

View File

@ -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;
}
/**

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
/**

View File

@ -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;
}
/**

View File

@ -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;
}
/**

View File

@ -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;
}
/**

View File

@ -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;
}
/**

View File

@ -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;
}
/**

View File

@ -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;
}
/**

View File

@ -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;
}
/**

View File

@ -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;
}
}

View File

@ -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;
}
/**

View File

@ -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';
}
/**

View File

@ -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;
}
/**

View File

@ -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;
}
}

View File

@ -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',
],
];
/**