Skip to content

Commit

Permalink
[BUGFIX] Improve handling of edit permissions (#732)
Browse files Browse the repository at this point in the history
Resolves: #731
  • Loading branch information
webian authored Oct 3, 2023
1 parent eb858bf commit e5d4cb2
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 40 deletions.
85 changes: 46 additions & 39 deletions Classes/Controller/EditorController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Form\Exception\AccessDeniedEditInternalsException;
use TYPO3\CMS\Backend\Form\Exception\AccessDeniedTableModifyException;
use TYPO3\CMS\Backend\Form\FormDataCompiler;
use TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord;
use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException;
Expand Down Expand Up @@ -88,51 +90,56 @@ public function getConfigurationAction(ServerRequestInterface $request, Response
'disabledWizards' => true
];

$this->formData = $formDataCompiler->compile($formDataCompilerInput);

$formDataFieldName = $this->formData['processedTca']['columns'][$fieldName] ?? null;
$this->rteConfiguration = (isset($formDataFieldName['config']['richtextConfiguration']))
? $formDataFieldName['config']['richtextConfiguration']['editor'] : [];
$hasCkeditorConfiguration = !empty($this->rteConfiguration);

$editorConfiguration = $this->prepareConfigurationForEditor();

$externalPlugins = '';
foreach ($this->getExtraPlugins() as $pluginName => $config) {
$editorConfiguration[$pluginName] = $config['config'];
$editorConfiguration['extraPlugins'] = (isset($editorConfiguration['extraPlugins']))
? $editorConfiguration['extraPlugins'] : '';
if ($editorConfiguration['extraPlugins'] !== null && $editorConfiguration['extraPlugins'] !== '') {
$editorConfiguration['extraPlugins'] .= ',';
try {
$this->formData = $formDataCompiler->compile($formDataCompilerInput);

$formDataFieldName = $this->formData['processedTca']['columns'][$fieldName] ?? null;
$this->rteConfiguration = (isset($formDataFieldName['config']['richtextConfiguration']))
? $formDataFieldName['config']['richtextConfiguration']['editor'] : [];
$hasCkeditorConfiguration = !empty($this->rteConfiguration);

$editorConfiguration = $this->prepareConfigurationForEditor();

$externalPlugins = '';
foreach ($this->getExtraPlugins() as $pluginName => $config) {
$editorConfiguration[$pluginName] = $config['config'];
$editorConfiguration['extraPlugins'] = (isset($editorConfiguration['extraPlugins']))
? $editorConfiguration['extraPlugins'] : '';
if ($editorConfiguration['extraPlugins'] !== null && $editorConfiguration['extraPlugins'] !== '') {
$editorConfiguration['extraPlugins'] .= ',';
}
$editorConfiguration['extraPlugins'] .= $pluginName;

$externalPlugins .= 'CKEDITOR.plugins.addExternal(';
$externalPlugins .= GeneralUtility::quoteJSvalue($pluginName) . ',';
$externalPlugins .= GeneralUtility::quoteJSvalue($config['resource']) . ',';
$externalPlugins .= '\'\');';
}
$editorConfiguration['extraPlugins'] .= $pluginName;

$externalPlugins .= 'CKEDITOR.plugins.addExternal(';
$externalPlugins .= GeneralUtility::quoteJSvalue($pluginName) . ',';
$externalPlugins .= GeneralUtility::quoteJSvalue($config['resource']) . ',';
$externalPlugins .= '\'\');';
}

$configuration = [
'configuration' => $editorConfiguration,
'hasCkeditorConfiguration' => $hasCkeditorConfiguration,
'externalPlugins' => $externalPlugins,
];
$configuration = [
'configuration' => $editorConfiguration,
'hasCkeditorConfiguration' => $hasCkeditorConfiguration,
'externalPlugins' => $externalPlugins,
];

$configurationKey = '';
foreach ($configurations as $existingConfigurationKey => $existingConfiguration) {
if (json_encode($existingConfiguration) === json_encode($configuration)) {
$configurationKey = $existingConfigurationKey;
break;
}
}

$configurationKey = '';
foreach ($configurations as $existingConfigurationKey => $existingConfiguration) {
if (json_encode($existingConfiguration) === json_encode($configuration)) {
$configurationKey = $existingConfigurationKey;
break;
if ($configurationKey === '') {
$configurationKey = count($configurations);
$configurations[$configurationKey] = $configuration;
}
}

if ($configurationKey === '') {
$configurationKey = count($configurations);
$configurations[$configurationKey] = $configuration;
$elements[$uid . '_' . $table . '_' . $fieldName] = $configurationKey;
} catch (AccessDeniedEditInternalsException|AccessDeniedTableModifyException $exception) {
// The editor does not have access to the table of this specific field or to the field itself so,
// instead of displaying a toast with an error, we simply intercept the exception and go on.
}

$elements[$uid . '_' . $table . '_' . $fieldName] = $configurationKey;
}
}

Expand Down
27 changes: 27 additions & 0 deletions Classes/Service/AccessService.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,33 @@ public static function isEnabled(): bool
return $isEnabled;
}

/**
* Has the user edit rights for the content of the page?
*
* @param array $page
* @param int $languageId
* @return bool
*/
public static function isPageEditAllowed(array $page, int $languageId = 0): bool
{
if ($GLOBALS['TCA']['pages']['ctrl']['readOnly'] ?? false) {
return false;
}
$backendUser = $GLOBALS['BE_USER'];
if ($backendUser->isAdmin()) {
return true;
}
if ($GLOBALS['TCA']['pages']['ctrl']['adminOnly'] ?? false) {
return false;
}

return $page !== []
&& !($page[$GLOBALS['TCA']['pages']['ctrl']['editlock'] ?? null] ?? false)
&& $backendUser->doesUserHaveAccess($page, Permission::PAGE_EDIT)
&& $backendUser->checkLanguageAccess($languageId)
&& $backendUser->check('tables_modify', 'pages');
}

/**
* Has the user edit rights for the content of the page?
*
Expand Down
5 changes: 5 additions & 0 deletions Classes/Service/ContentEditableWrapperService.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ public function wrapContent(string $table, int $uid, array $dataArr, string $con
return $content;
}

// Is BE user allowed to edit CE of this table?
if (!$this->getBackendUser()->check('tables_modify', $table)) {
return $content;
}

$hiddenElementClassName = $this->getContentElementClass($table, $uid);
$elementIsHidden = $hiddenElementClassName !== '';

Expand Down
14 changes: 13 additions & 1 deletion Classes/ViewHelpers/ContentEditableViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Exception;
use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\FrontendEditing\Service\AccessService;
Expand Down Expand Up @@ -115,7 +116,10 @@ public function render(): string
$isPageContentEditAllowed = true;
}

if (!AccessService::isEnabled() || !$isPageContentEditAllowed) {
$backendUser = $this->getBackendUser();
$isTableEditAllowed = $backendUser->check('tables_modify', $this->arguments['table']);

if (!AccessService::isEnabled() || !$isPageContentEditAllowed || !$isTableEditAllowed) {
$content = $content ?: '';
return $this->renderAsTag($content);
}
Expand Down Expand Up @@ -175,4 +179,12 @@ protected function renderAsTag(?string $content): string

return $content;
}

/**
* @return BackendUserAuthentication
*/
protected function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}
}

0 comments on commit e5d4cb2

Please sign in to comment.