Commit 248ea1d5 authored by Benni Mack's avatar Benni Mack Committed by Oliver Hader
Browse files

[TASK] Clean up Page Permission handling in DataHandler

TYPO3's page permissions are based on five fields and a bitset.

- perms_userid
- perms_groupid
- perms_user
- perms_group
- perms_everybody

For permissions of a page there is
- show page ("show")
- edit page properties ("edit page")
- edit page contents / records ("edit content")
- delete page ("delete")
- create new subpages ("new")

In addition, these can be pre-set globally or via PageTSconfig.

The DataHandler currently uses a mix between strings and integers
for defining these values.

A new PagePermissionAssembler class builds together the page permissions
now, allowing to thin out certain parts of DataHandlers responsibility.

The following properties and methods are now deprecated:
- DataHandler->defaultPermissions
- DataHandler->pMap
- DataHandler->setTSconfigPermissions()
- DataHandler->assemblePermissions()

The methods
- DataHandler->doesRecordExist()
- DataHandler->recordInfoWithPermissionCheck()
should only be called with integers as permission argument in the future.

Resolves: #90019
Releases: master
Change-Id: I3724cb8661fe2b7cc5e1f8ab34d17dd4fa68c11b
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/62763


Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
Reviewed-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
parent a28c475e
......@@ -363,6 +363,7 @@ class DataHandler implements LoggerAwareInterface
* Can be overridden from $GLOBALS['TYPO3_CONF_VARS']
*
* @var array
* @deprecated will be removed in TYPO3 11. use PagePermissionAssembler instead.
*/
public $defaultPermissions = [
'user' => 'show,edit,delete,new,editcontent',
......@@ -370,6 +371,11 @@ class DataHandler implements LoggerAwareInterface
'everybody' => ''
];
/**
* @var PagePermissionAssembler
*/
protected $pagePermissionAssembler;
/**
* The list of <table>-<fields> that cannot be edited by user. This is compiled from TCA/exclude-flag combined with non_exclude_fields for the user.
*
......@@ -418,6 +424,7 @@ class DataHandler implements LoggerAwareInterface
* Permission mapping
*
* @var array
* @deprecated will be removed in TYPO3 11. use PagePermissionAssembler instead.
*/
public $pMap = [
'show' => 1,
......@@ -632,6 +639,7 @@ class DataHandler implements LoggerAwareInterface
$this->checkStoredRecords = (bool)$GLOBALS['TYPO3_CONF_VARS']['BE']['checkStoredRecords'];
$this->checkStoredRecords_loose = (bool)$GLOBALS['TYPO3_CONF_VARS']['BE']['checkStoredRecordsLoose'];
$this->runtimeCache = $this->getRuntimeCache();
$this->pagePermissionAssembler = GeneralUtility::makeInstance(PagePermissionAssembler::class, $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPermissions']);
}
/**
......@@ -1056,10 +1064,12 @@ class DataHandler implements LoggerAwareInterface
// Here the "pid" is set IF NOT the old pid was a string pointing to a place in the subst-id array.
[$tscPID] = BackendUtility::getTSCpid($table, $id, $old_pid_value ?: $fieldArray['pid']);
if ($status === 'new' && $table === 'pages') {
$TSConfig = BackendUtility::getPagesTSconfig($tscPID)['TCEMAIN.'] ?? [];
if (isset($TSConfig['permissions.']) && is_array($TSConfig['permissions.'])) {
$fieldArray = $this->setTSconfigPermissions($fieldArray, $TSConfig['permissions.']);
}
$fieldArray = $this->pagePermissionAssembler->applyDefaults(
$fieldArray,
(int)$tscPid,
(int)$this->userid,
(int)$this->BE_USER->firstMainGroup
);
}
// Processing of all fields in incomingFieldArray and setting them in $fieldArray
$fieldArray = $this->fillInFieldArray($table, $id, $fieldArray, $incomingFieldArray, $theRealPid, $status, $tscPID);
......@@ -3153,7 +3163,7 @@ class DataHandler implements LoggerAwareInterface
}
// Fetch record with permission check
$row = $this->recordInfoWithPermissionCheck($table, $uid, 'show');
$row = $this->recordInfoWithPermissionCheck($table, $uid, Permission::PAGE_SHOW);
// This checks if the record can be selected which is all that a copy action requires.
if ($row === false) {
......@@ -3478,7 +3488,7 @@ class DataHandler implements LoggerAwareInterface
}
// Fetch record with permission check
$row = $this->recordInfoWithPermissionCheck($table, $uid, 'show');
$row = $this->recordInfoWithPermissionCheck($table, $uid, Permission::PAGE_SHOW);
// This checks if the record can be selected which is all that a copy action requires.
if ($row === false) {
......@@ -3937,7 +3947,7 @@ class DataHandler implements LoggerAwareInterface
// Edit rights for the record...
$mayMoveAccess = $this->checkRecordUpdateAccess($table, $uid);
} else {
$mayMoveAccess = $this->doesRecordExist($table, $uid, 'delete');
$mayMoveAccess = $this->doesRecordExist($table, $uid, Permission::PAGE_DELETE);
}
// Finding out, if the record may be moved TO another place. Here we check insert-rights (non-pages = edit, pages = new),
// unless the pages are moved on the same pid, then edit-rights are checked
......@@ -4302,7 +4312,7 @@ class DataHandler implements LoggerAwareInterface
return false;
}
if (!$this->doesRecordExist($table, $uid, 'show')) {
if (!$this->doesRecordExist($table, $uid, Permission::PAGE_SHOW)) {
$this->newlog('Attempt to localize record ' . $table . ':' . $uid . ' without permission.', SystemLogErrorClassification::USER_ERROR);
return false;
}
......@@ -4715,7 +4725,7 @@ class DataHandler implements LoggerAwareInterface
$this->log($table, $uid, SystemLogDatabaseAction::DELETE, 0, SystemLogErrorClassification::USER_ERROR, 'Attempt to delete record without delete-permissions');
return;
}
if (!$noRecordCheck && !$this->doesRecordExist($table, $uid, 'delete')) {
if (!$noRecordCheck && !$this->doesRecordExist($table, $uid, Permission::PAGE_DELETE)) {
return;
}
......@@ -4950,16 +4960,16 @@ class DataHandler implements LoggerAwareInterface
// Because it is currently only deleting the translation
$defaultLanguagePageId = $this->getDefaultLanguagePageId($uid);
if ($defaultLanguagePageId !== $uid) {
if ($this->doesRecordExist('pages', (int)$defaultLanguagePageId, 'delete')) {
if ($this->doesRecordExist('pages', (int)$defaultLanguagePageId, Permission::PAGE_DELETE)) {
$isTranslatedPage = true;
} else {
return 'Attempt to delete page without permissions';
}
} elseif (!$this->doesRecordExist('pages', $uid, 'delete')) {
} elseif (!$this->doesRecordExist('pages', $uid, Permission::PAGE_DELETE)) {
return 'Attempt to delete page without permissions';
}
$pageIdsInBranch = $this->doesBranchExist('', $uid, $this->pMap['delete'], true);
$pageIdsInBranch = $this->doesBranchExist('', $uid, Permission::PAGE_DELETE, true);
if ($this->deleteTree) {
if ($pageIdsInBranch === -1) {
......@@ -5003,7 +5013,7 @@ class DataHandler implements LoggerAwareInterface
$res = $this->canDeletePage($id);
return is_array($res) ? false : $res;
}
return $this->doesRecordExist($table, $id, 'delete') ? false : 'No permission to delete record';
return $this->doesRecordExist($table, $id, Permission::PAGE_DELETE) ? false : 'No permission to delete record';
}
/**
......@@ -5183,7 +5193,7 @@ class DataHandler implements LoggerAwareInterface
}
// Fetch record with permission check
$row = $this->recordInfoWithPermissionCheck($table, $id, 'show');
$row = $this->recordInfoWithPermissionCheck($table, $id, Permission::PAGE_SHOW);
// This checks if the record can be selected which is all that a copy action requires.
if ($row === false) {
......@@ -5984,7 +5994,13 @@ class DataHandler implements LoggerAwareInterface
return $cachedValue;
}
if ($this->doesRecordExist($table, $id, 'edit')) {
if ($table === 'pages' || ($table === 'sys_file_reference' && array_key_exists('pages', $this->datamap))) {
// @todo: find a more generic way to handle content relations of a page (without needing content editing access to that page)
$perms = Permission::PAGE_EDIT;
} else {
$perms = Permission::CONTENT_EDIT;
}
if ($this->doesRecordExist($table, $id, $perms)) {
$res = 1;
}
// Cache the result
......@@ -6015,12 +6031,12 @@ class DataHandler implements LoggerAwareInterface
$res = false;
if ($insertTable === 'pages') {
$perms = $this->pMap['new'];
$perms = Permission::PAGE_NEW;
} elseif (($insertTable === 'sys_file_reference') && array_key_exists('pages', $this->datamap)) {
// @todo: find a more generic way to handle content relations of a page (without needing content editing access to that page)
$perms = $this->pMap['edit'];
$perms = Permission::PAGE_EDIT;
} else {
$perms = $this->pMap['editcontent'];
$perms = Permission::CONTENT_EDIT;
}
$pageExists = (bool)$this->doesRecordExist('pages', $pid, $perms);
// If either admin and root-level or if page record exists and 1) if 'pages' you may create new ones 2) if page-content, new content items may be inserted on the $pid page
......@@ -6080,13 +6096,16 @@ class DataHandler implements LoggerAwareInterface
*
* @param string $table Record table name
* @param int $id Record UID
* @param int|string $perms Permission restrictions to observe: Either an integer that will be bitwise AND'ed or a string, which points to a key in the ->pMap array
* @param int|string $perms Permission restrictions to observe: Either an integer that will be bitwise AND'ed or a string, which points to a key in the ->pMap array. Only integers are supported starting with TYPO3 v11.
* @return bool Returns TRUE if the record given by $table, $id and $perms can be selected
*
* @throws \RuntimeException
*/
public function doesRecordExist($table, $id, $perms)
{
if (!MathUtility::canBeInterpretedAsInteger($perms)) {
trigger_error('Support for handing in permissions as string into "doesRecordExist" will be not be supported with TYPO3 v11 anymore. Use the Permission BitSet class instead.', E_USER_DEPRECATED);
}
return $this->recordInfoWithPermissionCheck($table, $id, $perms, 'uid, pid') !== false;
}
......@@ -6379,7 +6398,7 @@ class DataHandler implements LoggerAwareInterface
*
* @param string $table Record table name
* @param int $id Record UID
* @param int|string $perms Permission restrictions to observe: Either an integer that will be bitwise AND'ed or a string, which points to a key in the ->pMap array
* @param int|string $perms Permission restrictions to observe: Either an integer that will be bitwise AND'ed or a string, which points to a key in the ->pMap array. With TYPO3 v11, only integers are allowed
* @param string $fieldList - fields - default is '*'
* @throws \RuntimeException
* @return array|bool Row if exists and accessible, false otherwise
......@@ -6402,12 +6421,11 @@ class DataHandler implements LoggerAwareInterface
}
// Processing the incoming $perms (from possible string to integer that can be AND'ed)
if (!MathUtility::canBeInterpretedAsInteger($perms)) {
trigger_error('Support for handing in permissions as string into "recordInfoWithPermissionCheck" will be not be supported with TYPO3 v11 anymore. Use the Permission BitSet class instead.', E_USER_DEPRECATED);
if ($table !== 'pages') {
switch ($perms) {
case 'edit':
case 'delete':
case 'new':
// This holds it all in case the record is not page!!
if ($table === 'sys_file_reference' && array_key_exists('pages', $this->datamap)) {
......@@ -6418,7 +6436,7 @@ class DataHandler implements LoggerAwareInterface
break;
}
}
$perms = (int)$this->pMap[$perms];
$perms = (int)(Permission::getMap()[$perms] ?? 0);
} else {
$perms = (int)$perms;
}
......@@ -7084,9 +7102,11 @@ class DataHandler implements LoggerAwareInterface
* @param array $fieldArray Field Array, returned with modifications
* @param array $TSConfig_p TSconfig properties
* @return array Modified Field Array
* @deprecated will be removed in TYPO3 v11.0 - Use PagePermissionAssembler instead.
*/
public function setTSconfigPermissions($fieldArray, $TSConfig_p)
{
trigger_error('DataHandler->setTSconfigPermissions will be removed in TYPO3 v11.0. Use the PagePermissionAssembler API instead.', E_USER_DEPRECATED);
if ((string)$TSConfig_p['userid'] !== '') {
$fieldArray['perms_userid'] = (int)$TSConfig_p['userid'];
}
......@@ -7124,14 +7144,6 @@ class DataHandler implements LoggerAwareInterface
}
}
}
// Set default permissions for a page.
if ($table === 'pages') {
$fieldArray['perms_userid'] = $this->userid;
$fieldArray['perms_groupid'] = (int)$this->BE_USER->firstMainGroup;
$fieldArray['perms_user'] = $this->assemblePermissions($this->defaultPermissions['user']);
$fieldArray['perms_group'] = $this->assemblePermissions($this->defaultPermissions['group']);
$fieldArray['perms_everybody'] = $this->assemblePermissions($this->defaultPermissions['everybody']);
}
return $fieldArray;
}
......@@ -7282,14 +7294,17 @@ class DataHandler implements LoggerAwareInterface
* @return int Integer mask
* @see setTSconfigPermissions()
* @see newFieldArray()
* @deprecated will be removed in TYPO3 v11.0 - Use PagePermissionAssembler instead.
*/
public function assemblePermissions($string)
{
trigger_error('DataHandler->assemblePermissions will be removed in TYPO3 v11.0. Use the PagePermissionAssembler API instead.', E_USER_DEPRECATED);
$keyArr = GeneralUtility::trimExplode(',', $string, true);
$value = 0;
$permissionMap = Permission::getMap();
foreach ($keyArr as $key) {
if ($key && isset($this->pMap[$key])) {
$value |= $this->pMap[$key];
if ($key && isset($permissionMap[$key])) {
$value |= $permissionMap[$key];
}
}
return $value;
......@@ -7443,7 +7458,7 @@ class DataHandler implements LoggerAwareInterface
->where($queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pid, \PDO::PARAM_INT)))
->orderBy('sorting', 'DESC');
if (!$this->admin) {
$queryBuilder->andWhere($this->BE_USER->getPagePermsClause($this->pMap['show']));
$queryBuilder->andWhere($this->BE_USER->getPagePermsClause(Permission::PAGE_SHOW));
}
if ((int)$this->BE_USER->workspace === 0) {
$queryBuilder->andWhere(
......
<?php
declare(strict_types = 1);
namespace TYPO3\CMS\Core\DataHandling;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
/**
* Class to determine and set proper permissions to a new (or copied) page.
*
* The following order applies:
* - defaultPermissions as defined in this class.
* - TYPO3_CONF_VARS[BE][defaultPermissions]
* - PageTSconfig va TCEMAIN.permissions
*/
class PagePermissionAssembler
{
/**
* Can be overridden from $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPermissions']
*
* @var array
*/
protected $defaultPermissions = [
'user' => 'show,edit,delete,new,editcontent',
'group' => 'show,edit,new,editcontent',
'everybody' => ''
];
public function __construct(array $defaultPermissions = null)
{
// Initializing default permissions for pages
if (isset($defaultPermissions['user'])) {
$this->defaultPermissions['user'] = $defaultPermissions['user'];
}
if (isset($defaultPermissions['group'])) {
$this->defaultPermissions['group'] = $defaultPermissions['group'];
}
if (isset($defaultPermissions['everybody'])) {
$this->defaultPermissions['everybody'] = $defaultPermissions['everybody'];
}
}
/**
* Set default permissions of a new page, and override via pageTSconfig.
*
* @param array $fieldArray the field array to be used
* @param int $pid the parent page ID
* @param int $backendUserId the owner of the page to be set
* @param int $backendUserGroupId the owner group of the page to be set
* @return array the enriched field array
*/
public function applyDefaults(array $fieldArray, int $pid, int $backendUserId, int $backendUserGroupId): array
{
$fieldArray['perms_userid'] = $backendUserId;
$fieldArray['perms_groupid'] = $backendUserGroupId;
$fieldArray['perms_user'] = $this->assemblePermissions($this->defaultPermissions['user']);
$fieldArray['perms_group'] = $this->assemblePermissions($this->defaultPermissions['group']);
$fieldArray['perms_everybody'] = $this->assemblePermissions($this->defaultPermissions['everybody']);
$TSConfig = BackendUtility::getPagesTSconfig($pid)['TCEMAIN.'] ?? [];
if (isset($TSConfig['permissions.']) && is_array($TSConfig['permissions.'])) {
return $this->setTSconfigPermissions($fieldArray, $TSConfig['permissions.']);
}
return $fieldArray;
}
/**
* Setting up perms_* fields in $fieldArray based on TSconfig input
* Used for new pages and pages that are copied.
*
* @param array $fieldArray Field Array, returned with modifications
* @param array $tsconfig TSconfig properties
* @return array Modified Field Array
*/
protected function setTSconfigPermissions(array $fieldArray, array $tsconfig): array
{
if ((string)$tsconfig['userid'] !== '') {
$fieldArray['perms_userid'] = (int)$tsconfig['userid'];
}
if ((string)$tsconfig['groupid'] !== '') {
$fieldArray['perms_groupid'] = (int)$tsconfig['groupid'];
}
if ((string)$tsconfig['user'] !== '') {
$fieldArray['perms_user'] = $this->assemblePermissions($tsconfig['user']);
}
if ((string)$tsconfig['group'] !== '') {
$fieldArray['perms_group'] = $this->assemblePermissions($tsconfig['group']);
}
if ((string)$tsconfig['everybody'] !== '') {
$fieldArray['perms_everybody'] = $this->assemblePermissions($tsconfig['everybody']);
}
return $fieldArray;
}
/**
* Calculates the bitvalue of the permissions given in a string, comma-separated
*
* @param string $listOfPermissions a comma-separated list like "show,delete", usually from pageTSconfig
* @return int Integer mask
*/
protected function assemblePermissions($listOfPermissions): int
{
// Already set as integer, so this one is used.
if (MathUtility::canBeInterpretedAsInteger($listOfPermissions)) {
return (int)$listOfPermissions;
}
$keyArr = GeneralUtility::trimExplode(',', $listOfPermissions, true);
$value = 0;
$permissionMap = Permission::getMap();
foreach ($keyArr as $key) {
if ($key && isset($permissionMap[$key])) {
$value |= $permissionMap[$key];
}
}
return $value;
}
}
......@@ -55,4 +55,26 @@ final class Permission extends Enumeration
* @var int
*/
const ALL = 31;
/**
* Permission mapping
* Used for instance in PageTS
*
* @return array
* @internal
*/
public static function getMap(): array
{
return [
'show' => static::PAGE_SHOW,
// 1st bit
'edit' => static::PAGE_EDIT,
// 2nd bit
'delete' => static::PAGE_DELETE,
// 3rd bit
'new' => static::PAGE_NEW,
// 4th bit
'editcontent' => static::CONTENT_EDIT
];
}
}
.. include:: ../../Includes.txt
=====================================================================
Deprecation: #90019 - Extraction of DataHandler page permission logic
=====================================================================
See :issue:`90019`
Description
===========
A new PagePermissionAssembler class builds the page permissions, allowing to thin out certain parts of DataHandlers responsibilities.
The following properties and methods within :php:`DataHandler` are now deprecated:
- :php:`TYPO3\CMS\Core\DataHandling\DataHandler->defaultPermissions`
- :php:`TYPO3\CMS\Core\DataHandling\DataHandler->pMap`
- :php:`TYPO3\CMS\Core\DataHandling\DataHandler->setTSconfigPermissions()`
- :php:`TYPO3\CMS\Core\DataHandling\DataHandler->assemblePermissions()`
The methods
- :php:`TYPO3\CMS\Core\DataHandling\DataHandler->doesRecordExist()`
- :php:`TYPO3\CMS\Core\DataHandling\DataHandler->recordInfoWithPermissionCheck()`
should only be called with integers as permission argument.
Impact
======
Calling the mentioned methods will trigger a PHP deprecation warning but will continue to work until TYPO3 v11.0.
Affected Installations
======================
Any TYPO3 installations that enrich page permission handling and directly access the methods or properties in DataHandler.
Migration
=========
Ensure to use the new :php:`PagePermissionAssembler` PHP class
which serves as a proper API for creating page records.
.. index:: PHP-API, PartiallyScanned, ext:core
\ No newline at end of file
<?php
namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Regular;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
use TYPO3\CMS\Core\Type\Bitmask\Permission;
/**
* Tests related to DataHandler setting proper page permissions
*/
class PagePermissionTest extends AbstractDataHandlerActionTestCase
{
/**
* @var string
*/
protected $scenarioDataSetDirectory = 'typo3/sysext/core/Tests/Functional/DataHandling/Regular/DataSet/';
protected function setUp(): void
{
parent::setUp();
$this->importScenarioDataSet('LiveDefaultPages');
}
/**
* @test
*/
public function newPageReceivesDefaultPermissionSet()
{
$this->backendUser->user['uid'] = 13;
$this->backendUser->firstMainGroup = 14;
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPermissions'] = [
'user' => 'show,editcontent,edit,delete',
'group' => 'show,editcontent,new',
'everybody' => 'show'
];
$record = $this->insertPage();
self::assertEquals(13, $record['perms_userid']);
self::assertEquals(14, $record['perms_groupid']);
self::assertEquals(Permission::PAGE_SHOW + Permission::CONTENT_EDIT + Permission::PAGE_EDIT + Permission::PAGE_DELETE, $record['perms_user']);
self::assertEquals(Permission::PAGE_SHOW + Permission::CONTENT_EDIT + Permission::PAGE_NEW, $record['perms_group']);
self::assertEquals(Permission::PAGE_SHOW, $record['perms_everybody']);
}
/**
* @test
*/
public function newPageReceivesOverriddenPageTsPermissionSet()
{
$this->backendUser->user['uid'] = 13;
$this->backendUser->firstMainGroup = 14;
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPermissions'] = [
'user' => 'show,editcontent,edit,delete',
'group' => 'show,editcontent,new',
'everybody' => 'show'
];
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] = '
TCEMAIN.permissions.userid = 12
TCEMAIN.permissions.groupid = 42
TCEMAIN.permissions.user = show,edit
TCEMAIN.permissions.group = show,delete
TCEMAIN.permissions.everybody = show,delete
';
$record = $this->insertPage();
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']);
}
/**
* @return array
*/
protected function insertPage()
{
// pid 88 comes from LiveDefaultPages
$result = $this->actionService->createNewRecord('pages', 88, [
'title' => 'Test page'
]);
$recordUid = $result['pages'][0];
return BackendUtility::getRecord('pages', $recordUid);
}
}
......@@ -4378,4 +4378,18 @@ return [
'Deprecation-89868-RemoveReqCHashFunctionalityForPlugins.rst',
],
],
'TYPO3\CMS\Core\DataHandling\DataHandler->setTSconfigPermissions' => [
'numberOfMandatoryArguments' => 2,
'maximumNumberOfArguments' => 2,
'restFiles' => [
'Deprecation-90019-ExtractionOfDataHandlerPagePermissionLogic.rst',
],
],
'TYPO3\CMS\Core\DataHandling\DataHandler->assemblePermissions' => [
'numberOfMandatoryArguments' => 1,
'maximumNumberOfArguments' => 1,
'restFiles' => [
'Deprecation-90019-ExtractionOfDataHandlerPagePermissionLogic.rst',
],
],
];
......@@ -646,4 +646,14 @@ return [
'Deprecation-89868-RemoveReqCHashFunctionalityForPlugins.rst',
],
],
'TYPO3\CMS\Core\DataHandling\DataHandler->defaultPermissions' => [