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