From 0c292e8f9c5b1ba95721d18f13f73afcf71db78d Mon Sep 17 00:00:00 2001 From: Sybille Peters Date: Sun, 3 Oct 2021 16:22:14 +0200 Subject: [PATCH] [BUGFIX] Fix EditableRestriction for linkvalidator EditableRestriction in linkvalidator checks which fields are editable Doing so, it also considers the allow / deny types (explicit_allowdeny in be_groups). However, there were previously 2 problems which resulted in broken links not displayed for some tables (e.g. in tx_news_domain_model_news): 1. If the type was '0', no value was written to tx_linkvalidator_link. element_type. 2. If ctrl => type was set in TCA, but authMode is not or authMode_enforce == 'strict', the check should not be performed. Both problems are now fixed. The fix for problem 1 requires a rechecking of links so that the element_type field will be filled. Resolves: #94381 Releases: master, 10.4 Change-Id: Id8c6db57baab7e000130198e508b7c437d87faac Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/71419 Tested-by: core-ci Tested-by: Benni Mack Tested-by: Anja Leichsenring Reviewed-by: Benni Mack Reviewed-by: Anja Leichsenring --- .../linkvalidator/Classes/LinkAnalyzer.php | 4 +- .../QueryRestrictions/EditableRestriction.php | 50 ++++++++++++++----- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/typo3/sysext/linkvalidator/Classes/LinkAnalyzer.php b/typo3/sysext/linkvalidator/Classes/LinkAnalyzer.php index 40776f0cfb09..3ae91b1151b6 100644 --- a/typo3/sysext/linkvalidator/Classes/LinkAnalyzer.php +++ b/typo3/sysext/linkvalidator/Classes/LinkAnalyzer.php @@ -202,8 +202,8 @@ protected function checkLinks(array $links, array $linkTypes) $record['field'] = $entryValue['field']; $record['last_check'] = time(); $typeField = $GLOBALS['TCA'][$table]['ctrl']['type'] ?? false; - if ($entryValue['row'][$typeField] ?? false) { - $record['element_type'] = $entryValue['row'][$typeField]; + if (isset($entryValue['row'][$typeField])) { + $record['element_type'] = (string)$entryValue['row'][$typeField]; } $languageField = $GLOBALS['TCA'][$table]['ctrl']['languageField'] ?? false; if ($languageField && isset($entryValue['row'][$languageField])) { diff --git a/typo3/sysext/linkvalidator/Classes/QueryRestrictions/EditableRestriction.php b/typo3/sysext/linkvalidator/Classes/QueryRestrictions/EditableRestriction.php index 3ef244d5ceb1..45233f5478fc 100644 --- a/typo3/sysext/linkvalidator/Classes/QueryRestrictions/EditableRestriction.php +++ b/typo3/sysext/linkvalidator/Classes/QueryRestrictions/EditableRestriction.php @@ -66,7 +66,18 @@ public function __construct(array $searchFields, QueryBuilder $queryBuilder) foreach ($searchFields as $table => $fields) { if ($table !== 'pages' && ($GLOBALS['TCA'][$table]['ctrl']['type'] ?? false)) { $type = $GLOBALS['TCA'][$table]['ctrl']['type']; - $this->explicitAllowFields[$table][$type] = $this->getExplicitAllowFieldsForCurrentUser($table, $type); + $fieldConfig = $GLOBALS['TCA'][$table]['columns'][$type]['config']; + // Check for items + if ($fieldConfig['type'] === 'select' + && is_array($fieldConfig['items'] ?? false) + && isset($fieldConfig['authMode']) + && isset($fieldConfig['authMode_enforce']) && $fieldConfig['authMode_enforce'] === 'strict' + ) { + $this->explicitAllowFields[$table][$type] = $this->getExplicitAllowTypesForCurrentUser( + $table, + $type + ); + } } } $this->queryBuilder = $queryBuilder; @@ -88,20 +99,35 @@ protected function getAllowedLanguagesForCurrentUser(): array return GeneralUtility::intExplode(',', $allowedLanguages); } - protected function getExplicitAllowFieldsForCurrentUser(string $table, string $field): array + /** + * Returns the allowed types for the current user. Should only be called if the + * table has a type field (defined by TCA ctrl => type) which contains 'authMode' + * and has authMode_enforce === 'strict' + * + * @param string $table + * @param string $typeField + * @return string[] + */ + protected function getExplicitAllowTypesForCurrentUser(string $table, string $typeField): array { - $allowDenyOptions = []; - $fieldConfig = $GLOBALS['TCA'][$table]['columns'][$field]['config']; - // Check for items - if ($fieldConfig['type'] === 'select' && is_array($fieldConfig['items'] ?? false)) { - foreach ($fieldConfig['items'] as $iVal) { - $itemIdentifier = (string)$iVal[1]; - if ($GLOBALS['BE_USER']->checkAuthMode($table, $field, $itemIdentifier, $GLOBALS['TYPO3_CONF_VARS']['BE']['explicitADmode'])) { - $allowDenyOptions[] = $itemIdentifier; - } + $allowDenyFieldTypes = []; + $fieldConfig = $GLOBALS['TCA'][$table]['columns'][$typeField]['config']; + foreach ($fieldConfig['items'] as $iVal) { + $itemIdentifier = (string)$iVal[1]; + if ($itemIdentifier === '--div--') { + continue; + } + if ($GLOBALS['BE_USER']->checkAuthMode( + $table, + $typeField, + $itemIdentifier, + $GLOBALS['TYPO3_CONF_VARS']['BE']['explicitADmode'] + ) + ) { + $allowDenyFieldTypes[] = $itemIdentifier; } } - return $allowDenyOptions; + return $allowDenyFieldTypes; } /**