Skip to content

Commit

Permalink
[BUGFIX] Check "tables_modify" permissions in list module
Browse files Browse the repository at this point in the history
If an editor has "view" permissions set for a table, but no "modify"
permissions, the record list would still show many buttons related to
modifying records, to the user: "Add", "Edit", "Copy", "Cut" actions.
Trying to click one of these buttons would lead the editor to a broken
page that just shows an infinite loading spinner.

This patch now adds "tables_modify" permission checks to many places in
the code. The following adjustments were made:

- Check modify permissions on "copy" in RecordProvider (context menu)
- Check table modify permissions in DatabaseRecordList

Resolves: #83008
Resolves: #89307
Resolves: #23598
Releases: master, 9.5
Change-Id: Ia3140ba887573a314191ebba5672c85d93fe885c
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63696
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Oliver Bartsch <bo@cedev.de>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Benni Mack <benni@typo3.org>
  • Loading branch information
IndyIndyIndy authored and bmack committed Mar 18, 2020
1 parent 52a85d5 commit 72bcf63
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 6 deletions.
Expand Up @@ -590,6 +590,7 @@ protected function canOpenListModule(): bool
protected function canBeCopied(): bool
{
return !$this->isRecordInClipboard('copy')
&& $this->canBeEdited()
&& !$this->isRecordATranslation();
}

Expand Down
16 changes: 10 additions & 6 deletions typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php
Expand Up @@ -1595,6 +1595,8 @@ public function renderListHeader($table, $currentIdList)
}
// Add an empty entry, so column count fits again after moving this into $icon
$theData[$fCol] = '&nbsp;';
} else {
$icon = $this->spaceIcon;
}
break;
default:
Expand Down Expand Up @@ -1852,18 +1854,17 @@ public function makeControl($table, $row)
$this->addActionToCellGroup($cells, $viewAction, 'view');
}
// "Edit" link: ( Only if permissions to edit the page-record of the content of the parent page ($this->id)
if ($permsEdit) {
if ($permsEdit && $this->isEditable($table)) {
$params = '&edit[' . $table . '][' . $row['uid'] . ']=edit';
$iconIdentifier = 'actions-open';
if ($table === 'pages') {
// Disallow manual adjustment of the language field for pages
$params .= '&overrideVals[pages][sys_language_uid]=' . (int)$row[$GLOBALS['TCA']['pages']['ctrl']['languageField']];
$iconIdentifier = 'actions-page-open';
}
$overlayIdentifier = !$this->isEditable($table) ? 'overlay-readonly' : null;
$editLink = $this->uriBuilder->buildUriFromRoute('record_edit') . $params . $this->makeReturnUrl();
$editAction = '<a class="btn btn-default" href="' . htmlspecialchars($editLink) . '"'
. '" title="' . htmlspecialchars($this->getLanguageService()->getLL('edit')) . '">' . $this->iconFactory->getIcon($iconIdentifier, Icon::SIZE_SMALL, $overlayIdentifier)->render() . '</a>';
. '" title="' . htmlspecialchars($this->getLanguageService()->getLL('edit')) . '">' . $this->iconFactory->getIcon($iconIdentifier, Icon::SIZE_SMALL)->render() . '</a>';
} else {
$editAction = $this->spaceIcon;
}
Expand All @@ -1874,7 +1875,7 @@ public function makeControl($table, $row)
. $this->iconFactory->getIcon('actions-document-info', Icon::SIZE_SMALL)->render() . '</a>';
$this->addActionToCellGroup($cells, $viewBigAction, 'viewBig');
// "Move" wizard link for pages/tt_content elements:
if ($permsEdit && ($table === 'tt_content' || $table === 'pages')) {
if ($permsEdit && ($table === 'tt_content' || $table === 'pages') && $this->isEditable($table)) {
if ($isL10nOverlay) {
$moveAction = $this->spaceIcon;
} else {
Expand Down Expand Up @@ -2741,7 +2742,10 @@ public function setIsEditable(bool $isEditable): void
*/
public function isEditable(string $table): bool
{
return !empty($GLOBALS['TCA'][$table]['ctrl']['readOnly']) ? false : $this->editable;
$backendUser = $this->getBackendUserAuthentication();
return !$GLOBALS['TCA'][$table]['ctrl']['readOnly']
&& $this->editable
&& ($backendUser->isAdmin() || $backendUser->check('tables_modify', $table));
}

/**
Expand Down Expand Up @@ -3482,7 +3486,7 @@ public function linkWrapItems($table, $uid, $code, $row)
$permsEdit = $this->calcPerms & Permission::CONTENT_EDIT && $backendUser->recordEditAccessInternals($table, $row);
}
// "Edit" link: ( Only if permissions to edit the page-record of the content of the parent page ($this->id)
if ($permsEdit) {
if ($permsEdit && $this->isEditable($table)) {
$params = '&edit[' . $table . '][' . $row['uid'] . ']=edit';
$editLink = $this->uriBuilder->buildUriFromRoute('record_edit') . $params . $this->makeReturnUrl();
$code = '<a href="' . htmlspecialchars($editLink) . '" title="' . htmlspecialchars($lang->getLL('edit')) . '">' . $code . '</a>';
Expand Down

0 comments on commit 72bcf63

Please sign in to comment.