From e6d561df0c2179cf4ff427d8c008dde6a38cae6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sigmar=20K=C3=BChlmann?= Date: Wed, 18 Dec 2024 11:55:01 +0100 Subject: [PATCH 1/2] checkDeleteAllowed & checkUpdateAllowed --- src/actions/DeleteAction.php | 9 +++++++++ src/actions/UpdateAction.php | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/actions/DeleteAction.php b/src/actions/DeleteAction.php index f408491..45154ff 100644 --- a/src/actions/DeleteAction.php +++ b/src/actions/DeleteAction.php @@ -37,6 +37,11 @@ class DeleteAction extends JsonApiAction */ public $scenario = Model::SCENARIO_DEFAULT; + /** + * @var callable|null a PHP callable that checks if deletion is allowed. + */ + public $checkDeleteAllowed; + /** * @var callable|Closure Callback after save model with all relations * @example @@ -80,6 +85,10 @@ public function run($id):void call_user_func($this->checkAccess, $this->id, $model); } + if ($this->checkDeleteAllowed) { + call_user_func($this->checkDeleteAllowed, $this->id, $model); + } + if ($model->delete() === false) { throw new ServerErrorHttpException('Failed to delete the object for unknown reason.'); } diff --git a/src/actions/UpdateAction.php b/src/actions/UpdateAction.php index f0517cd..5ba675b 100644 --- a/src/actions/UpdateAction.php +++ b/src/actions/UpdateAction.php @@ -66,6 +66,12 @@ class UpdateAction extends JsonApiAction * ``` */ public $scenario = Model::SCENARIO_DEFAULT; + + /** + * @var callable|null a PHP callable that checks if updating is allowed. + */ + public $checkUpdateAllowed; + /** * @var callable|Closure Callback after save model with all relations * @example @@ -74,6 +80,7 @@ class UpdateAction extends JsonApiAction * } */ public $afterSave = null; + /** * @throws \yii\base\InvalidConfigException */ @@ -113,6 +120,10 @@ public function run($id):Item call_user_func($this->checkAccess, $this->id, $model); } + if ($this->checkUpdateAllowed) { + call_user_func($this->checkUpdateAllowed, $this->id, $model); + } + $originalModel = clone $model; RelationshipManager::validateRelationships($model, $this->getResourceRelationships(), $this->allowedRelations); if (empty($this->getResourceAttributes()) && $this->hasResourceRelationships()) { From c7f54e3039f53f606809709d472834e592437d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sigmar=20K=C3=BChlmann?= Date: Wed, 18 Dec 2024 13:07:58 +0100 Subject: [PATCH 2/2] checkAccess, checkUpdateAllowed, checkDeleteAllowed - description --- src/actions/DeleteAction.php | 17 ++++++++++++++++- src/actions/JsonApiAction.php | 15 +++++++++++---- src/actions/UpdateAction.php | 16 +++++++++++++++- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/actions/DeleteAction.php b/src/actions/DeleteAction.php index 45154ff..c6ee7b0 100644 --- a/src/actions/DeleteAction.php +++ b/src/actions/DeleteAction.php @@ -38,10 +38,25 @@ class DeleteAction extends JsonApiAction public $scenario = Model::SCENARIO_DEFAULT; /** - * @var callable|null a PHP callable that checks if deletion is allowed. + * @var callable|null A PHP callable that will be called to determine + * whether the deletion of a model is allowed. If not set, no deletion + * check will be performed. The callable should have the following signature: + * + * @example + * ```php + * function ($action, $model) { + * // $model is the model instance being deleted. + * + * // If the deletion is not allowed, an error should be thrown. For example: + * if ($model->status !== 'draft') { + * throw new MethodNotAllowedHttpException('The model can only be deleted if its status is "draft".'); + * } + * } + * ``` */ public $checkDeleteAllowed; + /** * @var callable|Closure Callback after save model with all relations * @example diff --git a/src/actions/JsonApiAction.php b/src/actions/JsonApiAction.php index de6e074..75b61eb 100644 --- a/src/actions/JsonApiAction.php +++ b/src/actions/JsonApiAction.php @@ -61,13 +61,20 @@ class JsonApiAction extends Action public $findModel; /** - * @var callable a PHP callable that will be called when running an action to determine - * if the current user has the permission to execute the action. If not set, the access - * check will not be performed. The signature of the callable should be as follows, + * @var callable|null A PHP callable that will be called when running an action to determine + * whether the current user has permission to execute the action. If not set, no access + * check will be performed. The callable should have the following signature: + * + * @example * ```php * function ($action, $model = null) { * // $model is the requested model instance. - * // If null, it means no specific model (e.g. IndexAction) + * // If null, it indicates no specific model (e.g., IndexAction). + * + * // If the user does not have the required permissions, an error should be thrown. For example: + * if (!Yii::$app->user->can('admin')) { + * throw new ForbiddenHttpException(); + * } * } * ``` */ diff --git a/src/actions/UpdateAction.php b/src/actions/UpdateAction.php index 5ba675b..57afd67 100644 --- a/src/actions/UpdateAction.php +++ b/src/actions/UpdateAction.php @@ -68,7 +68,21 @@ class UpdateAction extends JsonApiAction public $scenario = Model::SCENARIO_DEFAULT; /** - * @var callable|null a PHP callable that checks if updating is allowed. + * @var callable|null A PHP callable that will be called to determine + * whether the update of a model is allowed. If not set, no update + * check will be performed. The callable should have the following signature: + * + * @example + * ```php + * function ($action, $model) { + * // $model is the model instance being updated. + * + * // If the update is not allowed, an error should be thrown. For example: + * if ($model->status === 'archived') { + * throw new MethodNotAllowedHttpException('The model cannot be updated when its status is "archived".'); + * } + * } + * ``` */ public $checkUpdateAllowed;