Skip to content

Commit

Permalink
#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 74a200e
Show file tree
Hide file tree
Showing 13 changed files with 210 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
32 changes: 25 additions & 7 deletions controllers/grid/settings/roles/form/UserGroupForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ public function initData()

if ($userGroup) {
$assignedStages = Repo::userGroup()->getAssignedStagesByUserGroupId($this->getContextId(), $userGroup->getId())->toArray();
// Get a list of all settings-accessible user groups for the current user in
// order to prevent them from locking themselves out by disabling the only one.
$mySettingsAccessUserGroupIds = Repo::userGroup()->getCollector()
->filterByContextIds([$this->getContextId()])
->filterByUserIds([Application::get()->getRequest()->getUser()->getId()])
->getMany()
->filter(fn ($userGroup) => $userGroup->getPermitSettings())
->map(fn ($userGroup) => $userGroup->getId())
->toArray();

$data = [
'userGroupId' => $userGroup->getId(),
Expand All @@ -120,8 +129,10 @@ public function initData()
'abbrev' => $userGroup->getAbbrev(null), //Localized
'assignedStages' => $assignedStages,
'showTitle' => $userGroup->getShowTitle(),
'mySettingsAccessUserGroupIds' => array_values($mySettingsAccessUserGroupIds),
'permitSelfRegistration' => $userGroup->getPermitSelfRegistration(),
'permitMetadataEdit' => $userGroup->getPermitMetadataEdit(),
'permitSettings' => $userGroup->getPermitSettings(),
'recommendOnly' => $userGroup->getRecommendOnly(),
'masthead' => $userGroup->getMasthead(),
];
Expand All @@ -137,7 +148,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 +168,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 +177,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 +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($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 +241,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
Loading

0 comments on commit 74a200e

Please sign in to comment.