diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Feature-89917-InheritPageAccess.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Feature-89917-InheritPageAccess.rst index 1c2730310897fcb9f4e41c07da8ed27e01c00683..7e3a02f525943d56f514448f3749733054399448 100644 --- a/typo3/sysext/core/Documentation/Changelog/12.0/Feature-89917-InheritPageAccess.rst +++ b/typo3/sysext/core/Documentation/Changelog/12.0/Feature-89917-InheritPageAccess.rst @@ -1,18 +1,71 @@ .. include:: ../../Includes.txt ======================================================= -Feature: #89738 - Copy page access settings from parent +Feature: #89917 - Copy page access settings from parent ======================================================= -See :issue:`89738` +See :issue:`89917` Description =========== It is now possible to copy page access permissions from the parent page, -while creating new pages. This is possible, using :typoscript:`copyFromParent` +while creating new pages. This is enabled using :typoscript:`copyFromParent` as value for one of the page TSconfig :typoscript:`TCEMAIN.permissions.*` -subkeys. +sub keys. + +There are casual scenarios where this can be useful to avoid additional backend +administrator work: + +When having a top level page, backend admins use the access module to set a page +group owner and add TSconfig on this page to specify access details. A typical +TSconfig is :typoscript:`TCEMAIN.permissions.groupid` to a group id, plus +:typoscript:`TCEMAIN.permissions.group=31` to allow all members of this group to do +"everything". To be sure, :typoscript:`TCEMAIN.permissions.everybody=0` is set +to deny access for non-members. Most often, a "page owner" base group is added +all backend users are members of (directly, or via sub groups). Access to single page +trees are then done via page mounts points in backend group "mount group records" +that have this "page owner" group as sub group. When a backend user being member +of that "mount group" and thus having access to that page tree then creates new pages +below this top level page, the page owner is set to the creating user, and group +ownership plus access details like "can i modify?" are forced to the TSconfig +settings of the top level page. + +With a base setup like that, administrators typically have to configure and set up +page group ownership once per root site and are then sure that everything below +"inherits" properly. + +In more complex scenarios, different group owners are set for parts of a sub page +tree. Administrators then want to make sure that new pages created below this differently +restricted set of pages also inherit those changed group ownership settings when users +create new pages. Until now, they had to change :typoscript:`TCEMAIN.permissions.groupid` +and potentially `TCEMAIN.permissions.group` and :typoscript:`TCEMAIN.permissions.everybody` +to achieve that and had to maintain TSconfig accordingly. + +The new :typoscript:`copyFromParent` value can be leveraged to reduce administrator +overhead to near-zero for access settings, especially when combined with :php:`defaultPageTSconfig`. +Let's say we have a TYPO3 instance with multiple sites. There is still a "page owner" group +plus various other groups for backend user mount points to single sites. A basic +site extension now sets this in a :file:`ext_tables.php` file: + +.. code-block:: php + + $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] .= ' + TCEMAIN.permissions.groupid = copyFromParent + TCEMAIN.permissions.group = 31 + TCEMAIN.permissions.everybody = 0 + '; + +This configures a default 'New pages are set to the owner of the parent page and members +of this group can do "everything"'. When an administrator now creates a new site, it would +set the "group" of that page using the access module to the "page owner" group once, and +this will inherit to sub pages automatically whenever a backend user creates a page. And +all that without additional TSconfig settings. If an administrator later sets a different +group owner for a sub page, new pages in there will inherit that owner instead, too. + +From a unix administrator point of view, this setting is similar to the "group sticky bit" +for directories - new directories get that group owner set by looking at the parent +directory and in itself inherit it to new sub directories. Example ======= diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/PagePermissionTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/PagePermissionTest.php index 9fa1783d4985b5d9255a8c4552c2b4b1a2328629..06a23e92e3aa4584d0dce905ad6498bdf3a37715 100644 --- a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/PagePermissionTest.php +++ b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/PagePermissionTest.php @@ -118,12 +118,27 @@ TCEMAIN.permissions.everybody = copyFromParent ', ]); + // We change perm settings of recently added page, so we can really check + // if perm settings are copied from parent page and not using default settings. + $this->changePageData( + (int)$parent['uid'], + [ + 'perms_userid' => 1, + 'perms_groupid' => 1, + 'perms_user' => Permission::PAGE_SHOW, + 'perms_group' => Permission::PAGE_SHOW, + 'perms_everybody' => Permission::PAGE_SHOW, + ] + ); + + // insert second page which should inherit settings from page 88 $record = $this->insertPage((int)$parent['uid']); - self::assertEquals(12, $record['perms_userid']); - self::assertEquals(42, $record['perms_groupid']); - self::assertEquals(Permission::PAGE_SHOW + Permission::PAGE_EDIT, $record['perms_user']); - self::assertEquals(Permission::PAGE_SHOW + Permission::PAGE_DELETE, $record['perms_group']); - self::assertEquals(Permission::PAGE_SHOW + Permission::PAGE_DELETE, $record['perms_everybody']); + + self::assertEquals(1, $record['perms_userid']); + self::assertEquals(1, $record['perms_groupid']); + self::assertEquals(Permission::PAGE_SHOW, $record['perms_user']); + self::assertEquals(Permission::PAGE_SHOW, $record['perms_group']); + self::assertEquals(Permission::PAGE_SHOW, $record['perms_everybody']); } /** @@ -136,4 +151,13 @@ TCEMAIN.permissions.everybody = copyFromParent $recordUid = $result['pages'][0]; return BackendUtility::getRecord('pages', $recordUid); } + + protected function changePageData(int $pageId, array $data): void + { + $this->actionService->modifyRecord( + 'pages', + $pageId, + $data + ); + } }