diff --git a/_build/test/Tests/Model/Security/AccessPermissionUiTest.php b/_build/test/Tests/Model/Security/AccessPermissionUiTest.php new file mode 100644 index 00000000000..a1c49ffcc10 --- /dev/null +++ b/_build/test/Tests/Model/Security/AccessPermissionUiTest.php @@ -0,0 +1,131 @@ +getDefaultProperties(); + + $this->assertSame('usergroup_new', $defaults['permission']); + } + + public function testUserGroupAclGridCreateUsesUsergroupNew(): void + { + $source = $this->readManagerAsset('assets/modext/widgets/security/modx.grid.user.group.base.js'); + + $this->assertStringContainsString( + "this.setUserCanCreate(['usergroup_new', 'usergroup_save']);", + $source + ); + $this->assertStringNotContainsString( + "setUserCanCreate(['usergroup_create'", + $source + ); + $this->assertStringContainsString( + 'hidden: !MODx.perm.usergroup_new || !MODx.perm.usergroup_save', + $source + ); + $this->assertStringContainsString('getCreateAclButton', $source); + $this->assertStringNotContainsString('hideCreateAclButtonWithoutPermission', $source); + } + + /** + * @dataProvider providerAclGridCreateButtons + */ + public function testAclGridsUseCreateAclButtonFactory(string $relativePath): void + { + $source = $this->readManagerAsset($relativePath); + + $this->assertStringContainsString('this.getCreateAclButton(_(', $source); + } + + public function providerAclGridCreateButtons(): array + { + $dir = 'assets/modext/widgets/security/'; + + return [ + 'context' => [$dir . 'modx.grid.user.group.context.js'], + 'category' => [$dir . 'modx.grid.user.group.category.js'], + 'namespace' => [$dir . 'modx.grid.user.group.namespace.js'], + 'source' => [$dir . 'modx.grid.user.group.source.js'], + 'resource' => [$dir . 'modx.grid.user.group.resource.js'], + ]; + } + + public function testUserGroupTreeGatesCreateAndAddUser(): void + { + $source = $this->readManagerAsset('assets/modext/widgets/security/modx.tree.user.group.js'); + + $this->assertStringContainsString( + 'hidden: !MODx.perm.usergroup_new || !MODx.perm.usergroup_save', + $source + ); + $this->assertStringContainsString( + 'MODx.perm.usergroup_user_edit && MODx.perm.usergroup_user_list', + $source + ); + $this->assertStringContainsString( + 'MODx.perm.usergroup_new && MODx.perm.usergroup_save && ui.hasClass(\'pcreate\')', + $source + ); + } + + public function testUserGroupUsersGridAddRequiresListPermission(): void + { + $source = $this->readManagerAsset('assets/modext/widgets/security/modx.panel.user.group.js'); + + $this->assertStringContainsString( + '!this.userCanEditGroupUsers || !MODx.perm.usergroup_user_list', + $source + ); + } + + public function testDeleteRoleLexiconDoesNotSayRemove(): void + { + $lexicon = file_get_contents(MODX_CORE_PATH . 'lexicon/en/permissions.inc.php'); + + $this->assertNotFalse($lexicon); + $this->assertStringContainsString( + "\$_lang['perm.delete_role_desc'] = 'To delete any Roles.';", + $lexicon + ); + $this->assertStringNotContainsString( + "\$_lang['perm.delete_role_desc'] = 'To delete or remove any Roles.';", + $lexicon + ); + } + + private function readManagerAsset(string $relativePath): string + { + $path = MODX_MANAGER_PATH . $relativePath; + $this->assertFileExists($path); + + $source = file_get_contents($path); + $this->assertNotFalse($source); + + return $source; + } +} diff --git a/core/lexicon/en/permissions.inc.php b/core/lexicon/en/permissions.inc.php index 43d2ae252d5..9b7f3cf9f0c 100644 --- a/core/lexicon/en/permissions.inc.php +++ b/core/lexicon/en/permissions.inc.php @@ -35,7 +35,7 @@ $_lang['perm.delete_eventlog_desc'] = 'To empty the Event Log.'; $_lang['perm.delete_plugin_desc'] = 'To delete or remove any Plugins.'; $_lang['perm.delete_propertyset_desc'] = 'To delete or remove any Property Sets.'; -$_lang['perm.delete_role_desc'] = 'To delete or remove any Roles.'; +$_lang['perm.delete_role_desc'] = 'To delete any Roles.'; $_lang['perm.delete_snippet_desc'] = 'To delete or remove any Snippets.'; $_lang['perm.delete_template_desc'] = 'To delete or remove any Templates.'; $_lang['perm.delete_tv_desc'] = 'To delete or remove any TVs.'; diff --git a/manager/assets/modext/widgets/security/modx.grid.user.group.base.js b/manager/assets/modext/widgets/security/modx.grid.user.group.base.js index ef78bf52cb1..57a93b387a4 100644 --- a/manager/assets/modext/widgets/security/modx.grid.user.group.base.js +++ b/manager/assets/modext/widgets/security/modx.grid.user.group.base.js @@ -59,7 +59,7 @@ MODx.grid.UserGroupBase = function UserGroupBase(config = {}) { this.setUserCanEdit(['usergroup_edit', 'usergroup_save']); this.userCanEditAcls = this.userCanEdit; - this.setUserCanCreate(['usergroup_create', 'usergroup_save']); + this.setUserCanCreate(['usergroup_new', 'usergroup_save']); this.setUserCanDelete(['usergroup_delete']); this.setShowActionsMenu(); @@ -83,6 +83,15 @@ MODx.grid.UserGroupBase = function UserGroupBase(config = {}) { }; Ext.extend(MODx.grid.UserGroupBase, MODx.grid.Grid, { windows: {}, + getCreateAclButton: function(text) { + return { + text: text, + cls: 'primary-button', + scope: this, + handler: this.createAcl, + hidden: !MODx.perm.usergroup_new || !MODx.perm.usergroup_save + }; + }, getColumns: function(columns) { this.rowExpander = new Ext.grid.RowExpander({ tpl: new Ext.XTemplate( diff --git a/manager/assets/modext/widgets/security/modx.grid.user.group.category.js b/manager/assets/modext/widgets/security/modx.grid.user.group.category.js index ca4cd705f55..a7cd3df813a 100644 --- a/manager/assets/modext/widgets/security/modx.grid.user.group.category.js +++ b/manager/assets/modext/widgets/security/modx.grid.user.group.category.js @@ -61,12 +61,7 @@ MODx.grid.UserGroupCategory = function UserGroupCategory(config = {}) { } ]), tbar: [ - { - text: _('category_add'), - cls: 'primary-button', - scope: this, - handler: this.createAcl - }, + this.getCreateAclButton(_('category_add')), '->', { xtype: 'modx-combo-category', diff --git a/manager/assets/modext/widgets/security/modx.grid.user.group.context.js b/manager/assets/modext/widgets/security/modx.grid.user.group.context.js index c46545654f1..d77db5ebff2 100644 --- a/manager/assets/modext/widgets/security/modx.grid.user.group.context.js +++ b/manager/assets/modext/widgets/security/modx.grid.user.group.context.js @@ -56,12 +56,7 @@ MODx.grid.UserGroupContext = function UserGroupContext(config = {}) { } ]), tbar: [ - { - text: _('context_add'), - cls: 'primary-button', - scope: this, - handler: this.createAcl - }, + this.getCreateAclButton(_('context_add')), '->', { xtype: 'modx-combo-context', diff --git a/manager/assets/modext/widgets/security/modx.grid.user.group.namespace.js b/manager/assets/modext/widgets/security/modx.grid.user.group.namespace.js index bbbaff157f9..e965dd416d5 100644 --- a/manager/assets/modext/widgets/security/modx.grid.user.group.namespace.js +++ b/manager/assets/modext/widgets/security/modx.grid.user.group.namespace.js @@ -55,12 +55,7 @@ MODx.grid.UserGroupNamespace = function UserGroupNamespace(config = {}) { } ]), tbar: [ - { - text: _('namespace_add'), - cls: 'primary-button', - scope: this, - handler: this.createAcl - }, + this.getCreateAclButton(_('namespace_add')), '->', { xtype: 'modx-combo-namespace', diff --git a/manager/assets/modext/widgets/security/modx.grid.user.group.resource.js b/manager/assets/modext/widgets/security/modx.grid.user.group.resource.js index 46b94345fbe..5850b4dd26a 100644 --- a/manager/assets/modext/widgets/security/modx.grid.user.group.resource.js +++ b/manager/assets/modext/widgets/security/modx.grid.user.group.resource.js @@ -63,12 +63,7 @@ MODx.grid.UserGroupResourceGroup = function UserGroupResourceGroup(config = {}) } ]), tbar: [ - { - text: _('resource_group_add'), - cls: 'primary-button', - scope: this, - handler: this.createAcl - }, + this.getCreateAclButton(_('resource_group_add')), '->', { xtype: 'modx-combo-resourcegroup', diff --git a/manager/assets/modext/widgets/security/modx.grid.user.group.source.js b/manager/assets/modext/widgets/security/modx.grid.user.group.source.js index d0a6565c828..84583a8dc8c 100644 --- a/manager/assets/modext/widgets/security/modx.grid.user.group.source.js +++ b/manager/assets/modext/widgets/security/modx.grid.user.group.source.js @@ -57,12 +57,7 @@ MODx.grid.UserGroupSource = function UserGroupSource(config = {}) { } ]), tbar: [ - { - text: _('source_add'), - cls: 'primary-button', - scope: this, - handler: this.createAcl - }, + this.getCreateAclButton(_('source_add')), '->', { xtype: 'modx-combo-source', diff --git a/manager/assets/modext/widgets/security/modx.panel.user.group.js b/manager/assets/modext/widgets/security/modx.panel.user.group.js index da842026514..d4d348f1be4 100644 --- a/manager/assets/modext/widgets/security/modx.panel.user.group.js +++ b/manager/assets/modext/widgets/security/modx.panel.user.group.js @@ -441,7 +441,7 @@ MODx.grid.UserGroupUsers = function(config = {}) { if (!this.userCanEditGroups || grid.ownerCt.id !== 'modx-tree-panel-usergroup') { buttonsToHide.push('modx-btn-user-group-edit'); } - if (!this.userCanEditGroupUsers) { + if (!this.userCanEditGroupUsers || !MODx.perm.usergroup_user_list) { buttonsToHide.push('modx-btn-user-group-add-user'); } if (buttonsToHide.length > 0) { diff --git a/manager/assets/modext/widgets/security/modx.tree.user.group.js b/manager/assets/modext/widgets/security/modx.tree.user.group.js index b73b7d95881..30c1d9ad997 100644 --- a/manager/assets/modext/widgets/security/modx.tree.user.group.js +++ b/manager/assets/modext/widgets/security/modx.tree.user.group.js @@ -26,6 +26,7 @@ MODx.tree.UserGroup = function(config) { text: _('user_group_new') ,cls: 'primary-button' ,scope: this + ,hidden: !MODx.perm.usergroup_new || !MODx.perm.usergroup_save ,handler: this.createUserGroup.createDelegate(this,[true],true) }] }); @@ -107,14 +108,14 @@ Ext.extend(MODx.tree.UserGroup,MODx.tree.Tree,{ switch (n.attributes.type) { case 'usergroup': - if (MODx.perm.usergroup_user_edit && ui.hasClass('padduser')) { + if (MODx.perm.usergroup_user_edit && MODx.perm.usergroup_user_list && ui.hasClass('padduser')) { m.push({ text: _('user_group_user_add') ,handler: this.addUser }); m.push('-'); } - if (MODx.perm.usergroup_new && ui.hasClass('pcreate')) { + if (MODx.perm.usergroup_new && MODx.perm.usergroup_save && ui.hasClass('pcreate')) { m.push({ text: _('user_group_create') ,handler: this.createUserGroup