From 48be26b08229db6a7b6624e073df12d08e2cceb6 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Wed, 3 Mar 2021 11:48:27 -0500 Subject: [PATCH] Afform - use form-level permissions in APIv4 Afform::get --- .../Api4/Action/Afform/AbstractProcessor.php | 18 ++---------------- .../core/Civi/Api4/Action/Afform/Get.php | 13 +++++++++++++ ext/afform/core/Civi/Api4/Afform.php | 2 ++ .../tests/phpunit/api/v4/AfformUsageTest.php | 8 ++++---- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php b/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php index 077e73cee7..4d1799bd78 100644 --- a/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php +++ b/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php @@ -37,10 +37,9 @@ abstract class AbstractProcessor extends \Civi\Api4\Generic\AbstractAction { * @throws \API_Exception */ public function _run(Result $result) { - // This will throw an exception if the form doesn't exist - $this->_afform = (array) civicrm_api4('Afform', 'get', ['checkPermissions' => FALSE, 'where' => [['name', '=', $this->name]]], 0); + // This will throw an exception if the form doesn't exist or user lacks permission + $this->_afform = (array) civicrm_api4('Afform', 'get', ['where' => [['name', '=', $this->name]]], 0); $this->_formDataModel = new FormDataModel($this->_afform['layout']); - $this->checkPermissions(); $this->validateArgs(); $result->exchangeArray($this->processForm()); } @@ -59,19 +58,6 @@ abstract class AbstractProcessor extends \Civi\Api4\Generic\AbstractAction { } } - /** - * Assert that the current form submission is authorized. - * - * @throws \Civi\API\Exception\UnauthorizedException - */ - protected function checkPermissions() { - if ($this->getCheckPermissions()) { - if (!\CRM_Core_Permission::check("@afform:" . $this->_afform['name'])) { - throw new \Civi\API\Exception\UnauthorizedException("Authorization failed: Cannot process form " . $this->_afform['name']); - } - } - } - /** * @return array */ diff --git a/ext/afform/core/Civi/Api4/Action/Afform/Get.php b/ext/afform/core/Civi/Api4/Action/Afform/Get.php index 180bc20c6b..00d86e39f1 100644 --- a/ext/afform/core/Civi/Api4/Action/Afform/Get.php +++ b/ext/afform/core/Civi/Api4/Action/Afform/Get.php @@ -30,6 +30,10 @@ class Get extends \Civi\Api4\Generic\BasicGetAction { $values = $this->getAutoGenerated($names, $toGet, $getLayout); + if ($this->checkPermissions) { + $names = array_filter($names, [$this, 'checkPermission']); + } + foreach ($names as $name) { $info = [ 'name' => $name, @@ -63,6 +67,15 @@ class Get extends \Civi\Api4\Generic\BasicGetAction { return $values; } + /** + * Assert that a form is authorized. + * + * @return bool + */ + protected function checkPermission($name) { + return \CRM_Core_Permission::check("@afform:$name"); + } + /** * Generates afform blocks from custom field sets. * diff --git a/ext/afform/core/Civi/Api4/Afform.php b/ext/afform/core/Civi/Api4/Afform.php index 130f1110b0..0106f09b7f 100644 --- a/ext/afform/core/Civi/Api4/Afform.php +++ b/ext/afform/core/Civi/Api4/Afform.php @@ -197,6 +197,8 @@ class Afform extends Generic\AbstractEntity { return [ "meta" => ["access CiviCRM"], "default" => ["administer CiviCRM"], + // These all check form-level permissions + 'get' => [], 'prefill' => [], 'submit' => [], ]; diff --git a/ext/afform/mock/tests/phpunit/api/v4/AfformUsageTest.php b/ext/afform/mock/tests/phpunit/api/v4/AfformUsageTest.php index b79d9d532f..152e55c96b 100644 --- a/ext/afform/mock/tests/phpunit/api/v4/AfformUsageTest.php +++ b/ext/afform/mock/tests/phpunit/api/v4/AfformUsageTest.php @@ -88,8 +88,8 @@ EOHTML; ->indexBy('name'); $this->fail('Expected authorization exception from Afform.prefill'); } - catch (\Civi\API\Exception\UnauthorizedException $e) { - $this->assertRegExp(';Authorization failed: Cannot process form mock\d+;', $e->getMessage()); + catch (\API_Exception $e) { + // Should fail permission check } try { @@ -102,8 +102,8 @@ EOHTML; ->execute(); $this->fail('Expected authorization exception from Afform.submit'); } - catch (\Civi\API\Exception\UnauthorizedException $e) { - $this->assertRegExp(';Authorization failed: Cannot process form mock\d+;', $e->getMessage()); + catch (\API_Exception $e) { + // Should fail permission check } } -- 2.25.1