From 05ebeb873035bb90e9016084e50fbed4d009995c Mon Sep 17 00:00:00 2001 From: Alec Smecher Date: Mon, 9 Sep 2024 15:01:38 -0700 Subject: [PATCH] pkp/pkp-lib#5504 Add 'permit settings' flag on user groups --- classes/install/PKPInstall.php | 1 + .../install/RolesAndUserGroupsMigration.php | 1 + .../authorization/UserRolesRequiredPolicy.php | 1 + classes/template/PKPTemplateManager.php | 62 ++++++++++--------- classes/userGroup/DAO.php | 2 +- classes/userGroup/Repository.php | 4 +- classes/userGroup/UserGroup.php | 20 +++++- .../settings/roles/form/UserGroupForm.php | 5 +- locale/en/manager.po | 3 + schemas/userGroup.json | 3 + .../settings/roles/form/userGroupForm.tpl | 1 + 11 files changed, 69 insertions(+), 34 deletions(-) diff --git a/classes/install/PKPInstall.php b/classes/install/PKPInstall.php index eb39b49e6c0..76a9c0dc2d3 100644 --- a/classes/install/PKPInstall.php +++ b/classes/install/PKPInstall.php @@ -235,6 +235,7 @@ public function createData() $adminUserGroup = Repo::userGroup()->newDataObject(); $adminUserGroup->setRoleId(Role::ROLE_ID_SITE_ADMIN); $adminUserGroup->setContextId(\PKP\core\PKPApplication::SITE_CONTEXT_ID); + $adminUserGroup->setPermitSettings(true); $adminUserGroup->setDefault(true); foreach ($this->installedLocales as $locale) { $name = __('default.groups.name.siteAdmin', [], $locale); diff --git a/classes/migration/install/RolesAndUserGroupsMigration.php b/classes/migration/install/RolesAndUserGroupsMigration.php index d8c98f8e4d3..95395ffc02a 100644 --- a/classes/migration/install/RolesAndUserGroupsMigration.php +++ b/classes/migration/install/RolesAndUserGroupsMigration.php @@ -36,6 +36,7 @@ public function up(): void $table->smallInteger('show_title')->default(1); $table->smallInteger('permit_self_registration')->default(0); $table->smallInteger('permit_metadata_edit')->default(0); + $table->smallInteger('permit_settings')->default(0); $table->smallInteger('masthead')->default(0); $table->index(['user_group_id'], 'user_groups_user_group_id'); $table->index(['role_id'], 'user_groups_role_id'); diff --git a/classes/security/authorization/UserRolesRequiredPolicy.php b/classes/security/authorization/UserRolesRequiredPolicy.php index 61cba807689..8f5acf5e032 100644 --- a/classes/security/authorization/UserRolesRequiredPolicy.php +++ b/classes/security/authorization/UserRolesRequiredPolicy.php @@ -60,6 +60,7 @@ public function effect() $roleIds = array_map(fn ($userGroup) => $userGroup->getRoleId(), $userGroups); $this->addAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES, $roleIds); + $this->addAuthorizedContextObject(Application::ASSOC_TYPE_USER_GROUP, $userGroups); return AuthorizationPolicy::AUTHORIZATION_PERMIT; } diff --git a/classes/template/PKPTemplateManager.php b/classes/template/PKPTemplateManager.php index e6ae0c3f01e..b5eac3350f1 100644 --- a/classes/template/PKPTemplateManager.php +++ b/classes/template/PKPTemplateManager.php @@ -1046,36 +1046,40 @@ public function setupBackendPage() 'isCurrent' => $request->getRequestedPage() === 'management' && in_array('institutions', (array) $request->getRequestedArgs()), ]; } - $menu['settings'] = [ - 'name' => __('navigation.settings'), - 'submenu' => [ - 'context' => [ - 'name' => __('context.context'), - 'url' => $router->url($request, null, 'management', 'settings', ['context']), - 'isCurrent' => $router->getRequestedPage($request) === 'management' && in_array('context', (array) $router->getRequestedArgs($request)), - ], - 'website' => [ - 'name' => __('manager.website'), - 'url' => $router->url($request, null, 'management', 'settings', ['website']), - 'isCurrent' => $router->getRequestedPage($request) === 'management' && in_array('website', (array) $router->getRequestedArgs($request)), - ], - 'workflow' => [ - 'name' => __('manager.workflow'), - 'url' => $router->url($request, null, 'management', 'settings', ['workflow']), - 'isCurrent' => $router->getRequestedPage($request) === 'management' && in_array('workflow', (array) $router->getRequestedArgs($request)), - ], - 'distribution' => [ - 'name' => __('manager.distribution'), - 'url' => $router->url($request, null, 'management', 'settings', ['distribution']), - 'isCurrent' => $router->getRequestedPage($request) === 'management' && in_array('distribution', (array) $router->getRequestedArgs($request)), - ], - 'access' => [ - 'name' => __('navigation.access'), - 'url' => $router->url($request, null, 'management', 'settings', ['access']), - 'isCurrent' => $router->getRequestedPage($request) === 'management' && in_array('access', (array) $router->getRequestedArgs($request)), + $userGroups = (array) $router->getHandler()->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_GROUP); + $hasSettingsAccess = array_reduce($userGroups, fn ($carry, $userGroup) => $carry || $userGroup->getPermitSettings(), false); + if ($hasSettingsAccess) { + $menu['settings'] = [ + 'name' => __('navigation.settings'), + 'submenu' => [ + 'context' => [ + 'name' => __('context.context'), + 'url' => $router->url($request, null, 'management', 'settings', ['context']), + 'isCurrent' => $router->getRequestedPage($request) === 'management' && in_array('context', (array) $router->getRequestedArgs($request)), + ], + 'website' => [ + 'name' => __('manager.website'), + 'url' => $router->url($request, null, 'management', 'settings', ['website']), + 'isCurrent' => $router->getRequestedPage($request) === 'management' && in_array('website', (array) $router->getRequestedArgs($request)), + ], + 'workflow' => [ + 'name' => __('manager.workflow'), + 'url' => $router->url($request, null, 'management', 'settings', ['workflow']), + 'isCurrent' => $router->getRequestedPage($request) === 'management' && in_array('workflow', (array) $router->getRequestedArgs($request)), + ], + 'distribution' => [ + 'name' => __('manager.distribution'), + 'url' => $router->url($request, null, 'management', 'settings', ['distribution']), + 'isCurrent' => $router->getRequestedPage($request) === 'management' && in_array('distribution', (array) $router->getRequestedArgs($request)), + ], + 'access' => [ + 'name' => __('navigation.access'), + 'url' => $router->url($request, null, 'management', 'settings', ['access']), + 'isCurrent' => $router->getRequestedPage($request) === 'management' && in_array('access', (array) $router->getRequestedArgs($request)), + ] ] - ] - ]; + ]; + } } if (count(array_intersect([Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR], $userRoles))) { diff --git a/classes/userGroup/DAO.php b/classes/userGroup/DAO.php index dcf670c6efd..639f2a6c7c6 100644 --- a/classes/userGroup/DAO.php +++ b/classes/userGroup/DAO.php @@ -23,7 +23,6 @@ use Illuminate\Support\LazyCollection; use PKP\core\Core; use PKP\core\EntityDAO; -use PKP\core\PKPApplication; use PKP\core\traits\EntityWithParent; use PKP\services\PKPSchemaService; @@ -57,6 +56,7 @@ class DAO extends EntityDAO 'showTitle' => 'show_title', 'permitSelfRegistration' => 'permit_self_registration', 'permitMetadataEdit' => 'permit_metadata_edit', + 'permitSettings' => 'permit_settings', 'masthead' => 'masthead', ]; diff --git a/classes/userGroup/Repository.php b/classes/userGroup/Repository.php index dcaf172669d..e3c9658b6a6 100644 --- a/classes/userGroup/Repository.php +++ b/classes/userGroup/Repository.php @@ -500,7 +500,6 @@ public function getFirstSubmitAsAuthorUserGroup(int $contextId): ?UserGroup /** * Load the XML file and move the settings to the DB * - * @param int $contextId * @param string $filename * * @return bool true === success @@ -524,11 +523,13 @@ public function installSettings(?int $contextId, $filename) $abbrevKey = $setting->getAttribute('abbrev'); $permitSelfRegistration = $setting->getAttribute('permitSelfRegistration'); $permitMetadataEdit = $setting->getAttribute('permitMetadataEdit'); + $permitSettings = $setting->getAttribute('permitSettings'); $masthead = $setting->getAttribute('masthead'); // If has manager role then permitMetadataEdit can't be overridden if (in_array($roleId, [Role::ROLE_ID_MANAGER])) { $permitMetadataEdit = $setting->getAttribute('permitMetadataEdit'); + $permitSettings = $setting->getAttribute('permitSettings'); } $defaultStages = explode(',', (string) $setting->getAttribute('stages')); @@ -539,6 +540,7 @@ public function installSettings(?int $contextId, $filename) $userGroup->setContextId($contextId); $userGroup->setPermitSelfRegistration($permitSelfRegistration ?? false); $userGroup->setPermitMetadataEdit($permitMetadataEdit ?? false); + $userGroup->setPermitSettings($permitSettings ?? false); $userGroup->setDefault(true); $userGroup->setShowTitle(true); $userGroup->setMasthead($masthead ?? false); diff --git a/classes/userGroup/UserGroup.php b/classes/userGroup/UserGroup.php index 404180d2c98..53b0f9555ed 100644 --- a/classes/userGroup/UserGroup.php +++ b/classes/userGroup/UserGroup.php @@ -16,8 +16,6 @@ namespace PKP\userGroup; -use PKP\core\PKPApplication; - class UserGroup extends \PKP\core\DataObject { /** @@ -243,6 +241,24 @@ public function setPermitMetadataEdit(bool $permitMetadataEdit) $this->setData('permitMetadataEdit', $permitMetadataEdit); } + /** + * Getter for permitSettings attribute. + * + * @return bool + */ + public function getPermitSettings() + { + return $this->getData('permitSettings'); + } + + /** + * Setter for permitSettings attribute. + */ + public function setPermitSettings(bool $permitSettings) + { + $this->setData('permitSettings', $permitSettings); + } + /** * Get the masthead flag */ diff --git a/controllers/grid/settings/roles/form/UserGroupForm.php b/controllers/grid/settings/roles/form/UserGroupForm.php index 3a9333ee0a8..556ba4c49c3 100644 --- a/controllers/grid/settings/roles/form/UserGroupForm.php +++ b/controllers/grid/settings/roles/form/UserGroupForm.php @@ -122,6 +122,7 @@ public function initData() 'showTitle' => $userGroup->getShowTitle(), 'permitSelfRegistration' => $userGroup->getPermitSelfRegistration(), 'permitMetadataEdit' => $userGroup->getPermitMetadataEdit(), + 'permitSettings' => $userGroup->getPermitSettings(), 'recommendOnly' => $userGroup->getRecommendOnly(), 'masthead' => $userGroup->getMasthead(), ]; @@ -137,7 +138,7 @@ public function initData() */ public function readInputData() { - $this->readUserVars(['roleId', 'name', 'abbrev', 'assignedStages', 'showTitle', 'permitSelfRegistration', 'recommendOnly', 'permitMetadataEdit', 'masthead']); + $this->readUserVars(['roleId', 'name', 'abbrev', 'assignedStages', 'showTitle', 'permitSelfRegistration', 'recommendOnly', 'permitMetadataEdit', 'permitSettings', 'masthead']); } /** @@ -210,6 +211,7 @@ public function execute(...$functionParams) $userGroup->setShowTitle(is_null($this->getData('showTitle')) ? false : $this->getData('showTitle')); $userGroup->setPermitSelfRegistration($this->getData('permitSelfRegistration') && in_array($userGroup->getRoleId(), $this->getPermitSelfRegistrationRoles())); $userGroup->setPermitMetadataEdit($this->getData('permitMetadataEdit') && !in_array($this->getData('roleId'), Repo::userGroup()::NOT_CHANGE_METADATA_EDIT_PERMISSION_ROLES)); + $userGroup->setPermitSettings($this->getData('permitSettings') && $userGroup->getRoleId() == Role::ROLE_ID_MANAGER); if (in_array($this->getData('roleId'), Repo::userGroup()::NOT_CHANGE_METADATA_EDIT_PERMISSION_ROLES)) { $userGroup->setPermitMetadataEdit(true); } @@ -224,6 +226,7 @@ public function execute(...$functionParams) $userGroup->setShowTitle(is_null($this->getData('showTitle')) ? false : $this->getData('showTitle')); $userGroup->setPermitSelfRegistration($this->getData('permitSelfRegistration') && in_array($userGroup->getRoleId(), $this->getPermitSelfRegistrationRoles())); $userGroup->setPermitMetadataEdit($this->getData('permitMetadataEdit') && !in_array($userGroup->getRoleId(), Repo::userGroup()::NOT_CHANGE_METADATA_EDIT_PERMISSION_ROLES)); + $userGroup->setPermitSettings($this->getData('permitSettings') && $userGroup->getRoleId() == Role::ROLE_ID_MANAGER); if (in_array($userGroup->getRoleId(), Repo::userGroup()::NOT_CHANGE_METADATA_EDIT_PERMISSION_ROLES)) { $userGroup->setPermitMetadataEdit(true); } else { diff --git a/locale/en/manager.po b/locale/en/manager.po index 54e1e87cfb6..abc283ba766 100644 --- a/locale/en/manager.po +++ b/locale/en/manager.po @@ -1733,6 +1733,9 @@ msgstr "Show role title in contributor list" msgid "settings.roles.permitSelfRegistration" msgstr "Allow user self-registration" +msgid "settings.roles.permitSettings" +msgstr "Permit changes to Settings" + msgid "settings.roles.recommendOnly" msgstr "" "This role is only allowed to recommend a review decision and will require an " diff --git a/schemas/userGroup.json b/schemas/userGroup.json index ea266ea8553..cfb060ba0d8 100644 --- a/schemas/userGroup.json +++ b/schemas/userGroup.json @@ -31,6 +31,9 @@ "permitMetadataEdit": { "type": "boolean" }, + "permitSettings": { + "type": "boolean" + }, "recommendOnly": { "type": "boolean" }, diff --git a/templates/controllers/grid/settings/roles/form/userGroupForm.tpl b/templates/controllers/grid/settings/roles/form/userGroupForm.tpl index 0a3cc201d9d..1d1f486416f 100644 --- a/templates/controllers/grid/settings/roles/form/userGroupForm.tpl +++ b/templates/controllers/grid/settings/roles/form/userGroupForm.tpl @@ -57,6 +57,7 @@ {fbvElement type="checkbox" name="recommendOnly" id="recommendOnly" checked=$recommendOnly label="settings.roles.recommendOnly"} {fbvElement type="checkbox" name="permitMetadataEdit" id="permitMetadataEdit" checked=$permitMetadataEdit label="settings.roles.permitMetadataEdit"} {fbvElement type="checkbox" name="masthead" id="masthead" checked=$masthead label="settings.roles.masthead"} + {fbvElement type="checkbox" name="permitSettings" id="permitSettings" checked=$permitSettings label="settings.roles.permitSettings"} {/fbvFormSection} {/fbvFormArea}