‪TYPO3CMS  10.4
DatabaseUserPermissionCheck.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
31 
36 {
53  public function ‪addData(array $result)
54  {
55  $backendUser = $this->‪getBackendUser();
56 
57  // Early return for admins
58  if ($backendUser->isAdmin()) {
59  $result['userPermissionOnPage'] = ‪Permission::ALL;
60  return $result;
61  }
62 
63  if (!$backendUser->check('tables_modify', $result['tableName'])) {
64  // If user has no modify rights on table, processing is stopped by throwing an
65  // exception immediately. This case can not be circumvented by hooks.
67  'No table modify permission for user ' . $backendUser->user['uid'] . ' on table ' . $result['tableName'],
68  1437683248
69  );
70  }
71 
72  $exception = null;
73  $userHasAccess = false;
74  $userPermissionOnPage = ‪Permission::NOTHING;
75  if ($result['command'] === 'new') {
76  // A new record is created. Access rights of parent record are important here
77  // @todo: In case of new inline child, parentPageRow should probably be the
78  // @todo: "inlineFirstPid" page - Maybe effectivePid and parentPageRow should be calculated differently then?
79  if (is_array($result['parentPageRow'])) {
80  // Record is added below an existing page
81  $userPermissionOnPage = $backendUser->calcPerms($result['parentPageRow']);
82  if ($result['tableName'] === 'pages') {
83  // New page is created, user needs PAGE_NEW for this
84  if ((bool)($userPermissionOnPage & ‪Permission::PAGE_NEW)) {
85  $userHasAccess = true;
86  } else {
87  $exception = new ‪AccessDeniedPageNewException(
88  'No page new permission for user ' . $backendUser->user['uid'] . ' on page ' . $result['databaseRow']['uid'],
89  1437745640
90  );
91  }
92  } else {
93  // A regular record is added, not a page. User needs CONTENT_EDIT permission
94  if ((bool)($userPermissionOnPage & ‪Permission::CONTENT_EDIT)) {
95  $userHasAccess = true;
96  } else {
97  $exception = new ‪AccessDeniedContentEditException(
98  'No content new permission for user ' . $backendUser->user['uid'] . ' on page ' . $result['parentPageRow']['uid'],
99  1437745759
100  );
101  }
102  }
103  } elseif (‪BackendUtility::isRootLevelRestrictionIgnored($result['tableName'])) {
104  // Non admin is creating a record on root node for a table that is actively allowed
105  $userHasAccess = true;
106  $userPermissionOnPage = ‪Permission::ALL;
107  } else {
108  // Non admin has no create permission on root node records
109  $exception = new ‪AccessDeniedRootNodeException(
110  'No record creation permission for user ' . $backendUser->user['uid'] . ' on page root node',
111  1437745221
112  );
113  }
114  } else {
115  // A page or a record on a page is edited
116  if ($result['tableName'] === 'pages') {
117  // A page record is edited, check edit rights of this record directly
118  $userPermissionOnPage = $backendUser->calcPerms($result['defaultLanguagePageRow'] ?? $result['databaseRow']);
119  if ((bool)($userPermissionOnPage & ‪Permission::PAGE_EDIT) && $backendUser->check('pagetypes_select', $result['databaseRow'][$result['processedTca']['ctrl']['type']])) {
120  $userHasAccess = true;
121  } else {
122  $exception = new ‪AccessDeniedPageEditException(
123  'No page edit permission for user ' . $backendUser->user['uid'] . ' on page ' . $result['databaseRow']['uid'],
124  1437679336
125  );
126  }
127  } else {
128  // A non page record is edited.
129  if (isset($result['parentPageRow']) && is_array($result['parentPageRow'])) {
130  // If there is a parent page row, check content edit right of user
131  $userPermissionOnPage = $backendUser->calcPerms($result['parentPageRow']);
132  if ((bool)($userPermissionOnPage & ‪Permission::CONTENT_EDIT)) {
133  $userHasAccess = true;
134  } else {
135  $exception = new ‪AccessDeniedContentEditException(
136  'No content edit permission for user ' . $backendUser->user['uid'] . ' on page ' . $result['parentPageRow']['uid'],
137  1437679657
138  );
139  }
140  } elseif (‪BackendUtility::isRootLevelRestrictionIgnored($result['tableName'])) {
141  // Non admin is editing a record on root node for a table that is actively allowed
142  $userHasAccess = true;
143  $userPermissionOnPage = ‪Permission::ALL;
144  } else {
145  // Non admin has no edit permission on root node records
146  // @todo: This probably needs further handling, see http://review.typo3.org/40835
147  $exception = new ‪AccessDeniedRootNodeException(
148  'No content edit permission for user ' . $backendUser->user['uid'] . ' on page root node',
149  1437679856
150  );
151  }
152  }
153  if ($userHasAccess) {
154  // If general access is allowed, check "recordEditAccessInternals"
155  $userHasAccess = $backendUser->recordEditAccessInternals($result['tableName'], $result['databaseRow']);
156  if (!$userHasAccess) {
157  $exception = new ‪AccessDeniedEditInternalsException(
158  $backendUser->errorMsg,
159  1437687404
160  );
161  }
162  }
163  }
164 
165  if ($userHasAccess && $exception) {
166  // Having user access TRUE here and an exception defined must not happen,
167  // indicates an internal error and throws a logic exception
168  throw new \LogicException(
169  'Access was TRUE but an exception was raised as well for table ' . $result['tableName'] . ' and user ' . $backendUser->user['uid'],
170  1437688402
171  );
172  }
173 
174  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/alt_doc.php']['makeEditForm_accessCheck'] ?? null)) {
175  // A hook may modify the $userHasAccess decision. Previous state is saved to see if a hook changed
176  // a previous decision from TRUE to FALSE to throw a specific exception in this case
177  $userHasAccessBeforeHook = $userHasAccess;
178  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/alt_doc.php']['makeEditForm_accessCheck'] as $methodReference) {
179  $parameters = [
180  'table' => $result['tableName'],
181  'uid' => $result['databaseRow']['uid'],
182  'cmd' => $result['command'],
183  'hasAccess' => $userHasAccess,
184  ];
185  $userHasAccess = (bool)GeneralUtility::callUserFunction($methodReference, $parameters, $this);
186  }
187  if ($userHasAccessBeforeHook && !$userHasAccess) {
188  $exception = new ‪AccessDeniedHookException(
189  'Access to table ' . $result['tableName'] . ' for user ' . $backendUser->user['uid'] . ' was denied by a makeEditForm_accessCheck hook',
190  1437689705
191  );
192  }
193  if (!$userHasAccessBeforeHook && $userHasAccess) {
194  // Unset a previous exception if hook allowed access where previous checks didn't
195  $exception = null;
196  }
197  }
198 
199  if (!$userHasAccess && !$exception) {
200  // User has no access, but no according exception was defined. This is an
201  // internal error and throws a logic exception.
202  throw new \LogicException(
203  'Access to table ' . $result['tableName'] . ' denied, but no reason given',
204  1437690507
205  );
206  }
207 
208  if ($exception) {
209  throw $exception;
210  }
211 
212  $result['userPermissionOnPage'] = $userPermissionOnPage;
213 
214  return $result;
215  }
216 
220  protected function ‪getBackendUser()
221  {
222  return ‪$GLOBALS['BE_USER'];
223  }
224 }
‪TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseUserPermissionCheck
Definition: DatabaseUserPermissionCheck.php:36
‪TYPO3\CMS\Backend\Form\Exception\AccessDeniedContentEditException
Definition: AccessDeniedContentEditException.php:22
‪TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseUserPermissionCheck\addData
‪array addData(array $result)
Definition: DatabaseUserPermissionCheck.php:53
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_NEW
‪const PAGE_NEW
Definition: Permission.php:48
‪TYPO3\CMS\Backend\Form\Exception\AccessDeniedRootNodeException
Definition: AccessDeniedRootNodeException.php:22
‪TYPO3\CMS\Core\Type\Bitmask\Permission\NOTHING
‪const NOTHING
Definition: Permission.php:28
‪TYPO3\CMS\Backend\Utility\BackendUtility\isRootLevelRestrictionIgnored
‪static bool isRootLevelRestrictionIgnored($table)
Definition: BackendUtility.php:4063
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:24
‪TYPO3\CMS\Backend\Form\Exception\AccessDeniedEditInternalsException
Definition: AccessDeniedEditInternalsException.php:22
‪TYPO3\CMS\Core\Type\Bitmask\Permission\ALL
‪const ALL
Definition: Permission.php:58
‪TYPO3\CMS\Backend\Form\Exception\AccessDeniedTableModifyException
Definition: AccessDeniedTableModifyException.php:22
‪TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseUserPermissionCheck\getBackendUser
‪BackendUserAuthentication getBackendUser()
Definition: DatabaseUserPermissionCheck.php:220
‪TYPO3\CMS\Backend\Form\Exception\AccessDeniedHookException
Definition: AccessDeniedHookException.php:22
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Backend\Form\FormDataProvider
Definition: AbstractDatabaseRecordProvider.php:16
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:75
‪TYPO3\CMS\Backend\Form\FormDataProviderInterface
Definition: FormDataProviderInterface.php:23
‪TYPO3\CMS\Core\Type\Bitmask\Permission\CONTENT_EDIT
‪const CONTENT_EDIT
Definition: Permission.php:53
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Backend\Form\Exception\AccessDeniedException
Definition: AccessDeniedException.php:26
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_EDIT
‪const PAGE_EDIT
Definition: Permission.php:38
‪TYPO3\CMS\Backend\Form\Exception\AccessDeniedPageNewException
Definition: AccessDeniedPageNewException.php:22
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Backend\Form\Exception\AccessDeniedPageEditException
Definition: AccessDeniedPageEditException.php:22