Skip to content

Commit

Permalink
pkp#5504 Add 'permit settings' flag on user groups
Browse files Browse the repository at this point in the history
  • Loading branch information
asmecher committed Sep 12, 2024
1 parent ed99d62 commit d604d36
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 40 deletions.
1 change: 1 addition & 0 deletions classes/install/PKPInstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions classes/migration/install/RolesAndUserGroupsMigration.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
47 changes: 47 additions & 0 deletions classes/migration/upgrade/v3_5_0/I5504_UserGroupsSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

/**
* @file classes/migration/upgrade/v3_5_0/I5504_UserGroupsSettings.php
*
* Copyright (c) 2024 Simon Fraser University
* Copyright (c) 2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class I5504_UserGroupsSettings
*
* @brief Add permit_settings column to the user_groups table.
*/

namespace PKP\migration\upgrade\v3_5_0;

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use PKP\migration\Migration;

class I5504_UserGroupsSettings extends Migration
{
/**
* Run the migration.
*/
public function up(): void
{
Schema::table('user_groups', function (Blueprint $table) {
$table->smallInteger('permit_settings')->default(0);
});
DB::table('user_groups')->where('role_id', 1)->update(['permit_settings' => 1]); // role_id = 1 is ROLE_ID_SITE_ADMIN
DB::table('user_groups')->where('role_id', 16)->update(['permit_settings' => 1]); // role_id = 16 is ROLE_ID_MANAGER
}

/**
* Reverse the downgrades
*/
public function down(): void
{
Schema::table('user_groups', function (Blueprint $table) {
if (Schema::hasColumn($table->getTable(), 'permit_settings')) {
$table->dropColumn('permit_settings');
};
});
}
}
1 change: 1 addition & 0 deletions classes/security/authorization/UserRolesRequiredPolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
62 changes: 33 additions & 29 deletions classes/template/PKPTemplateManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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))) {
Expand Down
2 changes: 1 addition & 1 deletion classes/userGroup/DAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -57,6 +56,7 @@ class DAO extends EntityDAO
'showTitle' => 'show_title',
'permitSelfRegistration' => 'permit_self_registration',
'permitMetadataEdit' => 'permit_metadata_edit',
'permitSettings' => 'permit_settings',
'masthead' => 'masthead',
];

Expand Down
4 changes: 3 additions & 1 deletion classes/userGroup/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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'));
Expand All @@ -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);
Expand Down
20 changes: 18 additions & 2 deletions classes/userGroup/UserGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

namespace PKP\userGroup;

use PKP\core\PKPApplication;

class UserGroup extends \PKP\core\DataObject
{
/**
Expand Down Expand Up @@ -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
*/
Expand Down
22 changes: 15 additions & 7 deletions controllers/grid/settings/roles/form/UserGroupForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
];
Expand All @@ -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']);
}

/**
Expand All @@ -157,6 +158,7 @@ public function fetch($request, $template = null, $display = false)
$disableRoleSelect = ($this->getUserGroupId() > 0) ? true : false;
$templateMgr->assign('disableRoleSelect', $disableRoleSelect);
$templateMgr->assign('selfRegistrationRoleIds', $this->getPermitSelfRegistrationRoles());
$templateMgr->assign('permitSettingsRoleIds', $this->getPermitSettingsRoles());
$templateMgr->assign('recommendOnlyRoleIds', $this->getRecommendOnlyRoles());
$templateMgr->assign('notChangeMetadataEditPermissionRoles', Repo::userGroup()::NOT_CHANGE_METADATA_EDIT_PERMISSION_ROLES);

Expand All @@ -165,20 +167,24 @@ public function fetch($request, $template = null, $display = false)

/**
* Get a list of roles optionally permitting user self-registration.
*
* @return array
*/
public function getPermitSelfRegistrationRoles()
public function getPermitSelfRegistrationRoles(): array
{
return [Role::ROLE_ID_REVIEWER, Role::ROLE_ID_AUTHOR, Role::ROLE_ID_READER];
}

/**
* Get a list of roles optionally permitting settings access.
*/
public function getPermitSettingsRoles(): array
{
return [Role::ROLE_ID_MANAGER];
}

/**
* Get a list of roles optionally permitting recommendOnly option.
*
* @return array
*/
public function getRecommendOnlyRoles()
public function getRecommendOnlyRoles(): array
{
return [Role::ROLE_ID_MANAGER, Role::ROLE_ID_SUB_EDITOR];
}
Expand Down Expand Up @@ -210,6 +216,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);
}
Expand All @@ -224,6 +231,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 {
Expand Down
50 changes: 50 additions & 0 deletions js/controllers/grid/settings/roles/form/UserGroupFormHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@
this.recommendOnlyRoleIds_ = options.recommendOnlyRoleIds;
}

// Set the role IDs for which the permitSettings checkbox
// is relevant.
if (options.permitSettingsRoleIds) {
this.permitSettingsRoleIds_ = options.permitSettingsRoleIds;
}

// Set the roles that are not able to change
// submission metadata edit perissions
if (options.notChangeMetadataEditPermissionRoles) {
Expand All @@ -72,6 +78,11 @@
this.updatePermitMetadataEdit(
/** @type {string} */ ($roleId.val()), false);

// Initialize the "permit settings" checkbox disabled
// state based on the form's current selection
this.updatePermitSettings(
/** @type {string} */ ($roleId.val()), false);

// ...also initialize the stage options, disabling the ones
// that are forbidden for the current role.
this.updateStageOptions(
Expand Down Expand Up @@ -102,6 +113,15 @@
UserGroupFormHandler.prototype.selfRegistrationRoleIds_ = null;


/**
* The list of role IDs for which settings can be permitted/restricted
* @private
* @type {Object?}
*/
$.pkp.controllers.grid.settings.roles.form.
UserGroupFormHandler.prototype.permitSettingsRoleIds_ = null;


/**
* A list of role forbidden stages.
* @private
Expand Down Expand Up @@ -143,6 +163,7 @@

this.updatePermitSelfRegistration((dropDownValue));
this.updatePermitMetadataEdit(/** @type {string} */ (dropDownValue), true);
this.updatePermitSettings(/** @type {string} */ (dropDownValue), true);

// Also update the stages options.
this.updateStageOptions(/** @type {string} */ (dropDownValue));
Expand Down Expand Up @@ -182,6 +203,35 @@
};


/**
* Update the enabled/disabled state of the permitSettings
* checkbox.
* @param {number|string} roleId The role ID to select.
*/
$.pkp.controllers.grid.settings.roles.form.UserGroupFormHandler.prototype.
updatePermitSettings = function(roleId) {

// JQuerify the element
var $checkbox = $('[id^="permitSettings"]'),
$form = this.getHtmlElement(),
i,
found = false;

for (i = 0; i < this.selfRegistrationRoleIds_.length; i++) {
if (this.permitSettingsRoleIds_[i] == roleId) {
found = true;
}
}

if (found) {
$checkbox.removeAttr('disabled');
} else {
$checkbox.attr('disabled', 'disabled');
$checkbox.removeAttr('checked');
}
};


/**
* Update the enabled/disabled state of the PermitMetadataEdit
* checkbox.
Expand Down
3 changes: 3 additions & 0 deletions locale/en/manager.po
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
Expand Down
3 changes: 3 additions & 0 deletions schemas/userGroup.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
"permitMetadataEdit": {
"type": "boolean"
},
"permitSettings": {
"type": "boolean"
},
"recommendOnly": {
"type": "boolean"
},
Expand Down
Loading

0 comments on commit d604d36

Please sign in to comment.