‪TYPO3CMS  9.5
BackendUserAuthentication.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 
36 
45 {
47 
48  public const ‪ROLE_SYSTEMMAINTAINER = 'systemMaintainer';
49 
55  protected ‪$deprecatedPublicProperties = [
56  'TSdataArray' => 'Using $TSdataArray of class BackendUserAuthentication from the outside is discouraged. This property is for class internal use only.',
57  'userTS' => 'Using $userTS of class BackendUserAuthentication from the outside is discouraged. Use getTSConfig() instead.',
58  'userTSUpdated' => 'Using $userTSUpdated of class BackendUserAuthentication from the outside is discouraged. This property is for class internal use only.',
59  'userTS_text' => 'Using $userTS_text of class BackendUserAuthentication from the outside is discouraged. This property is for class internal use only.',
60  'userTS_dontGetCached' => 'Using $userTS_dontGetCached of class BackendUserAuthentication is deprecated. The property will be removed in TYPO3 v10.0.',
61  'checkWorkspaceCurrent_cache' => 'Using $checkWorkspaceCurrent_cache of class BackendUserAuthentication is marked as internal, as its sole purpose is a runtime cache for internal calls.',
62  ];
63 
68  public ‪$usergroup_column = 'usergroup';
69 
74  public ‪$usergroup_table = 'be_groups';
75 
81  public ‪$groupData = [
82  'filemounts' => []
83  ];
84 
89  public ‪$userGroups = [];
90 
95  public ‪$userGroupsUID = [];
96 
101  public ‪$groupList = '';
102 
110  public ‪$workspace = -99;
111 
116  public ‪$workspaceRec = [];
117 
125  public ‪$dataLists = [
126  'webmount_list' => '',
127  'filemount_list' => '',
128  'file_permissions' => '',
129  'modList' => '',
130  'tables_select' => '',
131  'tables_modify' => '',
132  'pagetypes_select' => '',
133  'non_exclude_fields' => '',
134  'explicit_allowdeny' => '',
135  'allowed_languages' => '',
136  'workspace_perms' => '',
137  'custom_options' => ''
138  ];
139 
145 
149  protected ‪$TSdataArray = [];
150 
154  protected ‪$userTS_text = '';
155 
159  protected ‪$userTS = [];
160 
164  protected ‪$userTSUpdated = false;
165 
170  protected ‪$userTS_dontGetCached = false;
171 
176  public ‪$errorMsg = '';
177 
183 
187  protected ‪$fileStorages;
188 
192  protected ‪$filePermissions;
193 
198  public ‪$user_table = 'be_users';
199 
204  public ‪$username_column = 'username';
205 
210  public ‪$userident_column = 'password';
211 
216  public ‪$userid_column = 'uid';
217 
221  public ‪$lastLogin_column = 'lastlogin';
222 
226  public ‪$enablecolumns = [
227  'rootLevel' => 1,
228  'deleted' => 'deleted',
229  'disabled' => 'disable',
230  'starttime' => 'starttime',
231  'endtime' => 'endtime'
232  ];
233 
238  public ‪$formfield_uname = 'username';
239 
244  public ‪$formfield_uident = 'userident';
245 
250  public ‪$formfield_status = 'login_status';
251 
256  public ‪$writeStdLog = true;
257 
262  public ‪$writeAttemptLog = true;
263 
273  public ‪$sessionTimeout = 28800;
274 
278  public ‪$firstMainGroup = 0;
279 
284  public ‪$uc;
285 
295  public ‪$uc_default = [
296  'interfaceSetup' => '',
297  // serialized content that is used to store interface pane and menu positions. Set by the logout.php-script
298  'moduleData' => [],
299  // user-data for the modules
300  'thumbnailsByDefault' => 1,
301  'emailMeAtLogin' => 0,
302  'startModule' => 'help_AboutAbout',
303  'titleLen' => 50,
304  'edit_RTE' => '1',
305  'edit_docModuleUpload' => '1',
306  'resizeTextareas' => 1,
307  'resizeTextareas_MaxHeight' => 500,
308  'resizeTextareas_Flexible' => 0
309  ];
310 
314  public function ‪__construct()
315  {
316  parent::__construct();
317  $this->name = ‪self::getCookieName();
318  $this->loginType = 'BE';
319  $this->warningEmail = ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
320  $this->lockIP = ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['lockIP'];
321  $this->sessionTimeout = (int)‪$GLOBALS['TYPO3_CONF_VARS']['BE']['sessionTimeout'];
322  }
323 
330  public function ‪isAdmin()
331  {
332  return is_array($this->user) && ($this->user['admin'] & 1) == 1;
333  }
334 
343  public function ‪isMemberOfGroup($groupId)
344  {
345  $groupId = (int)$groupId;
346  if ($this->groupList && $groupId) {
347  return GeneralUtility::inList($this->groupList, $groupId);
348  }
349  return false;
350  }
351 
367  public function ‪doesUserHaveAccess($row, $perms)
368  {
369  $userPerms = $this->‪calcPerms($row);
370  return ($userPerms & $perms) == $perms;
371  }
372 
389  public function ‪isInWebMount($idOrRow, $readPerms = '', $exitOnError = 0)
390  {
391  if (!‪$GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts'] || $this->‪isAdmin()) {
392  return 1;
393  }
394  $fetchPageFromDatabase = true;
395  if (is_array($idOrRow)) {
396  if (empty($idOrRow['uid'])) {
397  throw new \RuntimeException('The given page record is invalid. Missing uid.', 1578950324);
398  }
399  $checkRec = $idOrRow;
400  ‪$id = (int)$idOrRow['uid'];
401  // ensure the required fields are present on the record
402  if (isset($checkRec['pid'], $checkRec['t3ver_oid'], $checkRec[‪$GLOBALS['TCA']['pages']['ctrl']['languageField']], $checkRec[‪$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField']])) {
403  $fetchPageFromDatabase = false;
404  }
405  } else {
406  ‪$id = (int)$idOrRow;
407  }
408  if ($fetchPageFromDatabase) {
409  // Check if input id is an offline version page in which case we will map id to the online version:
410  $checkRec = ‪BackendUtility::getRecord(
411  'pages',
412  ‪$id,
413  'pid,t3ver_oid,'
414  . ‪$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'] . ','
415  . ‪$GLOBALS['TCA']['pages']['ctrl']['languageField']
416  );
417  }
418  if ($checkRec['pid'] == -1) {
419  ‪$id = (int)$checkRec['t3ver_oid'];
420  }
421  // if current rec is a translation then get uid from l10n_parent instead
422  // because web mounts point to pages in default language and rootline returns uids of default languages
423  if ((int)$checkRec[‪$GLOBALS['TCA']['pages']['ctrl']['languageField']] !== 0 && (int)$checkRec[‪$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField']] !== 0) {
424  ‪$id = (int)$checkRec[‪$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField']];
425  }
426  if (!$readPerms) {
427  $readPerms = $this->‪getPagePermsClause(‪Permission::PAGE_SHOW);
428  }
429  if (‪$id > 0) {
430  $wM = $this->‪returnWebmounts();
431  $rL = ‪BackendUtility::BEgetRootLine(‪$id, ' AND ' . $readPerms, true);
432  foreach ($rL as $v) {
433  if ($v['uid'] && in_array($v['uid'], $wM)) {
434  return $v['uid'];
435  }
436  }
437  }
438  if ($exitOnError) {
439  throw new \RuntimeException('Access Error: This page is not within your DB-mounts', 1294586445);
440  }
441  return null;
442  }
443 
452  public function ‪modAccess($conf, $exitOnError = null)
453  {
454  if ($exitOnError !== null) {
455  trigger_error('Calling BackendUserAuthentication->modAccess() with a second argument is deprecated, as the default behaviour is throwing exceptions, which might get customized in TYPO3 v10.0. Remove the second argument within modAccess() to avoid the deprecation, and ensure to catch the Exception in the callers code.', E_USER_DEPRECATED);
456  } else {
457  // new default behaviour (true by default when no second parameter given)
458  $exitOnError = true;
459  }
460  if (!‪BackendUtility::isModuleSetInTBE_MODULES($conf['name'])) {
461  if ($exitOnError) {
462  throw new \RuntimeException('Fatal Error: This module "' . $conf['name'] . '" is not enabled in TBE_MODULES', 1294586446);
463  }
464  return false;
465  }
466  // Workspaces check:
467  if (
468  !empty($conf['workspaces'])
470  && ($this->workspace !== 0 || !GeneralUtility::inList($conf['workspaces'], 'online'))
471  && ($this->workspace !== -1 || !GeneralUtility::inList($conf['workspaces'], 'offline'))
472  && ($this->workspace <= 0 || !GeneralUtility::inList($conf['workspaces'], 'custom'))
473  ) {
474  if ($exitOnError) {
475  throw new \RuntimeException('Workspace Error: This module "' . $conf['name'] . '" is not available under the current workspace', 1294586447);
476  }
477  return false;
478  }
479  // Returns false if conf[access] is set to system maintainers and the user is system maintainer
480  if (strpos($conf['access'], self::ROLE_SYSTEMMAINTAINER) !== false && !$this->‪isSystemMaintainer()) {
481  if ($exitOnError) {
482  throw new \RuntimeException('This module "' . $conf['name'] . '" is only available as system maintainer', 1504804727);
483  }
484  return false;
485  }
486  // Returns TRUE if conf[access] is not set at all or if the user is admin
487  if (!$conf['access'] || $this->‪isAdmin()) {
488  return true;
489  }
490  // If $conf['access'] is set but not with 'admin' then we return TRUE, if the module is found in the modList
491  $acs = false;
492  if (!strstr($conf['access'], 'admin') && $conf['name']) {
493  $acs = $this->‪check('modules', $conf['name']);
494  }
495  if (!$acs && $exitOnError) {
496  throw new \RuntimeException('Access Error: You don\'t have access to this module.', 1294586448);
497  }
498  return $acs;
499  }
500 
508  public function ‪isSystemMaintainer(): bool
509  {
510  if (!$this->‪isAdmin()) {
511  return false;
512  }
513 
514  if ((int)‪$GLOBALS['BE_USER']->user['ses_backuserid'] !== 0) {
515  return false;
516  }
517  if (GeneralUtility::getApplicationContext()->isDevelopment()) {
518  return true;
519  }
520  $systemMaintainers = ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers'] ?? [];
521  $systemMaintainers = array_map('intval', $systemMaintainers);
522  if (!empty($systemMaintainers)) {
523  return in_array((int)$this->user['uid'], $systemMaintainers, true);
524  }
525  // No system maintainers set up yet, so any admin is allowed to access the modules
526  // but explicitly no system maintainers allowed (empty string in TYPO3_CONF_VARS).
527  // @todo: this needs to be adjusted once system maintainers can log into the install tool with their credentials
528  if (isset(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers'])
529  && empty(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers'])) {
530  return false;
531  }
532  return true;
533  }
534 
539  protected function ‪getRealUserId(): int
540  {
541  return (int)(‪$GLOBALS['BE_USER']->user['ses_backuserid'] ?: $this->user['uid']);
542  }
543 
559  public function ‪getPagePermsClause($perms)
560  {
561  if (is_array($this->user)) {
562  if ($this->‪isAdmin()) {
563  return ' 1=1';
564  }
565  // Make sure it's integer.
566  $perms = (int)$perms;
567  $expressionBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
568  ->getQueryBuilderForTable('pages')
569  ->expr();
570 
571  // User
572  $constraint = $expressionBuilder->orX(
573  $expressionBuilder->comparison(
574  $expressionBuilder->bitAnd('pages.perms_everybody', $perms),
576  $perms
577  ),
578  $expressionBuilder->andX(
579  $expressionBuilder->eq('pages.perms_userid', (int)$this->user['uid']),
580  $expressionBuilder->comparison(
581  $expressionBuilder->bitAnd('pages.perms_user', $perms),
583  $perms
584  )
585  )
586  );
587 
588  // Group (if any is set)
589  if ($this->groupList) {
590  $constraint->add(
591  $expressionBuilder->andX(
592  $expressionBuilder->in(
593  'pages.perms_groupid',
594  GeneralUtility::intExplode(',', $this->groupList)
595  ),
596  $expressionBuilder->comparison(
597  $expressionBuilder->bitAnd('pages.perms_group', $perms),
599  $perms
600  )
601  )
602  );
603  }
604 
605  $constraint = ' (' . (string)$constraint . ')';
606 
607  // ****************
608  // getPagePermsClause-HOOK
609  // ****************
610  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['getPagePermsClause'] ?? [] as $_funcRef) {
611  $_params = ['currentClause' => $constraint, 'perms' => $perms];
612  $constraint = GeneralUtility::callUserFunction($_funcRef, $_params, $this);
613  }
614  return $constraint;
615  }
616  return ' 1=0';
617  }
618 
628  public function ‪calcPerms($row)
629  {
630  // Return 31 for admin users.
631  if ($this->‪isAdmin()) {
632  return ‪Permission::ALL;
633  }
634  // Return 0 if page is not within the allowed web mount
635  if (!$this->‪isInWebMount($row)) {
636  return ‪Permission::NOTHING;
637  }
638  $out = ‪Permission::NOTHING;
639  if (
640  isset($row['perms_userid']) && isset($row['perms_user']) && isset($row['perms_groupid'])
641  && isset($row['perms_group']) && isset($row['perms_everybody']) && isset($this->groupList)
642  ) {
643  if ($this->user['uid'] == $row['perms_userid']) {
644  $out |= $row['perms_user'];
645  }
646  if ($this->‪isMemberOfGroup($row['perms_groupid'])) {
647  $out |= $row['perms_group'];
648  }
649  $out |= $row['perms_everybody'];
650  }
651  // ****************
652  // CALCPERMS hook
653  // ****************
654  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['calcPerms'] ?? [] as $_funcRef) {
655  $_params = [
656  'row' => $row,
657  'outputPermissions' => $out
658  ];
659  $out = GeneralUtility::callUserFunction($_funcRef, $_params, $this);
660  }
661  return $out;
662  }
663 
669  public function ‪isRTE()
670  {
671  return (bool)$this->uc['edit_RTE'];
672  }
673 
684  public function ‪check($type, $value)
685  {
686  return isset($this->groupData[$type])
687  && ($this->‪isAdmin() || GeneralUtility::inList($this->groupData[$type], $value));
688  }
689 
699  public function ‪checkAuthMode($table, $field, $value, $authMode)
700  {
701  // Admin users can do anything:
702  if ($this->‪isAdmin()) {
703  return true;
704  }
705  // Allow all blank values:
706  if ((string)$value === '') {
707  return true;
708  }
709  // Allow dividers:
710  if ($value === '--div--') {
711  return true;
712  }
713  // Certain characters are not allowed in the value
714  if (preg_match('/[:|,]/', $value)) {
715  return false;
716  }
717  // Initialize:
718  $testValue = $table . ':' . $field . ':' . $value;
719  $out = true;
720  // Checking value:
721  switch ((string)$authMode) {
722  case 'explicitAllow':
723  if (!GeneralUtility::inList($this->groupData['explicit_allowdeny'], $testValue . ':ALLOW')) {
724  $out = false;
725  }
726  break;
727  case 'explicitDeny':
728  if (GeneralUtility::inList($this->groupData['explicit_allowdeny'], $testValue . ':DENY')) {
729  $out = false;
730  }
731  break;
732  case 'individual':
733  if (is_array(‪$GLOBALS['TCA'][$table]) && is_array(‪$GLOBALS['TCA'][$table]['columns'][$field])) {
734  $items = ‪$GLOBALS['TCA'][$table]['columns'][$field]['config']['items'];
735  if (is_array($items)) {
736  foreach ($items as $iCfg) {
737  if ((string)$iCfg[1] === (string)$value && $iCfg[4]) {
738  switch ((string)$iCfg[4]) {
739  case 'EXPL_ALLOW':
740  if (!GeneralUtility::inList(
741  $this->groupData['explicit_allowdeny'],
742  $testValue . ':ALLOW'
743  )) {
744  $out = false;
745  }
746  break;
747  case 'EXPL_DENY':
748  if (GeneralUtility::inList($this->groupData['explicit_allowdeny'], $testValue . ':DENY')) {
749  $out = false;
750  }
751  break;
752  }
753  break;
754  }
755  }
756  }
757  }
758  break;
759  }
760  return $out;
761  }
762 
769  public function ‪checkLanguageAccess($langValue)
770  {
771  // The users language list must be non-blank - otherwise all languages are allowed.
772  if (trim($this->groupData['allowed_languages']) !== '') {
773  $langValue = (int)$langValue;
774  // Language must either be explicitly allowed OR the lang Value be "-1" (all languages)
775  if ($langValue != -1 && !$this->‪check('allowed_languages', $langValue)) {
776  return false;
777  }
778  }
779  return true;
780  }
781 
789  public function ‪checkFullLanguagesAccess($table, $record)
790  {
791  if (!$this->‪checkLanguageAccess(0)) {
792  return false;
793  }
794 
796  $pointerField = ‪$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'];
797  $pointerValue = $record[$pointerField] > 0 ? $record[$pointerField] : $record['uid'];
798  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
799  $queryBuilder->getRestrictions()
800  ->removeAll()
801  ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
802  ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
803  $recordLocalizations = $queryBuilder->select('*')
804  ->from($table)
805  ->where(
806  $queryBuilder->expr()->eq(
807  $pointerField,
808  $queryBuilder->createNamedParameter($pointerValue, \PDO::PARAM_INT)
809  )
810  )
811  ->execute()
812  ->fetchAll();
813 
814  foreach ($recordLocalizations as $recordLocalization) {
815  if (!$this->‪checkLanguageAccess($recordLocalization[‪$GLOBALS['TCA'][$table]['ctrl']['languageField']])) {
816  return false;
817  }
818  }
819  }
820  return true;
821  }
822 
838  public function ‪recordEditAccessInternals($table, $idOrRow, $newRecord = false, $deletedRecord = false, $checkFullLanguageAccess = false)
839  {
840  if (!isset(‪$GLOBALS['TCA'][$table])) {
841  return false;
842  }
843  // Always return TRUE for Admin users.
844  if ($this->‪isAdmin()) {
845  return true;
846  }
847  // Fetching the record if the $idOrRow variable was not an array on input:
848  if (!is_array($idOrRow)) {
849  if ($deletedRecord) {
850  $idOrRow = ‪BackendUtility::getRecord($table, $idOrRow, '*', '', false);
851  } else {
852  $idOrRow = ‪BackendUtility::getRecord($table, $idOrRow);
853  }
854  if (!is_array($idOrRow)) {
855  $this->errorMsg = 'ERROR: Record could not be fetched.';
856  return false;
857  }
858  }
859  // Checking languages:
860  if ($table === 'pages' && $checkFullLanguageAccess && !$this->‪checkFullLanguagesAccess($table, $idOrRow)) {
861  return false;
862  }
863  if (‪$GLOBALS['TCA'][$table]['ctrl']['languageField']) {
864  // Language field must be found in input row - otherwise it does not make sense.
865  if (isset($idOrRow[‪$GLOBALS['TCA'][$table]['ctrl']['languageField']])) {
866  if (!$this->‪checkLanguageAccess($idOrRow[‪$GLOBALS['TCA'][$table]['ctrl']['languageField']])) {
867  $this->errorMsg = 'ERROR: Language was not allowed.';
868  return false;
869  }
870  if (
871  $checkFullLanguageAccess && $idOrRow[‪$GLOBALS['TCA'][$table]['ctrl']['languageField']] == 0
872  && !$this->‪checkFullLanguagesAccess($table, $idOrRow)
873  ) {
874  $this->errorMsg = 'ERROR: Related/affected language was not allowed.';
875  return false;
876  }
877  } else {
878  $this->errorMsg = 'ERROR: The "languageField" field named "'
879  . ‪$GLOBALS['TCA'][$table]['ctrl']['languageField'] . '" was not found in testing record!';
880  return false;
881  }
882  }
883  // Checking authMode fields:
884  if (is_array(‪$GLOBALS['TCA'][$table]['columns'])) {
885  foreach (‪$GLOBALS['TCA'][$table]['columns'] as $fieldName => $fieldValue) {
886  if (isset($idOrRow[$fieldName])) {
887  if (
888  $fieldValue['config']['type'] === 'select' && $fieldValue['config']['authMode']
889  && $fieldValue['config']['authMode_enforce'] === 'strict'
890  ) {
891  if (!$this->‪checkAuthMode($table, $fieldName, $idOrRow[$fieldName], $fieldValue['config']['authMode'])) {
892  $this->errorMsg = 'ERROR: authMode "' . $fieldValue['config']['authMode']
893  . '" failed for field "' . $fieldName . '" with value "'
894  . $idOrRow[$fieldName] . '" evaluated';
895  return false;
896  }
897  }
898  }
899  }
900  }
901  // Checking "editlock" feature (doesn't apply to new records)
902  if (!$newRecord && ‪$GLOBALS['TCA'][$table]['ctrl']['editlock']) {
903  if (isset($idOrRow[‪$GLOBALS['TCA'][$table]['ctrl']['editlock']])) {
904  if ($idOrRow[‪$GLOBALS['TCA'][$table]['ctrl']['editlock']]) {
905  $this->errorMsg = 'ERROR: Record was locked for editing. Only admin users can change this state.';
906  return false;
907  }
908  } else {
909  $this->errorMsg = 'ERROR: The "editLock" field named "' . ‪$GLOBALS['TCA'][$table]['ctrl']['editlock']
910  . '" was not found in testing record!';
911  return false;
912  }
913  }
914  // Checking record permissions
915  // THIS is where we can include a check for "perms_" fields for other records than pages...
916  // Process any hooks
917  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['recordEditAccessInternals'] ?? [] as $funcRef) {
918  $params = [
919  'table' => $table,
920  'idOrRow' => $idOrRow,
921  'newRecord' => $newRecord
922  ];
923  if (!GeneralUtility::callUserFunction($funcRef, $params, $this)) {
924  return false;
925  }
926  }
927  // Finally, return TRUE if all is well.
928  return true;
929  }
930 
941  public function ‪isPSet($compiledPermissions, $tableName, $actionType = '')
942  {
943  trigger_error('BackendUserAuthentication->isPSet() will be removed in TYPO3 v10.0. Use doesUserHaveAccess() and calcPerms().', E_USER_DEPRECATED);
944  if ($this->‪isAdmin()) {
945  $result = true;
946  } elseif ($tableName === 'pages') {
947  switch ($actionType) {
948  case 'edit':
949  $result = ($compiledPermissions & ‪Permission::PAGE_EDIT) !== 0;
950  break;
951  case 'new':
952  // Create new page OR page content
953  $result = ($compiledPermissions & ‪Permission::PAGE_NEW + ‪Permission::CONTENT_EDIT) !== 0;
954  break;
955  case 'delete':
956  $result = ($compiledPermissions & ‪Permission::PAGE_DELETE) !== 0;
957  break;
958  case 'editcontent':
959  $result = ($compiledPermissions & ‪Permission::CONTENT_EDIT) !== 0;
960  break;
961  default:
962  $result = false;
963  }
964  } else {
965  $result = ($compiledPermissions & ‪Permission::CONTENT_EDIT) !== 0;
966  }
967  return $result;
968  }
969 
975  public function ‪mayMakeShortcut()
976  {
977  return ($this->‪getTSConfig()['options.']['enableBookmarks'] ?? false)
978  && !($this->‪getTSConfig()['options.']['mayNotCreateEditBookmarks'] ?? false);
979  }
980 
992  public function ‪workspaceCannotEditRecord($table, $recData)
993  {
994  // Only test offline spaces:
995  if ($this->workspace !== 0) {
996  if (!is_array($recData)) {
997  $recData = ‪BackendUtility::getRecord(
998  $table,
999  $recData,
1000  'pid' . (‪$GLOBALS['TCA'][$table]['ctrl']['versioningWS'] ? ',t3ver_wsid,t3ver_stage' : '')
1001  );
1002  }
1003  if (is_array($recData)) {
1004  // We are testing a "version" (identified by a pid of -1): it can be edited provided
1005  // that workspace matches and versioning is enabled for the table.
1006  if ((int)$recData['pid'] === -1) {
1007  // No versioning, basic error, inconsistency even! Such records should not have a pid of -1!
1008  if (!‪$GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
1009  return 'Versioning disabled for table';
1010  }
1011  if ((int)$recData['t3ver_wsid'] !== $this->workspace) {
1012  // So does workspace match?
1013  return 'Workspace ID of record didn\'t match current workspace';
1014  }
1015  // So is the user allowed to "use" the edit stage within the workspace?
1016  return $this->‪workspaceCheckStageForCurrent(0)
1017  ? false
1018  : 'User\'s access level did not allow for editing';
1019  }
1020  // We are testing a "live" record:
1021  // For "Live" records, check that PID for table allows editing
1022  if ($res = $this->‪workspaceAllowLiveRecordsInPID($recData['pid'], $table)) {
1023  // Live records are OK in this branch, but what about the stage of branch point, if any:
1024  // OK
1025  return $res > 0
1026  ? false
1027  : 'Stage for versioning root point and users access level did not allow for editing';
1028  }
1029  // If not offline and not in versionized branch, output error:
1030  return 'Online record was not in versionized branch!';
1031  }
1032  return 'No record';
1033  }
1034  // OK because workspace is 0
1035  return false;
1036  }
1037 
1047  public function ‪workspaceCannotEditOfflineVersion($table, $recData)
1048  {
1049  if (‪$GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
1050  if (!is_array($recData)) {
1051  $recData = ‪BackendUtility::getRecord($table, $recData, 'uid,pid,t3ver_wsid,t3ver_stage');
1052  }
1053  if (is_array($recData)) {
1054  if ((int)$recData['pid'] === -1) {
1055  return $this->‪workspaceCannotEditRecord($table, $recData);
1056  }
1057  return 'Not an offline version';
1058  }
1059  return 'No record';
1060  }
1061  return 'Table does not support versioning.';
1062  }
1063 
1075  public function ‪workspaceAllowLiveRecordsInPID($pid, $table)
1076  {
1077  // Always for Live workspace AND if live-edit is enabled
1078  // and tables are completely without versioning it is ok as well.
1079  if (
1080  $this->workspace === 0
1081  || $this->workspaceRec['live_edit'] && !‪$GLOBALS['TCA'][$table]['ctrl']['versioningWS']
1082  || ‪$GLOBALS['TCA'][$table]['ctrl']['versioningWS_alwaysAllowLiveEdit']
1083  ) {
1084  // OK to create for this table.
1085  return 2;
1086  }
1087  // If the answer is FALSE it means the only valid way to create or edit records in the PID is by versioning
1088  return false;
1089  }
1090 
1098  public function ‪workspaceCreateNewRecord($pid, $table)
1099  {
1100  if ($res = $this->‪workspaceAllowLiveRecordsInPID($pid, $table)) {
1101  // If LIVE records cannot be created in the current PID due to workspace restrictions, prepare creation of placeholder-record
1102  if ($res < 0) {
1103  // Stage for versioning root point and users access level did not allow for editing
1104  return false;
1105  }
1106  } elseif (!‪$GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
1107  // So, if no live records were allowed, we have to create a new version of this record:
1108  return false;
1109  }
1110  return true;
1111  }
1112 
1121  public function ‪workspaceAllowAutoCreation($table, ‪$id, $recpid)
1122  {
1123  // Auto-creation of version: In offline workspace, test if versioning is
1124  // enabled and look for workspace version of input record.
1125  // If there is no versionized record found we will create one and save to that.
1126  if (
1127  $this->workspace !== 0
1128  && ‪$GLOBALS['TCA'][$table]['ctrl']['versioningWS'] && $recpid >= 0
1129  && !‪BackendUtility::getWorkspaceVersionOfRecord($this->workspace, $table, ‪$id, 'uid')
1130  ) {
1131  // There must be no existing version of this record in workspace.
1132  return true;
1133  }
1134  return false;
1135  }
1136 
1146  public function ‪workspaceCheckStageForCurrent($stage)
1147  {
1148  // Always allow for admins
1149  if ($this->‪isAdmin()) {
1150  return true;
1151  }
1152  if ($this->workspace !== 0 && ‪ExtensionManagementUtility::isLoaded('workspaces')) {
1153  $stage = (int)$stage;
1154  $stat = $this->‪checkWorkspaceCurrent();
1155  // Check if custom staging is activated
1156  ‪$workspaceRec = ‪BackendUtility::getRecord('sys_workspace', $stat['uid']);
1157  if (‪$workspaceRec['custom_stages'] > 0 && $stage !== 0 && $stage !== -10) {
1158  // Get custom stage record
1159  $workspaceStageRec = ‪BackendUtility::getRecord('sys_workspace_stage', $stage);
1160  // Check if the user is responsible for the current stage
1161  if (
1162  $stat['_ACCESS'] === 'owner'
1163  || $stat['_ACCESS'] === 'member'
1164  && GeneralUtility::inList($workspaceStageRec['responsible_persons'], 'be_users_' . $this->user['uid'])
1165  ) {
1166  return true;
1167  }
1168  // Check if the user is in a group which is responsible for the current stage
1169  foreach ($this->userGroupsUID as $groupUid) {
1170  if (
1171  $stat['_ACCESS'] === 'owner'
1172  || $stat['_ACCESS'] === 'member'
1173  && GeneralUtility::inList($workspaceStageRec['responsible_persons'], 'be_groups_' . $groupUid)
1174  ) {
1175  return true;
1176  }
1177  }
1178  } elseif ($stage == -10 || $stage == -20) {
1179  if ($stat['_ACCESS'] === 'owner') {
1180  return true;
1181  }
1182  return false;
1183  } else {
1184  $memberStageLimit = $this->workspaceRec['review_stage_edit'] ? 1 : 0;
1185  if (
1186  $stat['_ACCESS'] === 'owner'
1187  || $stat['_ACCESS'] === 'reviewer' && $stage <= 1
1188  || $stat['_ACCESS'] === 'member' && $stage <= $memberStageLimit
1189  ) {
1190  return true;
1191  }
1192  }
1193  } else {
1194  // Always OK for live workspace.
1195  return true;
1196  }
1197  return false;
1198  }
1199 
1211  public function ‪workspacePublishAccess($wsid)
1212  {
1213  if ($this->‪isAdmin()) {
1214  return true;
1215  }
1216  // If no access to workspace, of course you cannot publish!
1217  $retVal = false;
1218  $wsAccess = $this->‪checkWorkspace($wsid);
1219  if ($wsAccess) {
1220  switch ($wsAccess['uid']) {
1221  case 0:
1222  // Live workspace
1223  // If access to Live workspace, no problem.
1224  $retVal = true;
1225  break;
1226  default:
1227  // Custom workspace
1228  $retVal = $wsAccess['_ACCESS'] === 'owner' || $this->‪checkWorkspace(0) && !($wsAccess['publish_access'] & ‪Permission::PAGE_EDIT);
1229  // Either be an adminuser OR have access to online
1230  // workspace which is OK as well as long as publishing
1231  // access is not limited by workspace option.
1232  }
1233  }
1234  return $retVal;
1235  }
1236 
1243  public function ‪workspaceSwapAccess()
1244  {
1245  if ($this->workspace > 0 && (int)$this->workspaceRec['swap_modes'] === 2) {
1246  return false;
1247  }
1248  return true;
1249  }
1250 
1268  public function ‪getTSConfig($objectString = null, $config = null)
1269  {
1270  if ($objectString === null && $config === null) {
1271  return ‪$this->userTS;
1272  }
1273 
1274  trigger_error('Handing over arguments to BackendUserAuthentication->getTSConfig() will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
1275 
1276  if (!is_array($config)) {
1277  // Getting Root-ts if not sent
1278  $config = ‪$this->userTS;
1279  }
1280  $TSConf = ['value' => null, 'properties' => null];
1281  $parts = GeneralUtility::trimExplode('.', $objectString, true, 2);
1282  $key = $parts[0];
1283  if ($key !== '') {
1284  if (count($parts) > 1 && $parts[1] !== '') {
1285  // Go on, get the next level
1286  if (is_array($config[$key . '.'] ?? false)) {
1287  $TSConf = $this->‪getTSConfig($parts[1], $config[$key . '.']);
1288  }
1289  } else {
1290  $TSConf['value'] = $config[$key] ?? null;
1291  $TSConf['properties'] = $config[$key . '.'] ?? null;
1292  }
1293  }
1294  return $TSConf;
1295  }
1296 
1305  public function ‪getTSConfigVal($objectString)
1306  {
1307  trigger_error('BackendUserAuthentication->getTSConfigVal() will be removed in TYPO3 v10.0. Use getTSConfig() instead.', E_USER_DEPRECATED);
1308  $TSConf = $this->‪getTSConfig($objectString);
1309  return $TSConf['value'];
1310  }
1311 
1320  public function ‪getTSConfigProp($objectString)
1321  {
1322  trigger_error('BackendUserAuthentication->getTSConfigProp() will be removed in TYPO3 v10.0. Use getTSConfig() instead.', E_USER_DEPRECATED);
1323  $TSConf = $this->‪getTSConfig($objectString);
1324  return $TSConf['properties'];
1325  }
1326 
1334  public function ‪returnWebmounts()
1335  {
1336  return (string)$this->groupData['webmounts'] != '' ? explode(',', $this->groupData['webmounts']) : [];
1337  }
1338 
1345  public function ‪setWebmounts(array $mountPointUids, $append = false)
1346  {
1347  if (empty($mountPointUids)) {
1348  return;
1349  }
1350  if ($append) {
1351  $currentWebMounts = GeneralUtility::intExplode(',', $this->groupData['webmounts']);
1352  $mountPointUids = array_merge($currentWebMounts, $mountPointUids);
1353  }
1354  $this->groupData['webmounts'] = implode(',', array_unique($mountPointUids));
1355  }
1356 
1368  public function ‪initializeWebmountsForElementBrowser()
1369  {
1370  $alternativeWebmountPoint = (int)$this->‪getSessionData('pageTree_temporaryMountPoint');
1371  if ($alternativeWebmountPoint) {
1372  $alternativeWebmountPoint = GeneralUtility::intExplode(',', $alternativeWebmountPoint);
1373  $this->‪setWebmounts($alternativeWebmountPoint);
1374  return;
1375  }
1376 
1377  $alternativeWebmountPoints = trim($this->‪getTSConfig()['options.']['pageTree.']['altElementBrowserMountPoints'] ?? '');
1378  $appendAlternativeWebmountPoints = $this->‪getTSConfig()['options.']['pageTree.']['altElementBrowserMountPoints.']['append'] ?? '';
1379  if ($alternativeWebmountPoints) {
1380  $alternativeWebmountPoints = GeneralUtility::intExplode(',', $alternativeWebmountPoints);
1381  $this->‪setWebmounts($alternativeWebmountPoints, $appendAlternativeWebmountPoints);
1382  }
1383  }
1384 
1393  public function ‪jsConfirmation($bitmask)
1394  {
1395  try {
1396  $alertPopupsSetting = trim((string)($this->‪getTSConfig()['options.']['alertPopups'] ?? ''));
1397  $alertPopup = ‪JsConfirmation::cast($alertPopupsSetting === '' ? null : (int)$alertPopupsSetting);
1398  } catch (InvalidEnumerationValueException $e) {
1399  $alertPopup = new JsConfirmation();
1400  }
1401 
1402  return ‪JsConfirmation::cast($bitmask)->matches($alertPopup);
1403  }
1404 
1414  public function ‪fetchGroupData()
1415  {
1416  if ($this->user['uid']) {
1417  // Get lists for the be_user record and set them as default/primary values.
1418  // Enabled Backend Modules
1419  $this->dataLists['modList'] = $this->user['userMods'];
1420  // Add Allowed Languages
1421  $this->dataLists['allowed_languages'] = $this->user['allowed_languages'];
1422  // Set user value for workspace permissions.
1423  $this->dataLists['workspace_perms'] = $this->user['workspace_perms'];
1424  // Database mountpoints
1425  $this->dataLists['webmount_list'] = $this->user['db_mountpoints'];
1426  // File mountpoints
1427  $this->dataLists['filemount_list'] = $this->user['file_mountpoints'];
1428  // Fileoperation permissions
1429  $this->dataLists['file_permissions'] = $this->user['file_permissions'];
1430  // Setting default User TSconfig:
1431  $this->TSdataArray[] = ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'];
1432  // Default TSconfig for admin-users
1433  if ($this->‪isAdmin()) {
1434  $this->TSdataArray[] = 'admPanel.enable.all = 1';
1435  if (‪ExtensionManagementUtility::isLoaded('sys_note')) {
1436  $this->TSdataArray[] = '
1437  // Setting defaults for sys_note author / email...
1438  TCAdefaults.sys_note.author = ' . $this->user['realName'] . '
1439  TCAdefaults.sys_note.email = ' . $this->user['email'] . '
1440  ';
1441  }
1442  }
1443  // BE_GROUPS:
1444  // Get the groups...
1445  if (!empty($this->user[$this->usergroup_column])) {
1446  // Fetch groups will add a lot of information to the internal arrays: modules, accesslists, TSconfig etc.
1447  // Refer to fetchGroups() function.
1448  $this->‪fetchGroups($this->user[$this->usergroup_column]);
1449  }
1450 
1451  // Populating the $this->userGroupsUID -array with the groups in the order in which they were LAST included.!!
1452  $this->userGroupsUID = array_reverse(array_unique(array_reverse($this->includeGroupArray)));
1453  // Finally this is the list of group_uid's in the order they are parsed (including subgroups!)
1454  // and without duplicates (duplicates are presented with their last entrance in the list,
1455  // which thus reflects the order of the TypoScript in TSconfig)
1456  $this->groupList = implode(',', $this->userGroupsUID);
1457  $this->‪setCachedList($this->groupList);
1458 
1459  // Add the TSconfig for this specific user:
1460  $this->TSdataArray[] = $this->user['TSconfig'];
1461  // Check include lines.
1463  // Imploding with "[global]" will make sure that non-ended confinements with braces are ignored.
1464  $this->userTS_text = implode(LF . '[GLOBAL]' . LF, $this->TSdataArray);
1465  if (!$this->userTS_dontGetCached) {
1466  // @deprecated: Property userTS_dontGetCached is deprecated since TYPO3 v9 and will be removed in TYPO3 v10.0
1467  // Perform TS-Config parsing with condition matching
1468  $parseObj = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Configuration\TsConfigParser::class);
1469  $res = $parseObj->parseTSconfig($this->userTS_text, 'userTS');
1470  if ($res) {
1471  $this->userTS = $res['TSconfig'];
1472  $this->userTSUpdated = (bool)$res['cached'];
1473  }
1474  } else {
1475  // Parsing the user TSconfig (or getting from cache)
1476  $hash = md5('userTS:' . $this->userTS_text);
1477  $cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_hash');
1478  $cachedContent = $cache->get($hash);
1479  if (is_array($cachedContent) && !$this->userTS_dontGetCached) {
1480  // @deprecated: Property userTS_dontGetCached is deprecated since TYPO3 v9 and will be removed in TYPO3 v10.0
1481  $this->userTS = $cachedContent;
1482  } else {
1483  $parseObj = GeneralUtility::makeInstance(\‪TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser::class);
1484  $parseObj->parse($this->userTS_text);
1485  $this->userTS = $parseObj->setup;
1486  $cache->set($hash, $this->userTS, ['ident_BE_USER_TSconfig'], 0);
1487  // Update UC:
1488  $this->userTSUpdated = true;
1489  }
1490  }
1491  // Processing webmounts
1492  // Admin's always have the root mounted
1493  if ($this->‪isAdmin() && !($this->‪getTSConfig()['options.']['dontMountAdminMounts'] ?? false)) {
1494  $this->dataLists['webmount_list'] = '0,' . $this->dataLists['webmount_list'];
1495  }
1496  // The lists are cleaned for duplicates
1497  $this->groupData['webmounts'] = GeneralUtility::uniqueList($this->dataLists['webmount_list']);
1498  $this->groupData['pagetypes_select'] = GeneralUtility::uniqueList($this->dataLists['pagetypes_select']);
1499  $this->groupData['tables_select'] = GeneralUtility::uniqueList($this->dataLists['tables_modify'] . ',' . $this->dataLists['tables_select']);
1500  $this->groupData['tables_modify'] = GeneralUtility::uniqueList($this->dataLists['tables_modify']);
1501  $this->groupData['non_exclude_fields'] = GeneralUtility::uniqueList($this->dataLists['non_exclude_fields']);
1502  $this->groupData['explicit_allowdeny'] = GeneralUtility::uniqueList($this->dataLists['explicit_allowdeny']);
1503  $this->groupData['allowed_languages'] = GeneralUtility::uniqueList($this->dataLists['allowed_languages']);
1504  $this->groupData['custom_options'] = GeneralUtility::uniqueList($this->dataLists['custom_options']);
1505  $this->groupData['modules'] = GeneralUtility::uniqueList($this->dataLists['modList']);
1506  $this->groupData['file_permissions'] = GeneralUtility::uniqueList($this->dataLists['file_permissions']);
1507  $this->groupData['workspace_perms'] = $this->dataLists['workspace_perms'];
1508 
1509  if (!empty(trim($this->groupData['webmounts']))) {
1510  // Checking read access to web mounts if there are mounts points (not empty string, false or 0)
1511  $webmounts = explode(',', $this->groupData['webmounts']);
1512  // Selecting all web mounts with permission clause for reading
1513  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
1514  $queryBuilder->getRestrictions()
1515  ->removeAll()
1516  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1517 
1518  $MProws = $queryBuilder->select('uid')
1519  ->from('pages')
1520  // @todo DOCTRINE: check how to make getPagePermsClause() portable
1521  ->where(
1523  $queryBuilder->expr()->in(
1524  'uid',
1525  $queryBuilder->createNamedParameter(
1526  GeneralUtility::intExplode(',', $this->groupData['webmounts']),
1527  Connection::PARAM_INT_ARRAY
1528  )
1529  )
1530  )
1531  ->execute()
1532  ->fetchAll();
1533  $MProws = array_column(($MProws ?: []), 'uid', 'uid');
1534  foreach ($webmounts as $idx => $mountPointUid) {
1535  // If the mount ID is NOT found among selected pages, unset it:
1536  if ($mountPointUid > 0 && !isset($MProws[$mountPointUid])) {
1537  unset($webmounts[$idx]);
1538  }
1539  }
1540  // Implode mounts in the end.
1541  $this->groupData['webmounts'] = implode(',', $webmounts);
1542  }
1543  // Setting up workspace situation (after webmounts are processed!):
1544  $this->‪workspaceInit();
1545  }
1546  }
1547 
1556  public function ‪fetchGroups($grList, $idList = '')
1557  {
1558  // Fetching records of the groups in $grList (which are not blocked by lockedToDomain either):
1559  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->usergroup_table);
1560  $expressionBuilder = $queryBuilder->expr();
1561  $constraints = $expressionBuilder->andX(
1562  $expressionBuilder->eq(
1563  'pid',
1564  $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
1565  ),
1566  $expressionBuilder->in(
1567  'uid',
1568  $queryBuilder->createNamedParameter(
1569  GeneralUtility::intExplode(',', $grList),
1570  Connection::PARAM_INT_ARRAY
1571  )
1572  ),
1573  $expressionBuilder->orX(
1574  $expressionBuilder->eq('lockToDomain', $queryBuilder->quote('')),
1575  $expressionBuilder->isNull('lockToDomain'),
1576  $expressionBuilder->eq(
1577  'lockToDomain',
1578  $queryBuilder->createNamedParameter(GeneralUtility::getIndpEnv('HTTP_HOST'), \PDO::PARAM_STR)
1579  )
1580  )
1581  );
1582  // Hook for manipulation of the WHERE sql sentence which controls which BE-groups are included
1583  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['fetchGroupQuery'] ?? [] as $className) {
1584  $hookObj = GeneralUtility::makeInstance($className);
1585  if (method_exists($hookObj, 'fetchGroupQuery_processQuery')) {
1586  $constraints = $hookObj->fetchGroupQuery_processQuery($this, $grList, $idList, (string)$constraints);
1587  }
1588  }
1589  $res = $queryBuilder->select('*')
1590  ->from($this->usergroup_table)
1591  ->where($constraints)
1592  ->execute();
1593  // The userGroups array is filled
1594  while ($row = $res->fetch(\PDO::FETCH_ASSOC)) {
1595  $this->userGroups[$row['uid']] = $row;
1596  }
1597  // Traversing records in the correct order
1598  foreach (explode(',', $grList) as $uid) {
1599  // Get row:
1600  $row = $this->userGroups[$uid];
1601  // Must be an array and $uid should not be in the idList, because then it is somewhere previously in the grouplist
1602  if (is_array($row) && !GeneralUtility::inList($idList, $uid)) {
1603  // Include sub groups
1604  if (trim($row['subgroup'])) {
1605  // Make integer list
1606  $theList = implode(',', GeneralUtility::intExplode(',', $row['subgroup']));
1607  // Call recursively, pass along list of already processed groups so they are not recursed again.
1608  $this->‪fetchGroups($theList, $idList . ',' . $uid);
1609  }
1610  // Add the group uid, current list, TSconfig to the internal arrays.
1611  $this->includeGroupArray[] = $uid;
1612  $this->TSdataArray[] = $row['TSconfig'];
1613  // Mount group database-mounts
1614  if (($this->user['options'] & ‪Permission::PAGE_SHOW) == 1) {
1615  $this->dataLists['webmount_list'] .= ',' . $row['db_mountpoints'];
1616  }
1617  // Mount group file-mounts
1618  if (($this->user['options'] & ‪Permission::PAGE_EDIT) == 2) {
1619  $this->dataLists['filemount_list'] .= ',' . $row['file_mountpoints'];
1620  }
1621  // The lists are made: groupMods, tables_select, tables_modify, pagetypes_select, non_exclude_fields, explicit_allowdeny, allowed_languages, custom_options
1622  $this->dataLists['modList'] .= ',' . $row['groupMods'];
1623  $this->dataLists['tables_select'] .= ',' . $row['tables_select'];
1624  $this->dataLists['tables_modify'] .= ',' . $row['tables_modify'];
1625  $this->dataLists['pagetypes_select'] .= ',' . $row['pagetypes_select'];
1626  $this->dataLists['non_exclude_fields'] .= ',' . $row['non_exclude_fields'];
1627  $this->dataLists['explicit_allowdeny'] .= ',' . $row['explicit_allowdeny'];
1628  $this->dataLists['allowed_languages'] .= ',' . $row['allowed_languages'];
1629  $this->dataLists['custom_options'] .= ',' . $row['custom_options'];
1630  $this->dataLists['file_permissions'] .= ',' . $row['file_permissions'];
1631  // Setting workspace permissions:
1632  $this->dataLists['workspace_perms'] |= $row['workspace_perms'];
1633  // If this function is processing the users OWN group-list (not subgroups) AND
1634  // if the ->firstMainGroup is not set, then the ->firstMainGroup will be set.
1635  if ($idList === '' && !$this->firstMainGroup) {
1636  $this->firstMainGroup = $uid;
1637  }
1638  }
1639  }
1640  // HOOK: fetchGroups_postProcessing
1641  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['fetchGroups_postProcessing'] ?? [] as $_funcRef) {
1642  $_params = [];
1643  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
1644  }
1645  }
1646 
1657  public function ‪setCachedList($cList)
1658  {
1659  if ((string)$cList != (string)$this->user['usergroup_cached_list']) {
1660  GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('be_users')->update(
1661  'be_users',
1662  ['usergroup_cached_list' => $cList],
1663  ['uid' => (int)$this->user['uid']]
1664  );
1665  }
1666  }
1667 
1672  protected function ‪initializeFileStorages()
1673  {
1674  $this->fileStorages = [];
1676  $storageRepository = GeneralUtility::makeInstance(\‪TYPO3\CMS\Core\Resource\StorageRepository::class);
1677  // Admin users have all file storages visible, without any filters
1678  if ($this->‪isAdmin()) {
1679  $storageObjects = $storageRepository->findAll();
1680  foreach ($storageObjects as $storageObject) {
1681  $this->fileStorages[$storageObject->getUid()] = $storageObject;
1682  }
1683  } else {
1684  // Regular users only have storages that are defined in their filemounts
1685  // Permissions and file mounts for the storage are added in StoragePermissionAspect
1686  foreach ($this->‪getFileMountRecords() as $row) {
1687  if (!array_key_exists((int)$row['base'], $this->fileStorages)) {
1688  $storageObject = $storageRepository->findByUid($row['base']);
1689  if ($storageObject) {
1690  $this->fileStorages[$storageObject->getUid()] = $storageObject;
1691  }
1692  }
1693  }
1694  }
1695 
1696  // This has to be called always in order to set certain filters
1698  }
1699 
1706  public function ‪getCategoryMountPoints()
1707  {
1708  $categoryMountPoints = '';
1709 
1710  // Category mounts of the groups
1711  if (is_array($this->userGroups)) {
1712  foreach ($this->userGroups as $group) {
1713  if ($group['category_perms']) {
1714  $categoryMountPoints .= ',' . $group['category_perms'];
1715  }
1716  }
1717  }
1718 
1719  // Category mounts of the user record
1720  if ($this->user['category_perms']) {
1721  $categoryMountPoints .= ',' . $this->user['category_perms'];
1722  }
1723 
1724  // Make the ids unique
1725  $categoryMountPoints = GeneralUtility::trimExplode(',', $categoryMountPoints);
1726  $categoryMountPoints = array_filter($categoryMountPoints); // remove empty value
1727  $categoryMountPoints = array_unique($categoryMountPoints); // remove unique value
1728 
1729  return $categoryMountPoints;
1730  }
1731 
1739  public function ‪getFileMountRecords()
1740  {
1741  $runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime');
1742  $fileMountRecordCache = $runtimeCache->get('backendUserAuthenticationFileMountRecords') ?: [];
1743 
1744  if (!empty($fileMountRecordCache)) {
1745  return $fileMountRecordCache;
1746  }
1747 
1748  $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
1749 
1750  // Processing file mounts (both from the user and the groups)
1751  $fileMounts = array_unique(GeneralUtility::intExplode(',', $this->dataLists['filemount_list'], true));
1752 
1753  // Limit file mounts if set in workspace record
1754  if ($this->workspace > 0 && !empty($this->workspaceRec['file_mountpoints'])) {
1755  $workspaceFileMounts = GeneralUtility::intExplode(',', $this->workspaceRec['file_mountpoints'], true);
1756  $fileMounts = array_intersect($fileMounts, $workspaceFileMounts);
1757  }
1758 
1759  if (!empty($fileMounts)) {
1760  $orderBy = ‪$GLOBALS['TCA']['sys_filemounts']['ctrl']['default_sortby'] ?? 'sorting';
1761 
1762  $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_filemounts');
1763  $queryBuilder->getRestrictions()
1764  ->removeAll()
1765  ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
1766  ->add(GeneralUtility::makeInstance(HiddenRestriction::class))
1767  ->add(GeneralUtility::makeInstance(RootLevelRestriction::class));
1768 
1769  $queryBuilder->select('*')
1770  ->from('sys_filemounts')
1771  ->where(
1772  $queryBuilder->expr()->in('uid', $queryBuilder->createNamedParameter($fileMounts, Connection::PARAM_INT_ARRAY))
1773  );
1774 
1775  foreach (‪QueryHelper::parseOrderBy($orderBy) as $fieldAndDirection) {
1776  $queryBuilder->addOrderBy(...$fieldAndDirection);
1777  }
1778 
1779  $fileMountRecords = $queryBuilder->execute()->fetchAll(\PDO::FETCH_ASSOC);
1780  if ($fileMountRecords !== false) {
1781  foreach ($fileMountRecords as $fileMount) {
1782  $fileMountRecordCache[$fileMount['base'] . $fileMount['path']] = $fileMount;
1783  }
1784  }
1785  }
1786 
1787  // Read-only file mounts
1788  $readOnlyMountPoints = \trim($this->‪getTSConfig()['options.']['folderTree.']['altElementBrowserMountPoints'] ?? '');
1789  if ($readOnlyMountPoints) {
1790  // We cannot use the API here but need to fetch the default storage record directly
1791  // to not instantiate it (which directly applies mount points) before all mount points are resolved!
1792  $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_file_storage');
1793  $defaultStorageRow = $queryBuilder->select('uid')
1794  ->from('sys_file_storage')
1795  ->where(
1796  $queryBuilder->expr()->eq('is_default', $queryBuilder->createNamedParameter(1, \PDO::PARAM_INT))
1797  )
1798  ->setMaxResults(1)
1799  ->execute()
1800  ->fetch(\PDO::FETCH_ASSOC);
1801 
1802  $readOnlyMountPointArray = GeneralUtility::trimExplode(',', $readOnlyMountPoints);
1803  foreach ($readOnlyMountPointArray as $readOnlyMountPoint) {
1804  $readOnlyMountPointConfiguration = GeneralUtility::trimExplode(':', $readOnlyMountPoint);
1805  if (count($readOnlyMountPointConfiguration) === 2) {
1806  // A storage is passed in the configuration
1807  $storageUid = (int)$readOnlyMountPointConfiguration[0];
1808  $path = $readOnlyMountPointConfiguration[1];
1809  } else {
1810  if (empty($defaultStorageRow)) {
1811  throw new \RuntimeException('Read only mount points have been defined in User TsConfig without specific storage, but a default storage could not be resolved.', 1404472382);
1812  }
1813  // Backwards compatibility: If no storage is passed, we use the default storage
1814  $storageUid = $defaultStorageRow['uid'];
1815  $path = $readOnlyMountPointConfiguration[0];
1816  }
1817  $fileMountRecordCache[$storageUid . $path] = [
1818  'base' => $storageUid,
1819  'title' => $path,
1820  'path' => $path,
1821  'read_only' => true
1822  ];
1823  }
1824  }
1825 
1826  // Personal or Group filemounts are not accessible if file mount list is set in workspace record
1827  if ($this->workspace <= 0 || empty($this->workspaceRec['file_mountpoints'])) {
1828  // If userHomePath is set, we attempt to mount it
1829  if (‪$GLOBALS['TYPO3_CONF_VARS']['BE']['userHomePath']) {
1830  list($userHomeStorageUid, $userHomeFilter) = explode(':', ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['userHomePath'], 2);
1831  $userHomeStorageUid = (int)$userHomeStorageUid;
1832  $userHomeFilter = '/' . ltrim($userHomeFilter, '/');
1833  if ($userHomeStorageUid > 0) {
1834  // Try and mount with [uid]_[username]
1835  $path = $userHomeFilter . $this->user['uid'] . '_' . $this->user['username'] . ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['userUploadDir'];
1836  $fileMountRecordCache[$userHomeStorageUid . $path] = [
1837  'base' => $userHomeStorageUid,
1838  'title' => $this->user['username'],
1839  'path' => $path,
1840  'read_only' => false,
1841  'user_mount' => true
1842  ];
1843  // Try and mount with only [uid]
1844  $path = $userHomeFilter . $this->user['uid'] . ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['userUploadDir'];
1845  $fileMountRecordCache[$userHomeStorageUid . $path] = [
1846  'base' => $userHomeStorageUid,
1847  'title' => $this->user['username'],
1848  'path' => $path,
1849  'read_only' => false,
1850  'user_mount' => true
1851  ];
1852  }
1853  }
1854 
1855  // Mount group home-dirs
1856  if ((is_array($this->user) && $this->user['options'] & ‪Permission::PAGE_EDIT) == 2 && ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['groupHomePath'] != '') {
1857  // If groupHomePath is set, we attempt to mount it
1858  list($groupHomeStorageUid, $groupHomeFilter) = explode(':', ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['groupHomePath'], 2);
1859  $groupHomeStorageUid = (int)$groupHomeStorageUid;
1860  $groupHomeFilter = '/' . ltrim($groupHomeFilter, '/');
1861  if ($groupHomeStorageUid > 0) {
1862  foreach ($this->userGroups as ‪$groupData) {
1863  $path = $groupHomeFilter . ‪$groupData['uid'];
1864  $fileMountRecordCache[$groupHomeStorageUid . $path] = [
1865  'base' => $groupHomeStorageUid,
1866  'title' => ‪$groupData['title'],
1867  'path' => $path,
1868  'read_only' => false,
1869  'user_mount' => true
1870  ];
1871  }
1872  }
1873  }
1874  }
1875 
1876  $runtimeCache->set('backendUserAuthenticationFileMountRecords', $fileMountRecordCache);
1877  return $fileMountRecordCache;
1878  }
1879 
1887  public function ‪getFileStorages()
1888  {
1889  // Initializing file mounts after the groups are fetched
1890  if ($this->fileStorages === null) {
1891  $this->‪initializeFileStorages();
1892  }
1893  return ‪$this->fileStorages;
1894  }
1895 
1902  {
1903  // Add the option for also displaying the non-hidden files
1904  if ($this->uc['showHiddenFilesAndFolders']) {
1906  }
1907  }
1944  public function ‪getFilePermissions()
1945  {
1946  if (!isset($this->filePermissions)) {
1948  // File permissions
1949  'addFile' => false,
1950  'readFile' => false,
1951  'writeFile' => false,
1952  'copyFile' => false,
1953  'moveFile' => false,
1954  'renameFile' => false,
1955  'deleteFile' => false,
1956  // Folder permissions
1957  'addFolder' => false,
1958  'readFolder' => false,
1959  'writeFolder' => false,
1960  'copyFolder' => false,
1961  'moveFolder' => false,
1962  'renameFolder' => false,
1963  'deleteFolder' => false,
1964  'recursivedeleteFolder' => false
1965  ];
1966  if ($this->‪isAdmin()) {
1967  ‪$filePermissions = array_map('is_bool', ‪$filePermissions);
1968  } else {
1969  $userGroupRecordPermissions = GeneralUtility::trimExplode(',', $this->groupData['file_permissions'] ?? '', true);
1970  array_walk(
1971  $userGroupRecordPermissions,
1972  function ($permission) use (&‪$filePermissions) {
1973  ‪$filePermissions[$permission] = true;
1974  }
1975  );
1976 
1977  // Finally overlay any userTSconfig
1978  $permissionsTsConfig = $this->‪getTSConfig()['permissions.']['file.']['default.'] ?? [];
1979  if (!empty($permissionsTsConfig)) {
1980  array_walk(
1981  $permissionsTsConfig,
1982  function ($value, $permission) use (&‪$filePermissions) {
1983  ‪$filePermissions[$permission] = (bool)$value;
1984  }
1985  );
1986  }
1987  }
1988  $this->filePermissions = ‪$filePermissions;
1989  }
1991  }
1992 
2002  public function ‪getFilePermissionsForStorage(\‪TYPO3\CMS\Core\Resource\ResourceStorage $storageObject)
2003  {
2004  $finalUserPermissions = $this->‪getFilePermissions();
2005  if (!$this->‪isAdmin()) {
2006  $storageFilePermissions = $this->‪getTSConfig()['permissions.']['file.']['storage.'][$storageObject->getUid() . '.'] ?? [];
2007  if (!empty($storageFilePermissions)) {
2008  array_walk(
2009  $storageFilePermissions,
2010  function ($value, $permission) use (&$finalUserPermissions) {
2011  $finalUserPermissions[$permission] = (bool)$value;
2012  }
2013  );
2014  }
2015  }
2016  return $finalUserPermissions;
2017  }
2018 
2036  public function ‪getDefaultUploadFolder($pid = null, $table = null, $field = null)
2037  {
2038  $uploadFolder = $this->‪getTSConfig()['options.']['defaultUploadFolder'] ?? '';
2039  if ($uploadFolder) {
2041  } else {
2042  foreach ($this->‪getFileStorages() as $storage) {
2043  if ($storage->isDefault() && $storage->isWritable()) {
2044  try {
2045  $uploadFolder = $storage->getDefaultFolder();
2046  if ($uploadFolder->checkActionPermission('write')) {
2047  break;
2048  }
2049  $uploadFolder = null;
2050  } catch (\‪TYPO3\CMS\Core\Resource\Exception $folderAccessException) {
2051  // If the folder is not accessible (no permissions / does not exist) we skip this one.
2052  }
2053  break;
2054  }
2055  }
2056  if (!$uploadFolder instanceof \‪TYPO3\CMS\Core\Resource\Folder) {
2058  foreach ($this->‪getFileStorages() as $storage) {
2059  if ($storage->isWritable()) {
2060  try {
2061  $uploadFolder = $storage->getDefaultFolder();
2062  if ($uploadFolder->checkActionPermission('write')) {
2063  break;
2064  }
2065  $uploadFolder = null;
2066  } catch (\‪TYPO3\CMS\Core\Resource\‪Exception $folderAccessException) {
2067  // If the folder is not accessible (no permissions / does not exist) try the next one.
2068  }
2069  }
2070  }
2071  }
2072  }
2073 
2074  // HOOK: getDefaultUploadFolder
2075  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['getDefaultUploadFolder'] ?? [] as $_funcRef) {
2076  $_params = [
2077  'uploadFolder' => $uploadFolder,
2078  'pid' => $pid,
2079  'table' => $table,
2080  'field' => $field,
2081  ];
2082  $uploadFolder = GeneralUtility::callUserFunction($_funcRef, $_params, $this);
2083  }
2084 
2085  if ($uploadFolder instanceof \‪TYPO3\CMS\Core\Resource\Folder) {
2086  return $uploadFolder;
2087  }
2088  return false;
2089  }
2090 
2099  public function ‪getDefaultUploadTemporaryFolder()
2100  {
2101  $defaultTemporaryFolder = null;
2102  $defaultFolder = $this->‪getDefaultUploadFolder();
2103 
2104  if ($defaultFolder !== false) {
2105  $tempFolderName = '_temp_';
2106  $createFolder = !$defaultFolder->hasFolder($tempFolderName);
2107  if ($createFolder === true) {
2108  try {
2109  $defaultTemporaryFolder = $defaultFolder->createFolder($tempFolderName);
2110  } catch (\‪TYPO3\CMS\Core\Resource\‪Exception $folderAccessException) {
2111  }
2112  } else {
2113  $defaultTemporaryFolder = $defaultFolder->getSubfolder($tempFolderName);
2114  }
2115  }
2116 
2117  return $defaultTemporaryFolder;
2118  }
2119 
2127  public function ‪addTScomment($str)
2128  {
2129  trigger_error('BackendUserAuthentication->addTScomment() will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
2130  $delimiter = '# ***********************************************';
2131  $out = $delimiter . LF;
2132  $lines = GeneralUtility::trimExplode(LF, $str);
2133  foreach ($lines as $v) {
2134  $out .= '# ' . $v . LF;
2135  }
2136  $out .= $delimiter . LF;
2137  return $out;
2138  }
2139 
2146  public function ‪workspaceInit()
2147  {
2148  // Initializing workspace by evaluating and setting the workspace, possibly updating it in the user record!
2149  $this->‪setWorkspace($this->user['workspace_id']);
2150  // Limiting the DB mountpoints if there any selected in the workspace record
2152  $allowed_languages = $this->‪getTSConfig()['options.']['workspaces.']['allowed_languages.'][‪$this->workspace] ?? '';
2153  if (!empty($allowed_languages)) {
2154  $this->groupData['allowed_languages'] = GeneralUtility::uniqueList($allowed_languages);
2155  }
2156  }
2161  protected function ‪initializeDbMountpointsInWorkspace()
2162  {
2163  $dbMountpoints = trim($this->workspaceRec['db_mountpoints'] ?? '');
2164  if ($this->workspace > 0 && $dbMountpoints != '') {
2165  $filteredDbMountpoints = [];
2166  // Notice: We cannot call $this->getPagePermsClause(1);
2167  // as usual because the group-list is not available at this point.
2168  // But bypassing is fine because all we want here is check if the
2169  // workspace mounts are inside the current webmounts rootline.
2170  // The actual permission checking on page level is done elsewhere
2171  // as usual anyway before the page tree is rendered.
2172  $readPerms = '1=1';
2173  // Traverse mount points of the
2174  $dbMountpoints = GeneralUtility::intExplode(',', $dbMountpoints);
2175  foreach ($dbMountpoints as $mpId) {
2176  if ($this->‪isInWebMount($mpId, $readPerms)) {
2177  $filteredDbMountpoints[] = $mpId;
2178  }
2179  }
2180  // Re-insert webmounts:
2181  $filteredDbMountpoints = array_unique($filteredDbMountpoints);
2182  $this->groupData['webmounts'] = implode(',', $filteredDbMountpoints);
2183  }
2184  }
2185 
2193  public function ‪checkWorkspace($wsRec, ‪$fields = 'uid,title,adminusers,members,reviewers,publish_access,stagechg_notification')
2194  {
2195  $retVal = false;
2196  // If not array, look up workspace record:
2197  if (!is_array($wsRec)) {
2198  switch ((string)$wsRec) {
2199  case '0':
2200  $wsRec = ['uid' => $wsRec];
2201  break;
2202  default:
2203  if (‪ExtensionManagementUtility::isLoaded('workspaces')) {
2204  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_workspace');
2205  $queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(RootLevelRestriction::class));
2206  $wsRec = $queryBuilder->select(...GeneralUtility::trimExplode(',', ‪$fields))
2207  ->from('sys_workspace')
2208  ->where($queryBuilder->expr()->eq(
2209  'uid',
2210  $queryBuilder->createNamedParameter($wsRec, \PDO::PARAM_INT)
2211  ))
2212  ->orderBy('title')
2213  ->setMaxResults(1)
2214  ->execute()
2215  ->fetch(\PDO::FETCH_ASSOC);
2216  }
2217  }
2218  }
2219  // If wsRec is set to an array, evaluate it:
2220  if (is_array($wsRec)) {
2221  if ($this->‪isAdmin()) {
2222  return array_merge($wsRec, ['_ACCESS' => 'admin']);
2223  }
2224  switch ((string)$wsRec['uid']) {
2225  case '0':
2226  $retVal = $this->groupData['workspace_perms'] & ‪Permission::PAGE_SHOW
2227  ? array_merge($wsRec, ['_ACCESS' => 'online'])
2228  : false;
2229  break;
2230  default:
2231  // Checking if the guy is admin:
2232  if (GeneralUtility::inList($wsRec['adminusers'], 'be_users_' . $this->user['uid'])) {
2233  return array_merge($wsRec, ['_ACCESS' => 'owner']);
2234  }
2235  // Checking if he is owner through a user group of his:
2236  foreach ($this->userGroupsUID as $groupUid) {
2237  if (GeneralUtility::inList($wsRec['adminusers'], 'be_groups_' . $groupUid)) {
2238  return array_merge($wsRec, ['_ACCESS' => 'owner']);
2239  }
2240  }
2241  // Checking if he is reviewer user:
2242  if (GeneralUtility::inList($wsRec['reviewers'], 'be_users_' . $this->user['uid'])) {
2243  return array_merge($wsRec, ['_ACCESS' => 'reviewer']);
2244  }
2245  // Checking if he is reviewer through a user group of his:
2246  foreach ($this->userGroupsUID as $groupUid) {
2247  if (GeneralUtility::inList($wsRec['reviewers'], 'be_groups_' . $groupUid)) {
2248  return array_merge($wsRec, ['_ACCESS' => 'reviewer']);
2249  }
2250  }
2251  // Checking if he is member as user:
2252  if (GeneralUtility::inList($wsRec['members'], 'be_users_' . $this->user['uid'])) {
2253  return array_merge($wsRec, ['_ACCESS' => 'member']);
2254  }
2255  // Checking if he is member through a user group of his:
2256  foreach ($this->userGroupsUID as $groupUid) {
2257  if (GeneralUtility::inList($wsRec['members'], 'be_groups_' . $groupUid)) {
2258  return array_merge($wsRec, ['_ACCESS' => 'member']);
2259  }
2260  }
2261  }
2262  }
2263  return $retVal;
2264  }
2265 
2273  public function ‪checkWorkspaceCurrent()
2274  {
2275  if (!isset($this->checkWorkspaceCurrent_cache)) {
2276  $this->checkWorkspaceCurrent_cache = $this->‪checkWorkspace($this->workspace);
2277  }
2279  }
2280 
2286  public function ‪setWorkspace($workspaceId)
2287  {
2288  // Check workspace validity and if not found, revert to default workspace.
2289  if (!$this->‪setTemporaryWorkspace($workspaceId)) {
2290  $this->‪setDefaultWorkspace();
2291  }
2292  // Unset access cache:
2293  $this->checkWorkspaceCurrent_cache = null;
2294  // If ID is different from the stored one, change it:
2295  if ((int)$this->workspace !== (int)$this->user['workspace_id']) {
2296  $this->user['workspace_id'] = ‪$this->workspace;
2297  GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('be_users')->update(
2298  'be_users',
2299  ['workspace_id' => $this->user['workspace_id']],
2300  ['uid' => (int)$this->user['uid']]
2301  );
2302  $this->‪writelog(4, 0, 0, 0, 'User changed workspace to "' . $this->workspace . '"', []);
2303  }
2304  }
2305 
2312  public function ‪setTemporaryWorkspace($workspaceId)
2313  {
2314  $result = false;
2315  $workspaceRecord = $this->‪checkWorkspace($workspaceId, '*');
2316 
2317  if ($workspaceRecord) {
2318  $this->workspaceRec = $workspaceRecord;
2319  $this->workspace = (int)$workspaceId;
2320  $result = true;
2321  }
2322 
2323  return $result;
2324  }
2325 
2329  public function ‪setDefaultWorkspace()
2330  {
2331  $this->workspace = (int)$this->‪getDefaultWorkspace();
2332  $this->workspaceRec = $this->‪checkWorkspace($this->workspace, '*');
2333  }
2334 
2342  public function ‪getDefaultWorkspace()
2343  {
2344  if (!‪ExtensionManagementUtility::isLoaded('workspaces')) {
2345  return 0;
2346  }
2347  // Online is default
2348  if ($this->‪checkWorkspace(0)) {
2349  return 0;
2350  }
2351  // Otherwise -99 is the fallback
2352  $defaultWorkspace = -99;
2353  // Traverse all workspaces
2354  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_workspace');
2355  $queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(RootLevelRestriction::class));
2356  $result = $queryBuilder->select('*')
2357  ->from('sys_workspace')
2358  ->orderBy('title')
2359  ->execute();
2360  while ($workspaceRecord = $result->fetch()) {
2361  if ($this->‪checkWorkspace($workspaceRecord)) {
2362  $defaultWorkspace = (int)$workspaceRecord['uid'];
2363  break;
2364  }
2365  }
2366  return $defaultWorkspace;
2367  }
2368 
2387  public function ‪writelog($type, $action, $error, $details_nr, $details, $data, $tablename = '', $recuid = '', $recpid = '', $event_pid = -1, $NEWid = '', $userId = 0)
2388  {
2389  if (!$userId && !empty($this->user['uid'])) {
2390  $userId = $this->user['uid'];
2391  }
2392 
2393  if (!empty($this->user['ses_backuserid'])) {
2394  if (empty($data)) {
2395  $data = [];
2396  }
2397  $data['originalUser'] = $this->user['ses_backuserid'];
2398  }
2399 
2400  ‪$fields = [
2401  'userid' => (int)$userId,
2402  'type' => (int)$type,
2403  'action' => (int)$action,
2404  'error' => (int)$error,
2405  'details_nr' => (int)$details_nr,
2406  'details' => $details,
2407  'log_data' => serialize($data),
2408  'tablename' => $tablename,
2409  'recuid' => (int)$recuid,
2410  'IP' => (string)GeneralUtility::getIndpEnv('REMOTE_ADDR'),
2411  'tstamp' => ‪$GLOBALS['EXEC_TIME'] ?? time(),
2412  'event_pid' => (int)$event_pid,
2413  'NEWid' => $NEWid,
2414  'workspace' => $this->workspace
2415  ];
2416 
2417  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('sys_log');
2418  $connection->insert(
2419  'sys_log',
2420  ‪$fields,
2421  [
2422  \PDO::PARAM_INT,
2423  \PDO::PARAM_INT,
2424  \PDO::PARAM_INT,
2425  \PDO::PARAM_INT,
2426  \PDO::PARAM_INT,
2427  \PDO::PARAM_STR,
2428  \PDO::PARAM_STR,
2429  \PDO::PARAM_STR,
2430  \PDO::PARAM_INT,
2431  \PDO::PARAM_STR,
2432  \PDO::PARAM_INT,
2433  \PDO::PARAM_INT,
2434  \PDO::PARAM_STR,
2435  \PDO::PARAM_STR,
2436  ]
2437  );
2438 
2439  return (int)$connection->lastInsertId('sys_log');
2440  }
2441 
2451  public function ‪simplelog($message, $extKey = '', $error = 0)
2452  {
2453  trigger_error('BackendUserAuthentication->simplelog() will be removed in TYPO3 v10.0. Use writelog, or better, PSR-3 based logging instead.', E_USER_DEPRECATED);
2454  return $this->‪writelog(4, 0, $error, 0, ($extKey ? '[' . $extKey . '] ' : '') . $message, []);
2455  }
2456 
2468  public function ‪checkLogFailures($email, $secondsBack = 3600, $max = 3)
2469  {
2470  if ($email) {
2471  $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
2472 
2473  // Get last flag set in the log for sending
2474  $theTimeBack = ‪$GLOBALS['EXEC_TIME'] - $secondsBack;
2475  $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_log');
2476  $queryBuilder->select('tstamp')
2477  ->from('sys_log')
2478  ->where(
2479  $queryBuilder->expr()->eq(
2480  'type',
2481  $queryBuilder->createNamedParameter(255, \PDO::PARAM_INT)
2482  ),
2483  $queryBuilder->expr()->eq(
2484  'action',
2485  $queryBuilder->createNamedParameter(4, \PDO::PARAM_INT)
2486  ),
2487  $queryBuilder->expr()->gt(
2488  'tstamp',
2489  $queryBuilder->createNamedParameter($theTimeBack, \PDO::PARAM_INT)
2490  )
2491  )
2492  ->orderBy('tstamp', 'DESC')
2493  ->setMaxResults(1);
2494  if ($testRow = $queryBuilder->execute()->fetch(\PDO::FETCH_ASSOC)) {
2495  $theTimeBack = $testRow['tstamp'];
2496  }
2497 
2498  $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_log');
2499  $rowCount = $queryBuilder->count('uid')
2500  ->from('sys_log')
2501  ->where(
2502  $queryBuilder->expr()->eq(
2503  'type',
2504  $queryBuilder->createNamedParameter(255, \PDO::PARAM_INT)
2505  ),
2506  $queryBuilder->expr()->eq(
2507  'action',
2508  $queryBuilder->createNamedParameter(3, \PDO::PARAM_INT)
2509  ),
2510  $queryBuilder->expr()->neq(
2511  'error',
2512  $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
2513  ),
2514  $queryBuilder->expr()->gt(
2515  'tstamp',
2516  $queryBuilder->createNamedParameter($theTimeBack, \PDO::PARAM_INT)
2517  )
2518  )
2519  ->execute()
2520  ->fetchColumn(0);
2521 
2522  // Check for more than $max number of error failures with the last period.
2523  if ($rowCount > $max) {
2524  $result = $queryBuilder
2525  ->select('*')
2526  ->orderBy('tstamp')
2527  ->execute();
2528 
2529  // OK, so there were more than the max allowed number of login failures - so we will send an email then.
2530  $subject = 'TYPO3 Login Failure Warning (at ' . ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . ')';
2531  $email_body = 'There have been some attempts (' . $rowCount . ') to login at the TYPO3
2532 site "' . ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '" (' . GeneralUtility::getIndpEnv('HTTP_HOST') . ').
2533 
2534 This is a dump of the failures:
2535 
2536 ';
2537  while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
2538  $theData = unserialize($row['log_data']);
2539  $text = @sprintf($row['details'], (string)$theData[0], (string)$theData[1], (string)$theData[2]);
2540  if ((int)$row['type'] === 255) {
2541  $text = str_replace('###IP###', $row['IP'], $text);
2542  }
2543  $email_body .= date(
2544  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] . ' ' . ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'],
2545  $row['tstamp']
2546  ) . ': ' . $text;
2547  $email_body .= LF;
2548  }
2550  $mail = GeneralUtility::makeInstance(\‪TYPO3\CMS\Core\Mail\MailMessage::class);
2551  $mail->setTo($email)->setSubject($subject)->setBody($email_body);
2552  $mail->send();
2553  // Logout written to log
2554  $this->‪writelog(255, 4, 0, 3, 'Failure warning (%s failures within %s seconds) sent by email to %s', [$rowCount, $secondsBack, $email]);
2555  }
2556  }
2557  }
2558 
2565  public static function ‪getCookieName()
2566  {
2567  $configuredCookieName = trim(‪$GLOBALS['TYPO3_CONF_VARS']['BE']['cookieName']);
2568  if (empty($configuredCookieName)) {
2569  $configuredCookieName = 'be_typo_user';
2570  }
2571  return $configuredCookieName;
2572  }
2573 
2581  public function ‪checkLockToIP()
2582  {
2583  $isValid = true;
2584  if (‪$GLOBALS['TYPO3_CONF_VARS']['BE']['enabledBeUserIPLock']) {
2585  $IPList = trim($this->‪getTSConfig()['options.']['lockToIP'] ?? '');
2586  if (!empty($IPList)) {
2587  $isValid = GeneralUtility::cmpIP(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $IPList);
2588  }
2589  }
2590  return $isValid;
2591  }
2592 
2602  public function ‪backendCheckLogin($proceedIfNoUserIsLoggedIn = false)
2603  {
2604  if (empty($this->user['uid'])) {
2605  if ($proceedIfNoUserIsLoggedIn === false) {
2606  $url = GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir;
2608  }
2609  } else {
2610  // ...and if that's the case, call these functions
2611  $this->‪fetchGroupData();
2612  // The groups are fetched and ready for permission checking in this initialization.
2613  // Tables.php must be read before this because stuff like the modules has impact in this
2614  if ($this->‪checkLockToIP()) {
2615  if ($this->‪isUserAllowedToLogin()) {
2616  // Setting the UC array. It's needed with fetchGroupData first, due to default/overriding of values.
2617  $this->‪backendSetUC();
2618  if ($this->loginSessionStarted) {
2619  // Process hooks
2620  $hooks = ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['backendUserLogin'];
2621  foreach ($hooks ?? [] as $_funcRef) {
2622  $_params = ['user' => ‪$this->user];
2623  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
2624  }
2625  // Email at login, if feature is enabled in configuration
2626  $this->‪emailAtLogin();
2627  }
2628  } else {
2629  throw new \RuntimeException('Login Error: TYPO3 is in maintenance mode at the moment. Only administrators are allowed access.', 1294585860);
2630  }
2631  } else {
2632  throw new \RuntimeException('Login Error: IP locking prevented you from being authorized. Can\'t proceed, sorry.', 1294585861);
2633  }
2634  }
2635  }
2636 
2643  public function ‪backendSetUC()
2644  {
2645  // UC - user configuration is a serialized array inside the user object
2646  // If there is a saved uc we implement that instead of the default one.
2647  $this->‪unpack_uc();
2648  // Setting defaults if uc is empty
2649  $updated = false;
2650  $originalUc = [];
2651  if (is_array($this->uc) && isset($this->uc['ucSetByInstallTool'])) {
2652  $originalUc = ‪$this->uc;
2653  unset($originalUc['ucSetByInstallTool'], $this->uc);
2654  }
2655  if (!is_array($this->uc)) {
2656  $this->uc = array_merge(
2657  $this->uc_default,
2658  (array)‪$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUC'],
2659  GeneralUtility::removeDotsFromTS((array)($this->‪getTSConfig()['setup.']['default.'] ?? [])),
2660  $originalUc
2661  );
2662  $this->‪overrideUC();
2663  $updated = true;
2664  }
2665  // If TSconfig is updated, update the defaultUC.
2666  if ($this->userTSUpdated) {
2667  $this->‪overrideUC();
2668  $updated = true;
2669  }
2670  // Setting default lang from be_user record.
2671  if (!isset($this->uc['lang'])) {
2672  $this->uc['lang'] = $this->user['lang'];
2673  $updated = true;
2674  }
2675  // Setting the time of the first login:
2676  if (!isset($this->uc['firstLoginTimeStamp'])) {
2677  $this->uc['firstLoginTimeStamp'] = ‪$GLOBALS['EXEC_TIME'];
2678  $updated = true;
2679  }
2680  // Saving if updated.
2681  if ($updated) {
2682  $this->‪writeUC();
2683  }
2684  }
2685 
2692  public function ‪overrideUC()
2693  {
2694  $this->uc = array_merge((array)$this->uc, (array)($this->‪getTSConfig()['setup.']['override.'] ?? []));
2695  }
2696 
2702  public function ‪resetUC()
2703  {
2704  $this->user['uc'] = '';
2705  $this->uc = '';
2706  $this->‪backendSetUC();
2707  }
2708 
2714  private function ‪emailAtLogin()
2715  {
2716  // Send notify-mail
2717  $subject = 'At "' . ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '"' . ' from ' . GeneralUtility::getIndpEnv('REMOTE_ADDR');
2718  $msg = sprintf(
2719  'User "%s" logged in from %s at "%s" (%s)',
2720  $this->user['username'],
2721  GeneralUtility::getIndpEnv('REMOTE_ADDR'),
2722  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'],
2723  GeneralUtility::getIndpEnv('HTTP_HOST')
2724  );
2725  // Warning email address
2726  if (‪$GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr']) {
2727  $warn = 0;
2728  $prefix = '';
2729  if ((int)‪$GLOBALS['TYPO3_CONF_VARS']['BE']['warning_mode'] & 1) {
2730  // first bit: All logins
2731  $warn = 1;
2732  $prefix = $this->‪isAdmin() ? '[AdminLoginWarning]' : '[LoginWarning]';
2733  }
2734  if ($this->‪isAdmin() && (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['warning_mode'] & 2) {
2735  // second bit: Only admin-logins
2736  $warn = 1;
2737  $prefix = '[AdminLoginWarning]';
2738  }
2739  if ($warn) {
2741  $mail = GeneralUtility::makeInstance(\‪TYPO3\CMS\Core\Mail\MailMessage::class);
2742  $mail->setTo(‪$GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'])->setSubject($prefix . ' ' . $subject)->setBody($msg);
2743  $mail->send();
2744  }
2745  }
2746  // Trigger an email to the current BE user, if this has been enabled in the user configuration
2747  if (($this->uc['emailMeAtLogin'] ?? false) && strstr($this->user['email'] ?? '', '@')) {
2749  $mail = GeneralUtility::makeInstance(\‪TYPO3\CMS\Core\Mail\MailMessage::class);
2750  $mail->setTo($this->user['email'])->setSubject($subject)->setBody($msg);
2751  $mail->send();
2752  }
2753  }
2754 
2766  protected function ‪isUserAllowedToLogin()
2767  {
2768  $isUserAllowedToLogin = false;
2769  $adminOnlyMode = (int)‪$GLOBALS['TYPO3_CONF_VARS']['BE']['adminOnly'];
2770  // Backend user is allowed if adminOnly is not set or user is an admin:
2771  if (!$adminOnlyMode || $this->‪isAdmin()) {
2772  $isUserAllowedToLogin = true;
2773  } elseif ($this->user['ses_backuserid']) {
2774  $backendUserId = (int)$this->user['ses_backuserid'];
2775  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('be_users');
2776  $isUserAllowedToLogin = (bool)$queryBuilder->count('uid')
2777  ->from('be_users')
2778  ->where(
2779  $queryBuilder->expr()->eq(
2780  'uid',
2781  $queryBuilder->createNamedParameter($backendUserId, \PDO::PARAM_INT)
2782  ),
2783  $queryBuilder->expr()->eq('admin', $queryBuilder->createNamedParameter(1, \PDO::PARAM_INT))
2784  )
2785  ->execute()
2786  ->fetchColumn(0);
2787  }
2788  return $isUserAllowedToLogin;
2789  }
2790 
2794  public function ‪logoff()
2795  {
2796  if (isset(‪$GLOBALS['BE_USER'])
2797  && ‪$GLOBALS['BE_USER'] instanceof self
2798  && isset(‪$GLOBALS['BE_USER']->user['uid'])
2799  ) {
2801  // Release the locked records
2802  $this->‪releaseLockedRecords((int)$GLOBALS['BE_USER']->user['uid']);
2803 
2804  if ($this->‪isSystemMaintainer()) {
2805  // If user is system maintainer, destroy its possibly valid install tool session.
2806  $session = new SessionService();
2807  if ($session->hasSession()) {
2808  $session->destroySession();
2809  }
2810  }
2811  }
2812  parent::logoff();
2813  }
2814 
2819  protected function ‪releaseLockedRecords(int $userId)
2820  {
2821  if ($userId > 0) {
2822  GeneralUtility::makeInstance(ConnectionPool::class)
2823  ->getConnectionForTable('sys_lockedrecords')
2824  ->delete(
2825  'sys_lockedrecords',
2826  ['userid' => $userId]
2827  );
2828  }
2829  }
2830 }
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\backendCheckLogin
‪backendCheckLogin($proceedIfNoUserIsLoggedIn=false)
Definition: BackendUserAuthentication.php:2566
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\returnWebmounts
‪array returnWebmounts()
Definition: BackendUserAuthentication.php:1298
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\evaluateUserSpecificFileFilterSettings
‪evaluateUserSpecificFileFilterSettings()
Definition: BackendUserAuthentication.php:1865
‪TYPO3\CMS\Core\Database\Query\QueryHelper\parseOrderBy
‪static array array[] parseOrderBy(string $input)
Definition: QueryHelper.php:42
‪TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction
Definition: HiddenRestriction.php:25
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\workspacePublishAccess
‪bool workspacePublishAccess($wsid)
Definition: BackendUserAuthentication.php:1175
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\recordEditAccessInternals
‪bool recordEditAccessInternals($table, $idOrRow, $newRecord=false, $deletedRecord=false, $checkFullLanguageAccess=false)
Definition: BackendUserAuthentication.php:802
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\get
‪static TYPO3 CMS Core FormProtection AbstractFormProtection get($classNameOrType='default',... $constructorArguments)
Definition: FormProtectionFactory.php:72
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$usergroup_table
‪string $usergroup_table
Definition: BackendUserAuthentication.php:70
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder
Definition: ExpressionBuilder.php:33
‪TYPO3\CMS\Backend\Utility\BackendUtility\isModuleSetInTBE_MODULES
‪static bool isModuleSetInTBE_MODULES($modName)
Definition: BackendUtility.php:3763
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\workspaceCreateNewRecord
‪bool workspaceCreateNewRecord($pid, $table)
Definition: BackendUserAuthentication.php:1062
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\setWebmounts
‪setWebmounts(array $mountPointUids, $append=false)
Definition: BackendUserAuthentication.php:1309
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder\EQ
‪const EQ
Definition: ExpressionBuilder.php:34
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication\writeUC
‪writeUC($variable='')
Definition: AbstractUserAuthentication.php:1172
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication\unpack_uc
‪unpack_uc($theUC='')
Definition: AbstractUserAuthentication.php:1194
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\addTScomment
‪string addTScomment($str)
Definition: BackendUserAuthentication.php:2091
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$formfield_status
‪string $formfield_status
Definition: BackendUserAuthentication.php:220
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_NEW
‪const PAGE_NEW
Definition: Permission.php:47
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getPagePermsClause
‪string getPagePermsClause($perms)
Definition: BackendUserAuthentication.php:523
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\workspaceSwapAccess
‪bool workspaceSwapAccess()
Definition: BackendUserAuthentication.php:1207
‪TYPO3\CMS\Core\Exception
Definition: Exception.php:21
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\initializeDbMountpointsInWorkspace
‪initializeDbMountpointsInWorkspace()
Definition: BackendUserAuthentication.php:2125
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\initializeFileStorages
‪initializeFileStorages()
Definition: BackendUserAuthentication.php:1636
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$formfield_uname
‪string $formfield_uname
Definition: BackendUserAuthentication.php:210
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$userTS_text
‪string $userTS_text
Definition: BackendUserAuthentication.php:140
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\calcPerms
‪int calcPerms($row)
Definition: BackendUserAuthentication.php:592
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\setCachedList
‪setCachedList($cList)
Definition: BackendUserAuthentication.php:1621
‪TYPO3\CMS\Core\Authentication
Definition: AbstractAuthenticationService.php:2
‪TYPO3
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$usergroup_column
‪string $usergroup_column
Definition: BackendUserAuthentication.php:65
‪TYPO3\CMS\Core\Type\Bitmask\Permission\NOTHING
‪const NOTHING
Definition: Permission.php:27
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$firstMainGroup
‪int $firstMainGroup
Definition: BackendUserAuthentication.php:244
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$userGroups
‪array $userGroups
Definition: BackendUserAuthentication.php:83
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isAdmin
‪bool isAdmin()
Definition: BackendUserAuthentication.php:294
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$uc_default
‪array $uc_default
Definition: BackendUserAuthentication.php:259
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$uc
‪array $uc
Definition: BackendUserAuthentication.php:249
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFolderObjectFromCombinedIdentifier
‪Folder getFolderObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:539
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\check
‪bool check($type, $value)
Definition: BackendUserAuthentication.php:648
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getTSConfig
‪array getTSConfig($objectString=null, $config=null)
Definition: BackendUserAuthentication.php:1232
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isSystemMaintainer
‪bool isSystemMaintainer()
Definition: BackendUserAuthentication.php:472
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\fetchGroupData
‪fetchGroupData()
Definition: BackendUserAuthentication.php:1378
‪TYPO3\CMS\Core\Resource\ResourceFactory\getInstance
‪static ResourceFactory getInstance()
Definition: ResourceFactory.php:39
‪TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction
Definition: BackendWorkspaceRestriction.php:28
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\fetchGroups
‪fetchGroups($grList, $idList='')
Definition: BackendUserAuthentication.php:1520
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\workspaceAllowLiveRecordsInPID
‪mixed workspaceAllowLiveRecordsInPID($pid, $table)
Definition: BackendUserAuthentication.php:1039
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getDefaultUploadTemporaryFolder
‪TYPO3 CMS Core Resource Folder null getDefaultUploadTemporaryFolder()
Definition: BackendUserAuthentication.php:2063
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\setDefaultWorkspace
‪setDefaultWorkspace()
Definition: BackendUserAuthentication.php:2293
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\emailAtLogin
‪emailAtLogin()
Definition: BackendUserAuthentication.php:2678
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isMemberOfGroup
‪bool isMemberOfGroup($groupId)
Definition: BackendUserAuthentication.php:307
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication\$id
‪string $id
Definition: AbstractUserAuthentication.php:239
‪TYPO3\CMS\Backend\Utility\BackendUtility\BEgetRootLine
‪static array BEgetRootLine($uid, $clause='', $workspaceOL=false, array $additionalFields=[])
Definition: BackendUtility.php:374
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\checkAuthMode
‪bool checkAuthMode($table, $field, $value, $authMode)
Definition: BackendUserAuthentication.php:663
‪$fields
‪$fields
Definition: pages.php:4
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$writeAttemptLog
‪bool $writeAttemptLog
Definition: BackendUserAuthentication.php:230
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$filePermissions
‪array $filePermissions
Definition: BackendUserAuthentication.php:171
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getRealUserId
‪getRealUserId()
Definition: BackendUserAuthentication.php:503
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getFileStorages
‪TYPO3 CMS Core Resource ResourceStorage[] getFileStorages()
Definition: BackendUserAuthentication.php:1851
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:23
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$formfield_uident
‪string $formfield_uident
Definition: BackendUserAuthentication.php:215
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:36
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getCategoryMountPoints
‪array getCategoryMountPoints()
Definition: BackendUserAuthentication.php:1670
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$includeGroupArray
‪array $includeGroupArray
Definition: BackendUserAuthentication.php:132
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\checkLockToIP
‪bool checkLockToIP()
Definition: BackendUserAuthentication.php:2545
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getCookieName
‪static string getCookieName()
Definition: BackendUserAuthentication.php:2529
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\checkLogFailures
‪checkLogFailures($email, $secondsBack=3600, $max=3)
Definition: BackendUserAuthentication.php:2432
‪TYPO3\CMS\Core\Type\Enumeration\cast
‪static static cast($value)
Definition: Enumeration.php:182
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getFileMountRecords
‪array getFileMountRecords()
Definition: BackendUserAuthentication.php:1703
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\mayMakeShortcut
‪bool mayMakeShortcut()
Definition: BackendUserAuthentication.php:939
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\resetUC
‪resetUC()
Definition: BackendUserAuthentication.php:2666
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$userid_column
‪string $userid_column
Definition: BackendUserAuthentication.php:191
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$user_table
‪string $user_table
Definition: BackendUserAuthentication.php:176
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:30
‪TYPO3\CMS\Core\Type\Bitmask\Permission\ALL
‪const ALL
Definition: Permission.php:57
‪TYPO3\CMS\Core\Database\Query\Restriction\RootLevelRestriction
Definition: RootLevelRestriction.php:25
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\setWorkspace
‪setWorkspace($workspaceId)
Definition: BackendUserAuthentication.php:2250
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$userTSUpdated
‪bool $userTSUpdated
Definition: BackendUserAuthentication.php:148
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\backendSetUC
‪backendSetUC()
Definition: BackendUserAuthentication.php:2607
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$userTS_dontGetCached
‪bool $userTS_dontGetCached
Definition: BackendUserAuthentication.php:153
‪TYPO3\CMS\Core\FormProtection\AbstractFormProtection\clean
‪clean()
Definition: AbstractFormProtection.php:63
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\ROLE_SYSTEMMAINTAINER
‪const ROLE_SYSTEMMAINTAINER
Definition: BackendUserAuthentication.php:47
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isUserAllowedToLogin
‪bool isUserAllowedToLogin()
Definition: BackendUserAuthentication.php:2730
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$groupData
‪array $groupData
Definition: BackendUserAuthentication.php:76
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\doesUserHaveAccess
‪bool doesUserHaveAccess($row, $perms)
Definition: BackendUserAuthentication.php:331
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\workspaceAllowAutoCreation
‪bool workspaceAllowAutoCreation($table, $id, $recpid)
Definition: BackendUserAuthentication.php:1085
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getFilePermissions
‪array getFilePermissions()
Definition: BackendUserAuthentication.php:1908
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$deprecatedPublicProperties
‪array $deprecatedPublicProperties
Definition: BackendUserAuthentication.php:53
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$username_column
‪string $username_column
Definition: BackendUserAuthentication.php:181
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static bool isLoaded($key, $exitOnError=null)
Definition: ExtensionManagementUtility.php:115
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication\getSessionData
‪mixed getSessionData($key)
Definition: AbstractUserAuthentication.php:1258
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:34
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$TSdataArray
‪array $TSdataArray
Definition: BackendUserAuthentication.php:136
‪TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser\checkIncludeLines_array
‪static array checkIncludeLines_array(array $array)
Definition: TypoScriptParser.php:1214
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\checkLanguageAccess
‪bool checkLanguageAccess($langValue)
Definition: BackendUserAuthentication.php:733
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:45
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getFilePermissionsForStorage
‪array getFilePermissionsForStorage(\TYPO3\CMS\Core\Resource\ResourceStorage $storageObject)
Definition: BackendUserAuthentication.php:1966
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:32
‪TYPO3\CMS\Core\Resource\Filter\FileNameFilter\setShowHiddenFilesAndFolders
‪static bool setShowHiddenFilesAndFolders($showHiddenFilesAndFolders)
Definition: FileNameFilter.php:70
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getDefaultUploadFolder
‪TYPO3 CMS Core Resource Folder bool getDefaultUploadFolder($pid=null, $table=null, $field=null)
Definition: BackendUserAuthentication.php:2000
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$checkWorkspaceCurrent_cache
‪array null $checkWorkspaceCurrent_cache
Definition: BackendUserAuthentication.php:163
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$userGroupsUID
‪array $userGroupsUID
Definition: BackendUserAuthentication.php:88
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\overrideUC
‪overrideUC()
Definition: BackendUserAuthentication.php:2656
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$enablecolumns
‪array $enablecolumns
Definition: BackendUserAuthentication.php:199
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:72
‪TYPO3\CMS\Backend\Utility\BackendUtility\getWorkspaceVersionOfRecord
‪static array bool getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields=' *')
Definition: BackendUtility.php:4166
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\logoff
‪logoff()
Definition: BackendUserAuthentication.php:2758
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecord
‪static array null getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
Definition: BackendUtility.php:130
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\workspaceCannotEditRecord
‪string workspaceCannotEditRecord($table, $recData)
Definition: BackendUserAuthentication.php:956
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication\$user
‪array null $user
Definition: AbstractUserAuthentication.php:254
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\__construct
‪__construct()
Definition: BackendUserAuthentication.php:278
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getTSConfigProp
‪array getTSConfigProp($objectString)
Definition: BackendUserAuthentication.php:1284
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\releaseLockedRecords
‪releaseLockedRecords(int $userId)
Definition: BackendUserAuthentication.php:2783
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:31
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$sessionTimeout
‪int $sessionTimeout
Definition: BackendUserAuthentication.php:240
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$lastLogin_column
‪string $lastLogin_column
Definition: BackendUserAuthentication.php:195
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:74
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isRTE
‪bool isRTE()
Definition: BackendUserAuthentication.php:633
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory
Definition: FormProtectionFactory.php:45
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\writelog
‪int writelog($type, $action, $error, $details_nr, $details, $data, $tablename='', $recuid='', $recpid='', $event_pid=-1, $NEWid='', $userId=0)
Definition: BackendUserAuthentication.php:2351
‪TYPO3\CMS\Backend\Utility\BackendUtility\isTableLocalizable
‪static bool isTableLocalizable($table)
Definition: BackendUtility.php:616
‪TYPO3\CMS\Core\Type\Bitmask\Permission\CONTENT_EDIT
‪const CONTENT_EDIT
Definition: Permission.php:52
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$userTS
‪array $userTS
Definition: BackendUserAuthentication.php:144
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Type\Exception\InvalidEnumerationValueException
Definition: InvalidEnumerationValueException.php:21
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:26
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_EDIT
‪const PAGE_EDIT
Definition: Permission.php:37
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_DELETE
‪const PAGE_DELETE
Definition: Permission.php:42
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\simplelog
‪int simplelog($message, $extKey='', $error=0)
Definition: BackendUserAuthentication.php:2415
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\modAccess
‪bool modAccess($conf, $exitOnError=null)
Definition: BackendUserAuthentication.php:416
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$workspace
‪int $workspace
Definition: BackendUserAuthentication.php:101
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\workspaceInit
‪workspaceInit()
Definition: BackendUserAuthentication.php:2110
‪TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait
Definition: PublicPropertyDeprecationTrait.php:66
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:44
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\checkWorkspaceCurrent
‪array checkWorkspaceCurrent()
Definition: BackendUserAuthentication.php:2237
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\initializeWebmountsForElementBrowser
‪initializeWebmountsForElementBrowser()
Definition: BackendUserAuthentication.php:1332
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$userident_column
‪string $userident_column
Definition: BackendUserAuthentication.php:186
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\setTemporaryWorkspace
‪bool setTemporaryWorkspace($workspaceId)
Definition: BackendUserAuthentication.php:2276
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$groupList
‪string $groupList
Definition: BackendUserAuthentication.php:93
‪TYPO3\CMS\Core\Utility\HttpUtility\redirect
‪static redirect($url, $httpStatus=self::HTTP_STATUS_303)
Definition: HttpUtility.php:103
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$workspaceRec
‪array $workspaceRec
Definition: BackendUserAuthentication.php:106
‪TYPO3\CMS\Core\Type\Bitmask\JsConfirmation
Definition: JsConfirmation.php:24
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\checkFullLanguagesAccess
‪bool checkFullLanguagesAccess($table, $record)
Definition: BackendUserAuthentication.php:753
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\checkWorkspace
‪array checkWorkspace($wsRec, $fields='uid, title, adminusers, members, reviewers, publish_access, stagechg_notification')
Definition: BackendUserAuthentication.php:2157
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isPSet
‪bool isPSet($compiledPermissions, $tableName, $actionType='')
Definition: BackendUserAuthentication.php:905
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\workspaceCheckStageForCurrent
‪bool workspaceCheckStageForCurrent($stage)
Definition: BackendUserAuthentication.php:1110
‪TYPO3\CMS\Install\Service\SessionService
Definition: SessionService.php:30
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$fileStorages
‪TYPO3 CMS Core Resource ResourceStorage[] $fileStorages
Definition: BackendUserAuthentication.php:167
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$writeStdLog
‪bool $writeStdLog
Definition: BackendUserAuthentication.php:225
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication
Definition: AbstractUserAuthentication.php:51
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getDefaultWorkspace
‪int getDefaultWorkspace()
Definition: BackendUserAuthentication.php:2306
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\jsConfirmation
‪bool jsConfirmation($bitmask)
Definition: BackendUserAuthentication.php:1357
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$dataLists
‪array $dataLists
Definition: BackendUserAuthentication.php:114
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isInWebMount
‪int null isInWebMount($idOrRow, $readPerms='', $exitOnError=0)
Definition: BackendUserAuthentication.php:353
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\$errorMsg
‪string $errorMsg
Definition: BackendUserAuthentication.php:158
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\workspaceCannotEditOfflineVersion
‪string workspaceCannotEditOfflineVersion($table, $recData)
Definition: BackendUserAuthentication.php:1011
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getTSConfigVal
‪string getTSConfigVal($objectString)
Definition: BackendUserAuthentication.php:1269