Skip to content

Commit c04481c

Browse files
authored
Merge pull request #44 from ayacoo/security/2
[SECURITY] Ensure only allowed users can view redirects
2 parents efab058 + 289819e commit c04481c

6 files changed

Lines changed: 86 additions & 37 deletions

File tree

Classes/Form/Element/RedirectElement.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace Ayacoo\RedirectTab\Form\Element;
55

66
use Ayacoo\RedirectTab\Event\ModifyRedirectsEvent;
7+
use Ayacoo\RedirectTab\UserFunctions\RedirectAccessDisplayCondition;
78
use Psr\EventDispatcher\EventDispatcherInterface;
89
use TYPO3\CMS\Backend\Form\Element\AbstractFormElement;
910
use TYPO3\CMS\Core\Site\Entity\NullSite;
@@ -40,7 +41,9 @@ public function render(): array
4041
$event = $this->eventDispatcher->dispatch(new ModifyRedirectsEvent($redirects));
4142
$redirects = $event->getRedirects();
4243

44+
$redirectAccess = GeneralUtility::makeInstance(RedirectAccessDisplayCondition::class);
4345
$this->view->assignMultiple([
46+
'canEditRedirects' => $redirectAccess->canEditRedirects(),
4447
'redirects' => $redirects,
4548
'demand' => $demand,
4649
'pagination' => $this->preparePagination($demand)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Ayacoo\RedirectTab\UserFunctions;
6+
7+
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
8+
9+
class RedirectAccessDisplayCondition
10+
{
11+
private const TABLE_NAME = 'sys_redirect';
12+
13+
public function canListRedirects(): bool
14+
{
15+
return $this->getBackendUser()->isAdmin() || $this->getBackendUser()->check('tables_select', self::TABLE_NAME);
16+
}
17+
18+
public function canEditRedirects(): bool
19+
{
20+
return $this->getBackendUser()->isAdmin() || $this->getBackendUser()->check('tables_modify', self::TABLE_NAME);
21+
}
22+
23+
protected function getBackendUser(): BackendUserAuthentication
24+
{
25+
return $GLOBALS['BE_USER'];
26+
}
27+
}

Configuration/TCA/Overrides/pages.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
*/
1010
$temporaryColumns = [
1111
'redirects' => [
12+
'displayCond' => [
13+
'AND' => [
14+
'REC:NEW:false',
15+
'USER:' . \Ayacoo\RedirectTab\UserFunctions\RedirectAccessDisplayCondition::class . '->canListRedirects',
16+
],
17+
],
1218
'exclude' => true,
1319
'label' => '',
1420
'config' => [

Resources/Private/Templates/Backend/List.html

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,16 @@
3737
</f:if>
3838
<core:iconForRecord table="sys_redirect" row="{redirect}" /></span>
3939
</f:alias>
40-
<be:link.editRecord table="sys_redirect" uid="{redirect.uid}" title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:edit')}: {redirect.source_path}">
41-
{redirect.source_path -> f:format.crop(maxCharacters:100)}
42-
</be:link.editRecord>
40+
<f:if condition="{canEditRedirects}">
41+
<f:then>
42+
<be:link.editRecord table="sys_redirect" uid="{redirect.uid}" title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:edit')}: {redirect.source_path}">
43+
{redirect.source_path -> f:format.crop(maxCharacters:100)}
44+
</be:link.editRecord>
45+
</f:then>
46+
<f:else>
47+
{redirect.source_path -> f:format.crop(maxCharacters:100)}
48+
</f:else>
49+
</f:if>
4350
</td>
4451

4552
<td>
@@ -50,36 +57,38 @@
5057

5158
<td>
5259
<div class="btn-group">
53-
<f:if condition="{redirect.is_regexp} || {redirect.source_host} === '*'">
54-
<f:then>
55-
<span class="btn btn-default disabled"><core:icon identifier="empty-empty" /></span>
56-
</f:then>
57-
<f:else>
58-
<f:link.external class="btn btn-default" uri="{redirect.source_host}{redirect.source_path}" target="_blank" title="{f:translate(key: 'LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:view_redirect')}">
59-
<core:icon identifier="actions-view-page" />
60-
</f:link.external>
61-
</f:else>
60+
<f:if condition="{canEditRedirects}">
61+
<f:if condition="{redirect.is_regexp} || {redirect.source_host} === '*'">
62+
<f:then>
63+
<span class="btn btn-default disabled"><core:icon identifier="empty-empty" /></span>
64+
</f:then>
65+
<f:else>
66+
<f:link.external class="btn btn-default" uri="{redirect.source_host}{redirect.source_path}" target="_blank" title="{f:translate(key: 'LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:view_redirect')}">
67+
<core:icon identifier="actions-view-page" />
68+
</f:link.external>
69+
</f:else>
70+
</f:if>
71+
<f:if condition="{redirect.disabled} == 1">
72+
<f:then>
73+
<a class="btn btn-default" href="{be:moduleLink(route:'tce_db', query:'data[sys_redirect][{redirect.uid}][disabled]=0', currentUrlParameterName:'redirect')}" title="{f:translate(key:'LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:unHide')}"><core:icon identifier="actions-edit-unhide" /></a>
74+
</f:then>
75+
<f:else>
76+
<a class="btn btn-default" href="{be:moduleLink(route:'tce_db', query:'data[sys_redirect][{redirect.uid}][disabled]=1', currentUrlParameterName:'redirect')}" title="{f:translate(key:'LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:hide')}"><core:icon identifier="actions-edit-hide" /></a>
77+
</f:else>
78+
</f:if>
79+
<be:link.editRecord class="btn btn-default" table="sys_redirect" uid="{redirect.uid}" title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:edit')}">
80+
<core:icon identifier="actions-open" />
81+
</be:link.editRecord>
82+
<a class="btn btn-default t3js-modal-trigger"
83+
href="{be:moduleLink(route:'tce_db', query:'cmd[sys_redirect][{redirect.uid}][delete]=1', currentUrlParameterName:'redirect')}"
84+
title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:delete')}"
85+
data-severity="warning"
86+
data-title="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:label.confirm.delete_record.title')}"
87+
data-bs-content="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:deleteWarning')}"
88+
data-button-close-text="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:buttons.confirm.delete_record.no')}">
89+
<core:icon identifier="actions-delete" />
90+
</a>
6291
</f:if>
63-
<f:if condition="{redirect.disabled} == 1">
64-
<f:then>
65-
<a class="btn btn-default" href="{be:moduleLink(route:'tce_db', query:'data[sys_redirect][{redirect.uid}][disabled]=0', currentUrlParameterName:'redirect')}" title="{f:translate(key:'LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:unHide')}"><core:icon identifier="actions-edit-unhide" /></a>
66-
</f:then>
67-
<f:else>
68-
<a class="btn btn-default" href="{be:moduleLink(route:'tce_db', query:'data[sys_redirect][{redirect.uid}][disabled]=1', currentUrlParameterName:'redirect')}" title="{f:translate(key:'LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:hide')}"><core:icon identifier="actions-edit-hide" /></a>
69-
</f:else>
70-
</f:if>
71-
<be:link.editRecord class="btn btn-default" table="sys_redirect" uid="{redirect.uid}" title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:edit')}">
72-
<core:icon identifier="actions-open" />
73-
</be:link.editRecord>
74-
<a class="btn btn-default t3js-modal-trigger"
75-
href="{be:moduleLink(route:'tce_db', query:'cmd[sys_redirect][{redirect.uid}][delete]=1', currentUrlParameterName:'redirect')}"
76-
title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:delete')}"
77-
data-severity="warning"
78-
data-title="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:label.confirm.delete_record.title')}"
79-
data-bs-content="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:deleteWarning')}"
80-
data-button-close-text="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:buttons.confirm.delete_record.no')}">
81-
<core:icon identifier="actions-delete" />
82-
</a>
8392
</div>
8493
</td>
8594
</tr>
@@ -91,9 +100,13 @@
91100
<f:else>
92101
<f:be.infobox state="-1" title="{f:translate(key: 'LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:redirect_not_found.title')}">
93102
<p><f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:redirect_not_found.message"/></p>
94-
<be:link.newRecord class="btn btn-primary" table="sys_redirect">
95-
<f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:redirect_create"/>
96-
</be:link.newRecord>
103+
<f:if condition="{canEditRedirects}">
104+
<f:then>
105+
<be:link.newRecord class="btn btn-primary" table="sys_redirect">
106+
<f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:redirect_create"/>
107+
</be:link.newRecord>
108+
</f:then>
109+
</f:if>
97110
</f:be.infobox>
98111
</f:else>
99112
</f:if>

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ayacoo/redirect-tab",
33
"type": "typo3-cms-extension",
4-
"version": "2.1.1",
4+
"version": "2.1.2",
55
"description": "Show TYPO3 redirects in the page properties",
66
"authors": [
77
{

ext_emconf.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
'author_email' => 'info@ayacoo.de',
99
'state' => 'beta',
1010
'clearCacheOnLoad' => 0,
11-
'version' => '2.1.1',
11+
'version' => '2.1.2',
1212
'constraints' => [
1313
'depends' => [
1414
'typo3' => '11.0.0-11.99.99',

0 commit comments

Comments
 (0)