From 375e33830976bf643daa20fa0b322b48f1578689 Mon Sep 17 00:00:00 2001 From: Eric Wang <37554696+ericwang401@users.noreply.github.com> Date: Mon, 27 Nov 2023 20:46:08 -0600 Subject: [PATCH] use policy authorization for client-side server endpoints --- .../Client/Servers/BackupController.php | 42 ++++--- .../Addresses/StoreAddressRequest.php | 4 +- .../Addresses/UpdateAddressRequest.php | 4 +- .../AddressPools/UpdateAddressPoolRequest.php | 4 +- .../Admin/Nodes/Isos/StoreIsoRequest.php | 4 +- .../Admin/Nodes/Isos/UpdateIsoRequest.php | 4 +- .../Nodes/Settings/UpdateCotermRequest.php | 4 +- .../Admin/Nodes/UpdateNodeRequest.php | 4 +- .../Servers/Settings/UpdateBuildRequest.php | 4 +- .../Servers/Settings/UpdateDetailsRequest.php | 4 +- .../Settings/UpdateGeneralInfoRequest.php | 4 +- .../Admin/Servers/StoreServerRequest.php | 4 +- .../Admin/Users/UpdateUserRequest.php | 4 +- app/Http/Requests/BaseApiRequest.php | 109 ++++++++++++++++++ .../Servers/Backups/DeleteBackupRequest.php | 18 +++ .../Servers/Backups/RestoreBackupRequest.php | 18 +++ .../Servers/Backups/StoreBackupRequest.php | 13 +-- .../Servers/CreateConsoleSessionRequest.php | 12 +- .../Servers/SendPowerCommandRequest.php | 14 +-- .../Servers/Settings/MountMediaRequest.php | 4 +- .../Settings/ReinstallServerRequest.php | 4 +- .../Servers/Settings/RenameServerRequest.php | 13 +-- ...uest.php => UpdateAuthSettingsRequest.php} | 13 +-- .../Settings/UpdateBiosTypeRequest.php | 9 +- .../Settings/UpdateBootOrderRequest.php | 15 +-- .../Servers/Settings/UpdateNetworkRequest.php | 8 +- app/Http/Requests/FormRequest.php | 71 ------------ app/Policies/BackupPolicy.php | 46 ++++++++ app/Policies/ServerPolicy.php | 33 ++++++ lang/en_US/exceptions.php | 7 ++ 30 files changed, 317 insertions(+), 180 deletions(-) create mode 100644 app/Http/Requests/BaseApiRequest.php create mode 100644 app/Http/Requests/Client/Servers/Backups/DeleteBackupRequest.php create mode 100644 app/Http/Requests/Client/Servers/Backups/RestoreBackupRequest.php rename app/Http/Requests/Client/Servers/Settings/{UpdateSecurityRequest.php => UpdateAuthSettingsRequest.php} (86%) delete mode 100644 app/Http/Requests/FormRequest.php create mode 100644 app/Policies/BackupPolicy.php create mode 100644 app/Policies/ServerPolicy.php create mode 100644 lang/en_US/exceptions.php diff --git a/app/Http/Controllers/Client/Servers/BackupController.php b/app/Http/Controllers/Client/Servers/BackupController.php index 2fa4b9893a3..43fda8f076e 100644 --- a/app/Http/Controllers/Client/Servers/BackupController.php +++ b/app/Http/Controllers/Client/Servers/BackupController.php @@ -2,6 +2,8 @@ namespace Convoy\Http\Controllers\Client\Servers; +use Convoy\Http\Requests\Client\Servers\Backups\DeleteBackupRequest; +use Convoy\Http\Requests\Client\Servers\Backups\RestoreBackupRequest; use Convoy\Models\Backup; use Convoy\Models\Server; use Illuminate\Http\Request; @@ -19,48 +21,50 @@ class BackupController extends ApplicationApiController { public function __construct( - private BackupCreationService $backupCreationService, - private BackupDeletionService $backupDeletionService, + private BackupCreationService $backupCreationService, + private BackupDeletionService $backupDeletionService, private RestoreFromBackupService $restoreFromBackupService, - private BackupRepository $backupRepository, - ) { + private BackupRepository $backupRepository, + ) + { } - public function index(Server $server, Request $request) + public function index(Request $request, Server $server) { $backups = QueryBuilder::for(Backup::query()) - ->where('backups.server_id', $server->id) - ->allowedFilters(['name']) - ->defaultSort('-created_at') - ->allowedSorts('created_at', 'completed_at') - ->paginate(min($request->query('per_page') ?? 20, 50)); + ->where('backups.server_id', $server->id) + ->allowedFilters(['name']) + ->defaultSort('-created_at') + ->allowedSorts('created_at', 'completed_at') + ->paginate(min($request->query('per_page') ?? 20, 50)); - return fractal($backups, new BackupTransformer)->addMeta([ + return fractal($backups, new BackupTransformer())->addMeta([ 'backup_count' => $this->backupRepository->getNonFailedBackups($server)->count(), ])->respond(); } - public function store(Server $server, StoreBackupRequest $request) + public function store(StoreBackupRequest $request, Server $server) { $backup = $this->backupCreationService - ->create(server: $server, - name: $request->name, - mode: $request->enum('mode', BackupMode::class), + ->create( + server : $server, + name : $request->name, + mode : $request->enum('mode', BackupMode::class), compressionType: $request->enum('compression_type', BackupCompressionType::class), - isLocked: $request->input('locked', false) + isLocked : $request->input('locked', false), ); - return fractal($backup, new BackupTransformer)->respond(); + return fractal($backup, new BackupTransformer())->respond(); } - public function restore(Server $server, Backup $backup) + public function restore(RestoreBackupRequest $request, Server $server, Backup $backup) { $this->restoreFromBackupService->handle($server, $backup); return $this->returnNoContent(); } - public function destroy(Server $server, Backup $backup) + public function destroy(DeleteBackupRequest $request, Server $server, Backup $backup) { $this->backupDeletionService->handle($backup); diff --git a/app/Http/Requests/Admin/AddressPools/Addresses/StoreAddressRequest.php b/app/Http/Requests/Admin/AddressPools/Addresses/StoreAddressRequest.php index d8552917fb4..83c2933a571 100644 --- a/app/Http/Requests/Admin/AddressPools/Addresses/StoreAddressRequest.php +++ b/app/Http/Requests/Admin/AddressPools/Addresses/StoreAddressRequest.php @@ -6,12 +6,12 @@ use Illuminate\Support\Arr; use Convoy\Models\AddressPool; use Illuminate\Validation\Validator; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; use Convoy\Enums\Network\AddressType; use Convoy\Validation\ValidateAddressType; use Convoy\Validation\ValidateAddressUniqueness; -class StoreAddressRequest extends FormRequest +class StoreAddressRequest extends BaseApiRequest { public function rules(): array { diff --git a/app/Http/Requests/Admin/AddressPools/Addresses/UpdateAddressRequest.php b/app/Http/Requests/Admin/AddressPools/Addresses/UpdateAddressRequest.php index 8c59c79405d..7289c2e9668 100644 --- a/app/Http/Requests/Admin/AddressPools/Addresses/UpdateAddressRequest.php +++ b/app/Http/Requests/Admin/AddressPools/Addresses/UpdateAddressRequest.php @@ -6,12 +6,12 @@ use Illuminate\Support\Arr; use Convoy\Models\AddressPool; use Illuminate\Validation\Validator; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; use Convoy\Enums\Network\AddressType; use Convoy\Validation\ValidateAddressType; use Convoy\Validation\ValidateAddressUniqueness; -class UpdateAddressRequest extends FormRequest +class UpdateAddressRequest extends BaseApiRequest { public function rules(): array { diff --git a/app/Http/Requests/Admin/AddressPools/UpdateAddressPoolRequest.php b/app/Http/Requests/Admin/AddressPools/UpdateAddressPoolRequest.php index 277137a24fe..5bd60fb4026 100644 --- a/app/Http/Requests/Admin/AddressPools/UpdateAddressPoolRequest.php +++ b/app/Http/Requests/Admin/AddressPools/UpdateAddressPoolRequest.php @@ -5,9 +5,9 @@ use Convoy\Models\Node; use Convoy\Models\AddressPool; use Illuminate\Validation\Validator; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; -class UpdateAddressPoolRequest extends FormRequest +class UpdateAddressPoolRequest extends BaseApiRequest { public function rules(): array { diff --git a/app/Http/Requests/Admin/Nodes/Isos/StoreIsoRequest.php b/app/Http/Requests/Admin/Nodes/Isos/StoreIsoRequest.php index c1a170eb97e..12f6724aece 100644 --- a/app/Http/Requests/Admin/Nodes/Isos/StoreIsoRequest.php +++ b/app/Http/Requests/Admin/Nodes/Isos/StoreIsoRequest.php @@ -5,12 +5,12 @@ use Convoy\Models\ISO; use Convoy\Models\Node; use Illuminate\Validation\Validator; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; use Illuminate\Validation\Rules\Enum; use Convoy\Services\Nodes\Isos\IsoService; use Convoy\Enums\Helpers\ChecksumAlgorithm; -class StoreIsoRequest extends FormRequest +class StoreIsoRequest extends BaseApiRequest { public function rules(): array { diff --git a/app/Http/Requests/Admin/Nodes/Isos/UpdateIsoRequest.php b/app/Http/Requests/Admin/Nodes/Isos/UpdateIsoRequest.php index 459638ad06d..ce77d91f03c 100644 --- a/app/Http/Requests/Admin/Nodes/Isos/UpdateIsoRequest.php +++ b/app/Http/Requests/Admin/Nodes/Isos/UpdateIsoRequest.php @@ -3,9 +3,9 @@ namespace Convoy\Http\Requests\Admin\Nodes\Isos; use Convoy\Models\ISO; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; -class UpdateIsoRequest extends FormRequest +class UpdateIsoRequest extends BaseApiRequest { public function rules(): array { diff --git a/app/Http/Requests/Admin/Nodes/Settings/UpdateCotermRequest.php b/app/Http/Requests/Admin/Nodes/Settings/UpdateCotermRequest.php index 02d12cbd661..b0750496486 100644 --- a/app/Http/Requests/Admin/Nodes/Settings/UpdateCotermRequest.php +++ b/app/Http/Requests/Admin/Nodes/Settings/UpdateCotermRequest.php @@ -3,9 +3,9 @@ namespace Convoy\Http\Requests\Admin\Nodes\Settings; use Illuminate\Validation\Rule; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; -class UpdateCotermRequest extends FormRequest +class UpdateCotermRequest extends BaseApiRequest { /** * @return array diff --git a/app/Http/Requests/Admin/Nodes/UpdateNodeRequest.php b/app/Http/Requests/Admin/Nodes/UpdateNodeRequest.php index e64a9f98e4e..9616064188a 100644 --- a/app/Http/Requests/Admin/Nodes/UpdateNodeRequest.php +++ b/app/Http/Requests/Admin/Nodes/UpdateNodeRequest.php @@ -5,9 +5,9 @@ use Convoy\Models\Node; use Illuminate\Support\Arr; use Illuminate\Validation\Validator; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; -class UpdateNodeRequest extends FormRequest +class UpdateNodeRequest extends BaseApiRequest { public function rules(): array { diff --git a/app/Http/Requests/Admin/Servers/Settings/UpdateBuildRequest.php b/app/Http/Requests/Admin/Servers/Settings/UpdateBuildRequest.php index 29b88ae9d80..beb4abd3768 100644 --- a/app/Http/Requests/Admin/Servers/Settings/UpdateBuildRequest.php +++ b/app/Http/Requests/Admin/Servers/Settings/UpdateBuildRequest.php @@ -6,9 +6,9 @@ use Convoy\Models\Server; use Convoy\Models\Address; use Illuminate\Validation\Validator; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; -class UpdateBuildRequest extends FormRequest +class UpdateBuildRequest extends BaseApiRequest { public function rules(): array { diff --git a/app/Http/Requests/Admin/Servers/Settings/UpdateDetailsRequest.php b/app/Http/Requests/Admin/Servers/Settings/UpdateDetailsRequest.php index 99a724943ec..4f4ef2b860f 100644 --- a/app/Http/Requests/Admin/Servers/Settings/UpdateDetailsRequest.php +++ b/app/Http/Requests/Admin/Servers/Settings/UpdateDetailsRequest.php @@ -3,9 +3,9 @@ namespace Convoy\Http\Requests\Admin\Servers\Settings; use Convoy\Models\Server; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; -class UpdateDetailsRequest extends FormRequest +class UpdateDetailsRequest extends BaseApiRequest { /** * Determine if the user is authorized to make this request. diff --git a/app/Http/Requests/Admin/Servers/Settings/UpdateGeneralInfoRequest.php b/app/Http/Requests/Admin/Servers/Settings/UpdateGeneralInfoRequest.php index 775b817058e..2903496910b 100644 --- a/app/Http/Requests/Admin/Servers/Settings/UpdateGeneralInfoRequest.php +++ b/app/Http/Requests/Admin/Servers/Settings/UpdateGeneralInfoRequest.php @@ -4,9 +4,9 @@ use Convoy\Models\Server; use Convoy\Rules\Hostname; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; -class UpdateGeneralInfoRequest extends FormRequest +class UpdateGeneralInfoRequest extends BaseApiRequest { public function rules(): array { diff --git a/app/Http/Requests/Admin/Servers/StoreServerRequest.php b/app/Http/Requests/Admin/Servers/StoreServerRequest.php index f9b3b857b15..605445e8cad 100644 --- a/app/Http/Requests/Admin/Servers/StoreServerRequest.php +++ b/app/Http/Requests/Admin/Servers/StoreServerRequest.php @@ -7,13 +7,13 @@ use Convoy\Models\Address; use Convoy\Rules\Password; use Illuminate\Validation\Validator; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; use Convoy\Rules\EnglishKeyboardCharacters; /** * @property mixed $type */ -class StoreServerRequest extends FormRequest +class StoreServerRequest extends BaseApiRequest { /** * Get the validation rules that apply to the request. diff --git a/app/Http/Requests/Admin/Users/UpdateUserRequest.php b/app/Http/Requests/Admin/Users/UpdateUserRequest.php index b956e54afee..e7ccc90c9fa 100644 --- a/app/Http/Requests/Admin/Users/UpdateUserRequest.php +++ b/app/Http/Requests/Admin/Users/UpdateUserRequest.php @@ -3,10 +3,10 @@ namespace Convoy\Http\Requests\Admin\Users; use Convoy\Models\User; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; use Illuminate\Validation\Rules\Password; -class UpdateUserRequest extends FormRequest +class UpdateUserRequest extends BaseApiRequest { /** * Determine if the user is authorized to make this request. diff --git a/app/Http/Requests/BaseApiRequest.php b/app/Http/Requests/BaseApiRequest.php new file mode 100644 index 00000000000..e775ca335d3 --- /dev/null +++ b/app/Http/Requests/BaseApiRequest.php @@ -0,0 +1,109 @@ +user()->root_admin; + } + + /** + * Validate that the resource exists and can be accessed prior to booting + * the validator and attempting to use the data. + * + * @throws AuthorizationException + */ + protected function prepareForValidation(): void + { + if (!$this->passesAuthorization()) { + $this->failedAuthorization(); + } + + $this->hasValidated = true; + } + + /* + * Determine if the request passes the authorization check as well + * as the exists check. + * + * @return bool + * + * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException + */ + protected function passesAuthorization(): bool + { + // If we have already validated we do not need to call this function + // again. This is needed to work around Laravel's normal auth validation + // that occurs after validating the request params since we are doing auth + // validation in the prepareForValidation() function. + if ($this->hasValidated) { + return true; + } + + if (!parent::passesAuthorization()) { + return false; + } + + // Only let the user know that a resource does not exist if they are + // authenticated to access the endpoint. This avoids exposing that + // an item exists (or does not exist) to the user until they can prove + // that they have permission to know about it. + if ($this->attributes->get('is_missing_model', false)) { + throw new NotFoundHttpException(trans('exceptions.api.resource_not_found')); + } + + return true; + } + + public function requiredToOptional(array $rules): array + { + foreach ($rules as &$rule) { + if (is_string($rule)) { + $rule = str_replace('required', 'sometimes', $rule); + } + + if (is_array($rule)) { + $rule = $this->requiredToOptional($rule); + } + } + + return $rules; + } + + /** + * Returns the named route parameter and asserts that it is a real model that + * exists in the database. + * + * @template T of Model + * + * @param class-string $expect + * @return T + * + * @noinspection PhpDocSignatureInspection + */ + public function parameter(string $key, string $expect) + { + $value = $this->route()->parameter($key); + + Assert::isInstanceOf($value, $expect); + Assert::isInstanceOf($value, Model::class); + Assert::true($value->exists); + + /* @var T $value */ + return $value; + } +} diff --git a/app/Http/Requests/Client/Servers/Backups/DeleteBackupRequest.php b/app/Http/Requests/Client/Servers/Backups/DeleteBackupRequest.php new file mode 100644 index 00000000000..91c640d1292 --- /dev/null +++ b/app/Http/Requests/Client/Servers/Backups/DeleteBackupRequest.php @@ -0,0 +1,18 @@ +parameter('server', Server::class); + $backup = $this->parameter('backup', Backup::class); + + return $this->user()->can('delete', [$backup, $server]); + } +} diff --git a/app/Http/Requests/Client/Servers/Backups/RestoreBackupRequest.php b/app/Http/Requests/Client/Servers/Backups/RestoreBackupRequest.php new file mode 100644 index 00000000000..3a0681044fe --- /dev/null +++ b/app/Http/Requests/Client/Servers/Backups/RestoreBackupRequest.php @@ -0,0 +1,18 @@ +parameter('server', Server::class); + $backup = $this->parameter('backup', Backup::class); + + return $this->user()->can('restore', [$backup, $server]); + } +} diff --git a/app/Http/Requests/Client/Servers/Backups/StoreBackupRequest.php b/app/Http/Requests/Client/Servers/Backups/StoreBackupRequest.php index c81d0c59441..8a1696ff676 100644 --- a/app/Http/Requests/Client/Servers/Backups/StoreBackupRequest.php +++ b/app/Http/Requests/Client/Servers/Backups/StoreBackupRequest.php @@ -2,27 +2,20 @@ namespace Convoy\Http\Requests\Client\Servers\Backups; +use Convoy\Http\Requests\BaseApiRequest; use Convoy\Models\Backup; use Convoy\Enums\Server\BackupMode; use Illuminate\Validation\Rules\Enum; use Illuminate\Foundation\Http\FormRequest; use Convoy\Enums\Server\BackupCompressionType; -class StoreBackupRequest extends FormRequest +class StoreBackupRequest extends BaseApiRequest { - /** - * Determine if the user is authorized to make this request. - */ public function authorize(): bool { - return true; + return $this->user()->can('create', $this->parameter('server', Backup::class)); } - /** - * Get the validation rules that apply to the request. - * - * @return array - */ public function rules(): array { $rules = Backup::getRules(); diff --git a/app/Http/Requests/Client/Servers/CreateConsoleSessionRequest.php b/app/Http/Requests/Client/Servers/CreateConsoleSessionRequest.php index 1a6dbd9b4c2..8b9f4fbb299 100644 --- a/app/Http/Requests/Client/Servers/CreateConsoleSessionRequest.php +++ b/app/Http/Requests/Client/Servers/CreateConsoleSessionRequest.php @@ -4,14 +4,16 @@ use Convoy\Models\Server; use Convoy\Enums\Server\ConsoleType; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; use Illuminate\Validation\Rules\Enum; -class CreateConsoleSessionRequest extends FormRequest +class CreateConsoleSessionRequest extends BaseApiRequest { - /** - * @return array - */ + public function authorize(): bool + { + return $this->user()->can('createConsoleSession', $this->parameter('server', Server::class)); + } + public function rules(): array { $server = $this->parameter('server', Server::class); diff --git a/app/Http/Requests/Client/Servers/SendPowerCommandRequest.php b/app/Http/Requests/Client/Servers/SendPowerCommandRequest.php index 08cafdd75bd..6c35636cb5a 100644 --- a/app/Http/Requests/Client/Servers/SendPowerCommandRequest.php +++ b/app/Http/Requests/Client/Servers/SendPowerCommandRequest.php @@ -3,24 +3,18 @@ namespace Convoy\Http\Requests\Client\Servers; use Convoy\Enums\Server\PowerAction; +use Convoy\Http\Requests\BaseApiRequest; +use Convoy\Models\Server; use Illuminate\Validation\Rules\Enum; use Illuminate\Foundation\Http\FormRequest; -class SendPowerCommandRequest extends FormRequest +class SendPowerCommandRequest extends BaseApiRequest { - /** - * Determine if the user is authorized to make this request. - */ public function authorize(): bool { - return true; + return $this->user()->can('sendPowerCommand', $this->parameter('server', Server::class)); } - /** - * Get the validation rules that apply to the request. - * - * @return array - */ public function rules(): array { return [ diff --git a/app/Http/Requests/Client/Servers/Settings/MountMediaRequest.php b/app/Http/Requests/Client/Servers/Settings/MountMediaRequest.php index 2b70617a9cd..50b77cb7e52 100644 --- a/app/Http/Requests/Client/Servers/Settings/MountMediaRequest.php +++ b/app/Http/Requests/Client/Servers/Settings/MountMediaRequest.php @@ -3,9 +3,9 @@ namespace Convoy\Http\Requests\Client\Servers\Settings; use Convoy\Models\ISO; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; -class MountMediaRequest extends FormRequest +class MountMediaRequest extends BaseApiRequest { public function authorize(): bool { diff --git a/app/Http/Requests/Client/Servers/Settings/ReinstallServerRequest.php b/app/Http/Requests/Client/Servers/Settings/ReinstallServerRequest.php index 5b163c53bbe..43680951d5b 100644 --- a/app/Http/Requests/Client/Servers/Settings/ReinstallServerRequest.php +++ b/app/Http/Requests/Client/Servers/Settings/ReinstallServerRequest.php @@ -5,10 +5,10 @@ use Convoy\Models\Server; use Convoy\Rules\Password; use Convoy\Models\Template; -use Convoy\Http\Requests\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; use Convoy\Rules\EnglishKeyboardCharacters; -class ReinstallServerRequest extends FormRequest +class ReinstallServerRequest extends BaseApiRequest { /** * Determine if the user is authorized to make this request. diff --git a/app/Http/Requests/Client/Servers/Settings/RenameServerRequest.php b/app/Http/Requests/Client/Servers/Settings/RenameServerRequest.php index c8aa8ec0010..101065e7eda 100644 --- a/app/Http/Requests/Client/Servers/Settings/RenameServerRequest.php +++ b/app/Http/Requests/Client/Servers/Settings/RenameServerRequest.php @@ -2,25 +2,18 @@ namespace Convoy\Http\Requests\Client\Servers\Settings; +use Convoy\Http\Requests\BaseApiRequest; use Convoy\Models\Server; use Convoy\Rules\Hostname; use Illuminate\Foundation\Http\FormRequest; -class RenameServerRequest extends FormRequest +class RenameServerRequest extends BaseApiRequest { - /** - * Determine if the user is authorized to make this request. - */ public function authorize(): bool { - return true; + return $this->user()->can('rename', $this->parameter('server', Server::class)); } - /** - * Get the validation rules that apply to the request. - * - * @return array - */ public function rules(): array { return [ diff --git a/app/Http/Requests/Client/Servers/Settings/UpdateSecurityRequest.php b/app/Http/Requests/Client/Servers/Settings/UpdateAuthSettingsRequest.php similarity index 86% rename from app/Http/Requests/Client/Servers/Settings/UpdateSecurityRequest.php rename to app/Http/Requests/Client/Servers/Settings/UpdateAuthSettingsRequest.php index f0ec26c4cb9..2d2693e2622 100644 --- a/app/Http/Requests/Client/Servers/Settings/UpdateSecurityRequest.php +++ b/app/Http/Requests/Client/Servers/Settings/UpdateAuthSettingsRequest.php @@ -2,8 +2,11 @@ namespace Convoy\Http\Requests\Client\Servers\Settings; +use Convoy\Http\Requests\BaseApiRequest; use Exception; use Convoy\Rules\Password; +use Faker\Provider\Base; +use Grpc\Server; use Illuminate\Validation\Validator; use Illuminate\Validation\Rules\Enum; use phpseclib3\Crypt\PublicKeyLoader; @@ -11,19 +14,13 @@ use Convoy\Rules\EnglishKeyboardCharacters; use Illuminate\Foundation\Http\FormRequest; -class UpdateSecurityRequest extends FormRequest +class UpdateAuthSettingsRequest extends BaseApiRequest { - /** - * Determine if the user is authorized to make this request. - */ public function authorize(): bool { - return true; + return $this->user()->can('updateAuthSettings', $this->parameter('server', Server::class)); } - /** - * Get the validation rules that apply to the request. - */ public function rules(): array { return [ diff --git a/app/Http/Requests/Client/Servers/Settings/UpdateBiosTypeRequest.php b/app/Http/Requests/Client/Servers/Settings/UpdateBiosTypeRequest.php index d1c78838c2a..01331e15532 100644 --- a/app/Http/Requests/Client/Servers/Settings/UpdateBiosTypeRequest.php +++ b/app/Http/Requests/Client/Servers/Settings/UpdateBiosTypeRequest.php @@ -3,17 +3,16 @@ namespace Convoy\Http\Requests\Client\Servers\Settings; use Convoy\Enums\Server\BiosType; +use Convoy\Http\Requests\BaseApiRequest; +use Convoy\Models\Server; use Illuminate\Validation\Rules\Enum; use Illuminate\Foundation\Http\FormRequest; -class UpdateBiosTypeRequest extends FormRequest +class UpdateBiosTypeRequest extends BaseApiRequest { - /** - * Determine if the user is authorized to make this request. - */ public function authorize(): bool { - return true; + return $this->user()->can('updateBiosType', $this->parameter('server', Server::class)); } /** diff --git a/app/Http/Requests/Client/Servers/Settings/UpdateBootOrderRequest.php b/app/Http/Requests/Client/Servers/Settings/UpdateBootOrderRequest.php index 6dd3ba39bbc..5dd773e6d5c 100644 --- a/app/Http/Requests/Client/Servers/Settings/UpdateBootOrderRequest.php +++ b/app/Http/Requests/Client/Servers/Settings/UpdateBootOrderRequest.php @@ -2,23 +2,16 @@ namespace Convoy\Http\Requests\Client\Servers\Settings; -use Illuminate\Foundation\Http\FormRequest; +use Convoy\Http\Requests\BaseApiRequest; +use Convoy\Models\Server; -class UpdateBootOrderRequest extends FormRequest +class UpdateBootOrderRequest extends BaseApiRequest { - /** - * Determine if the user is authorized to make this request. - */ public function authorize(): bool { - return true; + return $this->user()->can('updateBootOrder', $this->parameter('server', Server::class)); } - /** - * Get the validation rules that apply to the request. - * - * @return array - */ public function rules(): array { return [ diff --git a/app/Http/Requests/Client/Servers/Settings/UpdateNetworkRequest.php b/app/Http/Requests/Client/Servers/Settings/UpdateNetworkRequest.php index c8338d89905..f67891a8fbe 100644 --- a/app/Http/Requests/Client/Servers/Settings/UpdateNetworkRequest.php +++ b/app/Http/Requests/Client/Servers/Settings/UpdateNetworkRequest.php @@ -6,9 +6,11 @@ class UpdateNetworkRequest extends FormRequest { - /** - * Get the validation rules that apply to the request. - */ + public function authorize(): bool + { + return $this->user()->can('updateNetworkSettings', $this->route('server')); + } + public function rules(): array { return [ diff --git a/app/Http/Requests/FormRequest.php b/app/Http/Requests/FormRequest.php deleted file mode 100644 index 7ed5f5b4940..00000000000 --- a/app/Http/Requests/FormRequest.php +++ /dev/null @@ -1,71 +0,0 @@ -user())) { -// return false; -// } -// -// return (bool) $this->user()->root_admin; -// } - - public function requiredToOptional(array $rules): array - { - foreach ($rules as &$rule) { - if (is_string($rule)) { - $rule = str_replace('required', 'sometimes', $rule); - } - - if (is_array($rule)) { - $rule = $this->requiredToOptional($rule); - } - } - - return $rules; - } - - /** - * Returns the named route parameter and asserts that it is a real model that - * exists in the database. - * - * @template T of Model - * - * @param class-string $expect - * @return T - * - * @noinspection PhpUndefinedClassInspection - * @noinspection PhpDocSignatureInspection - */ - public function parameter(string $key, string $expect) - { - $value = $this->route()->parameter($key); - - Assert::isInstanceOf($value, $expect); - Assert::isInstanceOf($value, Model::class); - Assert::true($value->exists); - - /* @var T $value */ - return $value; - } -} diff --git a/app/Policies/BackupPolicy.php b/app/Policies/BackupPolicy.php new file mode 100644 index 00000000000..86abb5fba14 --- /dev/null +++ b/app/Policies/BackupPolicy.php @@ -0,0 +1,46 @@ +id === $server->user_id; + } + + public function update(User $user, Backup $backup, Server $server): bool + { + if ($backup->server_id !== $server->id) { + return false; + } + + return $user->id === $server->user_id; + } + + public function delete(User $user, Backup $backup, Server $server): bool + { + if ($backup->server_id !== $server->id) { + return false; + } + + return $user->id === $server->user_id; + } + + public function restore(User $user, Backup $backup, Server $server): bool + { + if ($backup->server_id !== $server->id) { + return false; + } + + return $user->id === $server->user_id; + } + +} diff --git a/app/Policies/ServerPolicy.php b/app/Policies/ServerPolicy.php new file mode 100644 index 00000000000..f9e43ef473a --- /dev/null +++ b/app/Policies/ServerPolicy.php @@ -0,0 +1,33 @@ +root_admin) { + return true; + } + + return null; + } + + public function view(User $user, Server $server): bool + { + return $user->id === $server->user_id; + } + + /** + * This is a horrendous hack to avoid Laravel's "smart" behavior that does + * not call the before() function if there isn't a function matching the + * policy permission. + */ + public function __call(string $name, mixed $arguments) + { + // do nothing + } +} diff --git a/lang/en_US/exceptions.php b/lang/en_US/exceptions.php new file mode 100644 index 00000000000..c87620d361e --- /dev/null +++ b/lang/en_US/exceptions.php @@ -0,0 +1,7 @@ + [ + 'resource_not_found' => 'The requested resource was not found on this server.', + ], +]; \ No newline at end of file