From 09e4735180ff85c421c5631fda2177909dda6fec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20B=C3=BCrk?= <stefan@buerk.tech>
Date: Thu, 25 Nov 2021 18:14:03 +0100
Subject: [PATCH] [TASK] Improve page permission copyFromParent tests and docs

A new feature has been added with #89917 to provide the
possibility that user/group informations and permissions
are used from parent page where the new page is created,
instead of eventually configured defaults through long
standing TSconfig options, or even fallback to current
signed in backend user/user group.

The patch extend the test cases to make more clear
how this new feature is intended to work and improves
the feature .rst file to show how it can be leveraged.

Resolves: #96091
Related: #89917
Releases: master
Change-Id: I5f4478229af69f1abda9aa9e95f1e620743d07ba
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/72290
Tested-by: core-ci <typo3@b13.com>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Nikita Hovratov <nikita.h@live.de>
Tested-by: Oliver Bartsch <bo@cedev.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Nikita Hovratov <nikita.h@live.de>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
---
 .../12.0/Feature-89917-InheritPageAccess.rst  | 61 +++++++++++++++++--
 .../Regular/PagePermissionTest.php            | 34 +++++++++--
 2 files changed, 86 insertions(+), 9 deletions(-)

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 1c2730310897..7e3a02f52594 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 9fa1783d4985..06a23e92e3aa 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
+        );
+    }
 }
-- 
GitLab