a60ace81bcbdc30e5070dff9f2255c0477e6bd48
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / FrontendBackendUserAuthentication.php
1 <?php
2 namespace TYPO3\CMS\Backend;
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
17 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
18 use TYPO3\CMS\Core\Database\ConnectionPool;
19 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
20 use TYPO3\CMS\Core\Database\Query\QueryHelper;
21 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
22 use TYPO3\CMS\Core\Localization\LanguageService;
23 use TYPO3\CMS\Core\Type\Bitmask\Permission;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25
26 /**
27 * TYPO3 backend user authentication in the TSFE frontend.
28 * This includes mainly functions related to the Admin Panel
29 */
30 class FrontendBackendUserAuthentication extends BackendUserAuthentication
31 {
32 /**
33 * Form field with login name.
34 *
35 * @var string
36 */
37 public $formfield_uname = '';
38
39 /**
40 * Form field with password.
41 *
42 * @var string
43 */
44 public $formfield_uident = '';
45
46 /**
47 * Formfield_status should be set to "". The value this->formfield_status is set to empty in order to
48 * disable login-attempts to the backend account through this script
49 *
50 * @var string
51 */
52 public $formfield_status = '';
53
54 /**
55 * Decides if the writelog() function is called at login and logout.
56 *
57 * @var bool
58 */
59 public $writeStdLog = false;
60
61 /**
62 * If the writelog() functions is called if a login-attempt has be tried without success.
63 *
64 * @var bool
65 */
66 public $writeAttemptLog = false;
67
68 /**
69 * General flag which is set if the adminpanel is enabled at all.
70 *
71 * @var bool
72 */
73 public $extAdmEnabled = false;
74
75 /**
76 * @var \TYPO3\CMS\Frontend\View\AdminPanelView Instance of admin panel
77 */
78 public $adminPanel = null;
79
80 /**
81 * @var \TYPO3\CMS\Core\FrontendEditing\FrontendEditingController
82 */
83 public $frontendEdit = null;
84
85 /**
86 * @var array
87 */
88 public $extAdminConfig = [];
89
90 /**
91 * Initializes the admin panel.
92 */
93 public function initializeAdminPanel()
94 {
95 $this->extAdminConfig = $this->getTSConfigProp('admPanel');
96 if (isset($this->extAdminConfig['enable.'])) {
97 foreach ($this->extAdminConfig['enable.'] as $value) {
98 if ($value) {
99 $this->adminPanel = GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\View\AdminPanelView::class);
100 $this->extAdmEnabled = true;
101 break;
102 }
103 }
104 }
105 }
106
107 /**
108 * Initializes frontend editing.
109 */
110 public function initializeFrontendEdit()
111 {
112 if (isset($this->extAdminConfig['enable.']) && $this->isFrontendEditingActive()) {
113 foreach ($this->extAdminConfig['enable.'] as $value) {
114 if ($value) {
115 if ($GLOBALS['TSFE'] instanceof \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController) {
116 // Grab the Page TSConfig property that determines which controller to use.
117 $pageTSConfig = $GLOBALS['TSFE']->getPagesTSconfig();
118 $controllerKey = isset($pageTSConfig['TSFE.']['frontendEditingController'])
119 ? $pageTSConfig['TSFE.']['frontendEditingController']
120 : 'default';
121 } else {
122 $controllerKey = 'default';
123 }
124 $controllerClass = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController'][$controllerKey];
125 if ($controllerClass) {
126 $this->frontendEdit = GeneralUtility::makeInstance($controllerClass);
127 }
128 break;
129 }
130 }
131 }
132 }
133
134 /**
135 * Determines whether frontend editing is currently active.
136 *
137 * @return bool Whether frontend editing is active
138 */
139 public function isFrontendEditingActive()
140 {
141 return $this->extAdmEnabled && (
142 $this->adminPanel->isAdminModuleEnabled('edit') ||
143 (int)$GLOBALS['TSFE']->displayEditIcons === 1 ||
144 (int)$GLOBALS['TSFE']->displayFieldEditIcons === 1
145 );
146 }
147
148 /**
149 * Delegates to the appropriate view and renders the admin panel content.
150 *
151 * @return string.
152 */
153 public function displayAdminPanel()
154 {
155 return $this->adminPanel->display();
156 }
157
158 /**
159 * Determines whether the admin panel is enabled and visible.
160 *
161 * @return bool true if the admin panel is enabled and visible
162 */
163 public function isAdminPanelVisible()
164 {
165 return $this->extAdmEnabled && !$this->extAdminConfig['hide'] && $GLOBALS['TSFE']->config['config']['admPanel'];
166 }
167
168 /*****************************************************
169 *
170 * TSFE BE user Access Functions
171 *
172 ****************************************************/
173 /**
174 * Implementing the access checks that the TYPO3 CMS bootstrap script does before a user is ever logged in.
175 * Used in the frontend.
176 *
177 * @return bool Returns TRUE if access is OK
178 */
179 public function checkBackendAccessSettingsFromInitPhp()
180 {
181 // Check Hardcoded lock on BE
182 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['adminOnly'] < 0) {
183 return false;
184 }
185 // Check IP
186 if (trim($GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
187 if (!GeneralUtility::cmpIP(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
188 return false;
189 }
190 }
191 // Check IP mask based on TSconfig
192 if (!$this->checkLockToIP()) {
193 return false;
194 }
195 // Check SSL (https)
196 if ((bool)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'] && !GeneralUtility::getIndpEnv('TYPO3_SSL')) {
197 return false;
198 }
199 // Finally a check as in BackendUserAuthentication::backendCheckLogin()
200 return $this->isUserAllowedToLogin();
201 }
202
203 /**
204 * Evaluates if the Backend User has read access to the input page record.
205 * The evaluation is based on both read-permission and whether the page is found in one of the users webmounts.
206 * Only if both conditions match, will the function return TRUE.
207 *
208 * Read access means that previewing is allowed etc.
209 *
210 * Used in \TYPO3\CMS\Frontend\Http\RequestHandler
211 *
212 * @param array $pageRec The page record to evaluate for
213 * @return bool TRUE if read access
214 */
215 public function extPageReadAccess($pageRec)
216 {
217 return $this->isInWebMount($pageRec['uid']) && $this->doesUserHaveAccess($pageRec, Permission::PAGE_SHOW);
218 }
219
220 /*****************************************************
221 *
222 * TSFE BE user Access Functions
223 *
224 ****************************************************/
225 /**
226 * Generates a list of Page-uid's from $id. List does not include $id itself
227 * The only pages excluded from the list are deleted pages.
228 *
229 * @param int $id Start page id
230 * @param int $depth Depth to traverse down the page tree.
231 * @param int $begin Is an optional integer that determines at which level in the tree to start collecting uid's. Zero means 'start right away', 1 = 'next level and out'
232 * @param string $perms_clause Perms clause
233 * @return string Returns the list with a comma in the end (if any pages selected!)
234 */
235 public function extGetTreeList($id, $depth, $begin = 0, $perms_clause)
236 {
237 /** @var QueryBuilder $queryBuilder */
238 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
239 ->getQueryBuilderForTable('pages');
240
241 $queryBuilder->getRestrictions()
242 ->removeAll()
243 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
244
245 $depth = (int)$depth;
246 $begin = (int)$begin;
247 $id = (int)$id;
248 $theList = '';
249 if ($id && $depth > 0) {
250 $result = $queryBuilder
251 ->select('uid', 'title')
252 ->from('pages')
253 ->where(
254 $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)),
255 QueryHelper::stripLogicalOperatorPrefix($perms_clause)
256 )
257 ->execute();
258 while ($row = $result->fetch()) {
259 if ($begin <= 0) {
260 $theList .= $row['uid'] . ',';
261 }
262 if ($depth > 1) {
263 $theList .= $this->extGetTreeList($row['uid'], $depth - 1, $begin - 1, $perms_clause);
264 }
265 }
266 }
267 return $theList;
268 }
269
270 /*****************************************************
271 *
272 * Localization handling
273 *
274 ****************************************************/
275 /**
276 * Returns the label for key. If a translation for the language set in $this->uc['lang']
277 * is found that is returned, otherwise the default value.
278 * If the global variable $LOCAL_LANG is NOT an array (yet) then this function loads
279 * the global $LOCAL_LANG array with the content of "EXT:lang/Resources/Private/Language/locallang_tsfe.xlf"
280 * such that the values therein can be used for labels in the Admin Panel
281 *
282 * @param string $key Key for a label in the $GLOBALS['LOCAL_LANG'] array of "EXT:lang/Resources/Private/Language/locallang_tsfe.xlf
283 * @return string The value for the $key
284 */
285 public function extGetLL($key)
286 {
287 if (!is_array($GLOBALS['LOCAL_LANG'])) {
288 $this->getLanguageService()->includeLLFile('EXT:lang/Resources/Private/Language/locallang_tsfe.xlf');
289 if (!is_array($GLOBALS['LOCAL_LANG'])) {
290 $GLOBALS['LOCAL_LANG'] = [];
291 }
292 }
293 return htmlspecialchars($this->getLanguageService()->getLL($key));
294 }
295
296 /**
297 * @return LanguageService
298 */
299 protected function getLanguageService()
300 {
301 return $GLOBALS['LANG'];
302 }
303 }