Fixed bug #13493: Cleanup return value in t3lib_userauthgroup check() (Thanks to...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_userauthgroup.php
old mode 100755 (executable)
new mode 100644 (file)
index b85439f..82c991e
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -99,8 +99,6 @@
  *
  */
 
  *
  */
 
-       // Need this for parsing User TSconfig
-require_once (PATH_t3lib.'class.t3lib_tsparser.php');
 
 
 
 
 
 
@@ -149,6 +147,7 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
        var $dataLists=array(                           // Used internally to accumulate data for the user-group. DONT USE THIS EXTERNALLY! Use $this->groupData instead
                'webmount_list'=>'',
                'filemount_list'=>'',
        var $dataLists=array(                           // Used internally to accumulate data for the user-group. DONT USE THIS EXTERNALLY! Use $this->groupData instead
                'webmount_list'=>'',
                'filemount_list'=>'',
+               'fileoper_perms' => 0,
                'modList'=>'',
                'tables_select'=>'',
                'tables_modify'=>'',
                'modList'=>'',
                'tables_select'=>'',
                'tables_modify'=>'',
@@ -250,6 +249,13 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
        function isInWebMount($id,$readPerms='',$exitOnError=0) {
                if (!$GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts'] || $this->isAdmin())     return 1;
                $id = intval($id);
        function isInWebMount($id,$readPerms='',$exitOnError=0) {
                if (!$GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts'] || $this->isAdmin())     return 1;
                $id = intval($id);
+
+                       // Check if input id is an offline version page in which case we will map id to the online version:
+               $checkRec = t3lib_beFUnc::getRecord('pages',$id,'pid,t3ver_oid');
+               if ($checkRec['pid']==-1)       {
+                       $id = intval($checkRec['t3ver_oid']);
+               }
+
                if (!$readPerms)        $readPerms = $this->getPagePermsClause(1);
                if ($id>0)      {
                        $wM = $this->returnWebmounts();
                if (!$readPerms)        $readPerms = $this->getPagePermsClause(1);
                if ($id>0)      {
                        $wM = $this->returnWebmounts();
@@ -313,14 +319,14 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
 
        /**
         * Returns a WHERE-clause for the pages-table where user permissions according to input argument, $perms, is validated.
 
        /**
         * Returns a WHERE-clause for the pages-table where user permissions according to input argument, $perms, is validated.
-        * $perms is the 'mask' used to select. Fx. if $perms is 1 then you'll get all pages that a user can actually see!
+        * $perms is the "mask" used to select. Fx. if $perms is 1 then you'll get all pages that a user can actually see!
         *              2^0 = show (1)
         *              2^1 = edit (2)
         *              2^2 = delete (4)
         *              2^3 = new (8)
         * If the user is 'admin' " 1=1" is returned (no effect)
         * If the user is not set at all (->user is not an array), then " 1=0" is returned (will cause no selection results at all)
         *              2^0 = show (1)
         *              2^1 = edit (2)
         *              2^2 = delete (4)
         *              2^3 = new (8)
         * If the user is 'admin' " 1=1" is returned (no effect)
         * If the user is not set at all (->user is not an array), then " 1=0" is returned (will cause no selection results at all)
-        * The 95% use of this function is "->getPagePermsClause(1)" which will return WHERE clauses for *selecting* pages in backend listings - in other words will this check read permissions.
+        * The 95% use of this function is "->getPagePermsClause(1)" which will return WHERE clauses for *selecting* pages in backend listings - in other words this will check read permissions.
         *
         * @param       integer         Permission mask to use, see function description
         * @return      string          Part of where clause. Prefix " AND " to this.
         *
         * @param       integer         Permission mask to use, see function description
         * @return      string          Part of where clause. Prefix " AND " to this.
@@ -335,8 +341,10 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                        $perms = intval($perms);        // Make sure it's integer.
                        $str= ' ('.
                                '(pages.perms_everybody & '.$perms.' = '.$perms.')'.    // Everybody
                        $perms = intval($perms);        // Make sure it's integer.
                        $str= ' ('.
                                '(pages.perms_everybody & '.$perms.' = '.$perms.')'.    // Everybody
-                               'OR(pages.perms_userid = '.$this->user['uid'].' AND pages.perms_user & '.$perms.' = '.$perms.')';       // User
-                       if ($this->groupList){$str.='OR(pages.perms_groupid in ('.$this->groupList.') AND pages.perms_group & '.$perms.' = '.$perms.')';}       // Group (if any is set)
+                               ' OR (pages.perms_userid = '.$this->user['uid'].' AND pages.perms_user & '.$perms.' = '.$perms.')';     // User
+                       if ($this->groupList)   {
+                               $str.= ' OR (pages.perms_groupid in ('.$this->groupList.') AND pages.perms_group & '.$perms.' = '.$perms.')';   // Group (if any is set)
+                       }
                        $str.=')';
 
                        // ****************
                        $str.=')';
 
                        // ****************
@@ -414,7 +422,7 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
 
 
                        // Acquire RTE object:
 
 
                        // Acquire RTE object:
-               $RTE = &t3lib_BEfunc::RTEgetObj();
+               $RTE = t3lib_BEfunc::RTEgetObj();
                if (!is_object($RTE))   {
                        $this->RTE_errors = array_merge($this->RTE_errors, $RTE);
                }
                if (!is_object($RTE))   {
                        $this->RTE_errors = array_merge($this->RTE_errors, $RTE);
                }
@@ -436,12 +444,13 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
         * @param       string          String to search for in the groupData-list
         * @return      boolean         True if permission is granted (that is, the value was found in the groupData list - or the BE_USER is "admin")
         */
         * @param       string          String to search for in the groupData-list
         * @return      boolean         True if permission is granted (that is, the value was found in the groupData list - or the BE_USER is "admin")
         */
-       function check($type,$value)    {
-               if (isset($this->groupData[$type]))     {
-                       if ($this->isAdmin() || $this->inList($this->groupData[$type],$value)) {
-                               return 1;
+       function check($type, $value) {
+               if (isset($this->groupData[$type])) {
+                       if ($this->isAdmin() || $this->inList($this->groupData[$type], $value)) {
+                               return TRUE;
                        }
                }
                        }
                }
+               return FALSE;
        }
 
        /**
        }
 
        /**
@@ -463,7 +472,7 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                if (!strcmp($value,'')) return TRUE;
 
                        // Certain characters are not allowed in the value
                if (!strcmp($value,'')) return TRUE;
 
                        // Certain characters are not allowed in the value
-               if (ereg('[:|,]',$value))       {
+               if (preg_match('/[:|,]/',$value))       {
                        return FALSE;
                }
 
                        return FALSE;
                }
 
@@ -520,7 +529,7 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
         * @return      boolean         Returns true if the language value is allowed, otherwise false.
         */
        function checkLanguageAccess($langValue)        {
         * @return      boolean         Returns true if the language value is allowed, otherwise false.
         */
        function checkLanguageAccess($langValue)        {
-               if (strcmp($this->groupData['allowed_languages'],''))   {       // The users language list must be non-blank - otherwise all languages are allowed.
+               if (strcmp(trim($this->groupData['allowed_languages']),''))     {       // The users language list must be non-blank - otherwise all languages are allowed.
                        $langValue = intval($langValue);
                        if ($langValue != -1 && !$this->check('allowed_languages',$langValue))  {       // Language must either be explicitly allowed OR the lang Value be "-1" (all languages)
                                return FALSE;
                        $langValue = intval($langValue);
                        if ($langValue != -1 && !$this->check('allowed_languages',$langValue))  {       // Language must either be explicitly allowed OR the lang Value be "-1" (all languages)
                                return FALSE;
@@ -530,6 +539,42 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
        }
 
        /**
        }
 
        /**
+        * Check if user has access to all existing localizations for a certain record
+        *
+        * @param string        the table
+        * @param array         the current record
+        * @return boolean
+        */
+       function checkFullLanguagesAccess($table, $record) {
+               $recordLocalizationAccess = $this->checkLanguageAccess(0);
+               if ($recordLocalizationAccess && t3lib_BEfunc::isTableLocalizable($table)) {
+
+                       $pointerField = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'];
+
+                       $recordLocalizations = t3lib_BEfunc::getRecordsByField(
+                               $table,
+                               $pointerField,
+                               $record[$pointerField] > 0 ? $record[$pointerField] : $record['uid'],
+                               '',
+                               '',
+                               '',
+                               '1'
+                       );
+
+                       if (is_array($recordLocalizations)) {
+                               foreach($recordLocalizations as $localization) {
+                                       $recordLocalizationAccess = $recordLocalizationAccess && $this->checkLanguageAccess($localization[$GLOBALS['TCA'][$table]['ctrl']['languageField']]);
+                                       if (!$recordLocalizationAccess) {
+                                               break;
+                                       }
+                               }
+                       }
+
+               }
+               return $recordLocalizationAccess;
+       }
+
+       /**
         * Checking if a user has editing access to a record from a $TCA table.
         * The checks does not take page permissions and other "environmental" things into account. It only deal with record internals; If any values in the record fields disallows it.
         * For instance languages settings, authMode selector boxes are evaluated (and maybe more in the future).
         * Checking if a user has editing access to a record from a $TCA table.
         * The checks does not take page permissions and other "environmental" things into account. It only deal with record internals; If any values in the record fields disallows it.
         * For instance languages settings, authMode selector boxes are evaluated (and maybe more in the future).
@@ -539,9 +584,11 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
         * @param       string          Table name
         * @param       mixed           If integer, then this is the ID of the record. If Array this just represents fields in the record.
         * @param       boolean         Set, if testing a new (non-existing) record array. Will disable certain checks that doesn't make much sense in that context.
         * @param       string          Table name
         * @param       mixed           If integer, then this is the ID of the record. If Array this just represents fields in the record.
         * @param       boolean         Set, if testing a new (non-existing) record array. Will disable certain checks that doesn't make much sense in that context.
+        * @param       boolean         Set, if testing a deleted record array.
+        * @param       boolean         Set, whenever access to all translations of the record is required
         * @return      boolean         True if OK, otherwise false
         */
         * @return      boolean         True if OK, otherwise false
         */
-       function recordEditAccessInternals($table,$idOrRow,$newRecord=FALSE)    {
+       function recordEditAccessInternals($table, $idOrRow, $newRecord = FALSE, $deletedRecord = FALSE, $checkFullLanguageAccess = FALSE) {
                global $TCA;
 
                if (isset($TCA[$table]))        {
                global $TCA;
 
                if (isset($TCA[$table]))        {
@@ -552,7 +599,11 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
 
                                // Fetching the record if the $idOrRow variable was not an array on input:
                        if (!is_array($idOrRow))        {
 
                                // Fetching the record if the $idOrRow variable was not an array on input:
                        if (!is_array($idOrRow))        {
-                               $idOrRow = t3lib_BEfunc::getRecord($table, $idOrRow);
+                               if ($deletedRecord) {
+                                       $idOrRow = t3lib_BEfunc::getRecord($table, $idOrRow, '*', '', FALSE);
+                               } else {
+                                       $idOrRow = t3lib_BEfunc::getRecord($table, $idOrRow);
+                               }
                                if (!is_array($idOrRow))        {
                                        $this->errorMsg = 'ERROR: Record could not be fetched.';
                                        return FALSE;
                                if (!is_array($idOrRow))        {
                                        $this->errorMsg = 'ERROR: Record could not be fetched.';
                                        return FALSE;
@@ -565,6 +616,9 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                                        if (!$this->checkLanguageAccess($idOrRow[$TCA[$table]['ctrl']['languageField']]))       {
                                                $this->errorMsg = 'ERROR: Language was not allowed.';
                                                return FALSE;
                                        if (!$this->checkLanguageAccess($idOrRow[$TCA[$table]['ctrl']['languageField']]))       {
                                                $this->errorMsg = 'ERROR: Language was not allowed.';
                                                return FALSE;
+                                       } elseif ($checkFullLanguageAccess && $idOrRow[$TCA[$table]['ctrl']['languageField']]==0 && !$this->checkFullLanguagesAccess($table, $idOrRow)) {
+                                               $this->errorMsg = 'ERROR: Related/affected language was not allowed.';
+                                               return FALSE;
                                        }
                                } else {
                                        $this->errorMsg = 'ERROR: The "languageField" field named "'.$TCA[$table]['ctrl']['languageField'].'" was not found in testing record!';
                                        }
                                } else {
                                        $this->errorMsg = 'ERROR: The "languageField" field named "'.$TCA[$table]['ctrl']['languageField'].'" was not found in testing record!';
@@ -602,6 +656,20 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                                // Checking record permissions
                        // THIS is where we can include a check for "perms_" fields for other records than pages...
 
                                // Checking record permissions
                        // THIS is where we can include a check for "perms_" fields for other records than pages...
 
+                               // Process any hooks
+                       if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['recordEditAccessInternals']))    {
+                               foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['recordEditAccessInternals'] as $funcRef)     {
+                                       $params = array(
+                                               'table' => $table,
+                                               'idOrRow' => $idOrRow,
+                                               'newRecord' => $newRecord
+                                       );
+                                       if (!t3lib_div::callUserFunction($funcRef, $params, $this)) {
+                                               return FALSE;
+                                       }
+                               }
+                       }
+
                                // Finally, return true if all is well.
                        return TRUE;
                }
                                // Finally, return true if all is well.
                        return TRUE;
                }
@@ -634,7 +702,19 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
         * @return      boolean
         */
        function mayMakeShortcut()      {
         * @return      boolean
         */
        function mayMakeShortcut()      {
-               return $this->getTSConfigVal('options.shortcutFrame') && !$this->getTSConfigVal('options.mayNotCreateEditShortcuts');
+                       // If the old BE is used (maybe with some parameters),
+                       // check for options.enableShortcuts and options.shortcutFrame being set.
+               if (substr($this->getTSConfigVal('auth.BE.redirectToURL'), 0, 12) == 'alt_main.php') {
+                       return $this->getTSConfigVal('options.enableShortcuts') &&
+                               $this->getTSConfigVal('options.shortcutFrame') &&
+                               !$this->getTSConfigVal('options.mayNotCreateEditShortcuts');
+               }
+                       // If the new BE is used, don't check options.shortcutFrame,
+                       // because this is not used there anymore.
+               else {
+                       return $this->getTSConfigVal('options.enableShortcuts') &&
+                               !$this->getTSConfigVal('options.mayNotCreateEditShortcuts');
+               }
        }
 
        /**
        }
 
        /**
@@ -712,7 +792,7 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
        function workspaceAllowLiveRecordsInPID($pid, $table)   {
 
                        // Always for Live workspace AND if live-edit is enabled and tables are completely without versioning it is ok as well.
        function workspaceAllowLiveRecordsInPID($pid, $table)   {
 
                        // Always for Live workspace AND if live-edit is enabled and tables are completely without versioning it is ok as well.
-               if ($this->workspace===0 || ($this->workspaceRec['live_edit'] && !$GLOBALS['TCA'][$table]['ctrl']['versioningWS']))     {
+               if ($this->workspace===0 || ($this->workspaceRec['live_edit'] && !$GLOBALS['TCA'][$table]['ctrl']['versioningWS']) || $GLOBALS['TCA'][$table]['ctrl']['versioningWS_alwaysAllowLiveEdit'])      {
                        return 2;       // OK to create for this table.
                } elseif (t3lib_BEfunc::isPidInVersionizedBranch($pid, $table)) {       // Check if records from $table can be created with this PID: Either if inside "branch" versioning type or a "versioning_followPages" table on a "page" versioning type.
                                // Now, check what the stage of that "page" or "branch" version type is:
                        return 2;       // OK to create for this table.
                } elseif (t3lib_BEfunc::isPidInVersionizedBranch($pid, $table)) {       // Check if records from $table can be created with this PID: Either if inside "branch" versioning type or a "versioning_followPages" table on a "page" versioning type.
                                // Now, check what the stage of that "page" or "branch" version type is:
@@ -765,6 +845,7 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
         * Checks if an element stage allows access for the user in the current workspace
         * In workspaces 0 (Live) and -1 (Default draft) access is always granted for any stage.
         * Admins are always allowed.
         * Checks if an element stage allows access for the user in the current workspace
         * In workspaces 0 (Live) and -1 (Default draft) access is always granted for any stage.
         * Admins are always allowed.
+        * An option for custom workspaces allows members to also edit when the stage is "Review"
         *
         * @param       integer         Stage id from an element: -1,0 = editing, 1 = reviewer, >1 = owner
         * @return      boolean         TRUE if user is allowed access
         *
         * @param       integer         Stage id from an element: -1,0 = editing, 1 = reviewer, >1 = owner
         * @return      boolean         TRUE if user is allowed access
@@ -774,7 +855,8 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
 
                if ($this->workspace>0) {
                        $stat = $this->checkWorkspaceCurrent();
 
                if ($this->workspace>0) {
                        $stat = $this->checkWorkspaceCurrent();
-                       if (($stage<=0 && $stat['_ACCESS']==='member') ||
+                       $memberStageLimit = $this->workspaceRec['review_stage_edit'] ? 1 : 0;
+                       if (($stage<=$memberStageLimit && $stat['_ACCESS']==='member') ||
                                ($stage<=1 && $stat['_ACCESS']==='reviewer') ||
                                ($stat['_ACCESS']==='owner')) {
                                        return TRUE;    // OK for these criteria
                                ($stage<=1 && $stat['_ACCESS']==='reviewer') ||
                                ($stat['_ACCESS']==='owner')) {
                                        return TRUE;    // OK for these criteria
@@ -835,11 +917,17 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
        function workspaceVersioningTypeAccess($type)   {
                $retVal = FALSE;
 
        function workspaceVersioningTypeAccess($type)   {
                $retVal = FALSE;
 
+               $type = t3lib_div::intInRange($type,-1);
+
+                       // Check if only element versioning is allowed:
+               if ($GLOBALS['TYPO3_CONF_VARS']['BE']['elementVersioningOnly'] && $type!=-1)    {
+                       return FALSE;
+               }
+
                if ($this->workspace>0 && !$this->isAdmin())    {
                        $stat = $this->checkWorkspaceCurrent();
                        if ($stat['_ACCESS']!=='owner') {
 
                if ($this->workspace>0 && !$this->isAdmin())    {
                        $stat = $this->checkWorkspaceCurrent();
                        if ($stat['_ACCESS']!=='owner') {
 
-                               $type = t3lib_div::intInRange($type,-1);
                                switch((int)$type)      {
                                        case -1:
                                                $retVal = $this->workspaceRec['vtypes']&1 ? FALSE : TRUE;
                                switch((int)$type)      {
                                        case -1:
                                                $retVal = $this->workspaceRec['vtypes']&1 ? FALSE : TRUE;
@@ -982,6 +1070,27 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
        }
 
        /**
        }
 
        /**
+        * Returns an integer bitmask that represents the permissions for file operations.
+        * Permissions of the user and groups the user is a member of were combined by a logical OR.
+        *
+        * Meaning of each bit:
+        *      1 - Files: Upload,Copy,Move,Delete,Rename
+        *      2 - Files: Unzip
+        *      4 - Directory: Move,Delete,Rename,New
+        *      8 - Directory: Copy
+        *      16 - Directory: Delete recursively (rm -Rf)
+        *
+        * @return      integer         File operation permission bitmask
+        */
+       public function getFileoperationPermissions() {
+               if ($this->isAdmin()) {
+                       return 31;
+               } else {
+                       return $this->groupData['fileoper_perms'];
+               }
+       }
+
+       /**
         * Returns true or false, depending if an alert popup (a javascript confirmation) should be shown
         * call like $GLOBALS['BE_USER']->jsConfirmation($BITMASK)
         *
         * Returns true or false, depending if an alert popup (a javascript confirmation) should be shown
         * call like $GLOBALS['BE_USER']->jsConfirmation($BITMASK)
         *
@@ -1041,6 +1150,7 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                        $this->dataLists['workspace_perms'] = $this->user['workspace_perms'];                                   // Set user value for workspace permissions.
                        $this->dataLists['webmount_list'] = $this->user['db_mountpoints'];              // Database mountpoints
                        $this->dataLists['filemount_list'] = $this->user['file_mountpoints'];   // File mountpoints
                        $this->dataLists['workspace_perms'] = $this->user['workspace_perms'];                                   // Set user value for workspace permissions.
                        $this->dataLists['webmount_list'] = $this->user['db_mountpoints'];              // Database mountpoints
                        $this->dataLists['filemount_list'] = $this->user['file_mountpoints'];   // File mountpoints
+                       $this->dataLists['fileoper_perms'] = (int)$this->user['fileoper_perms'];        // Fileoperation permissions
 
                                // Setting default User TSconfig:
                        $this->TSdataArray[]=$this->addTScomment('From $GLOBALS["TYPO3_CONF_VARS"]["BE"]["defaultUserTSconfig"]:').
 
                                // Setting default User TSconfig:
                        $this->TSdataArray[]=$this->addTScomment('From $GLOBALS["TYPO3_CONF_VARS"]["BE"]["defaultUserTSconfig"]:').
@@ -1091,19 +1201,30 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                                // Check include lines.
                        $this->TSdataArray = t3lib_TSparser::checkIncludeLines_array($this->TSdataArray);
 
                                // Check include lines.
                        $this->TSdataArray = t3lib_TSparser::checkIncludeLines_array($this->TSdataArray);
 
-                               // Parsing the user TSconfig (or getting from cache)
                        $this->userTS_text = implode(chr(10).'[GLOBAL]'.chr(10),$this->TSdataArray);    // Imploding with "[global]" will make sure that non-ended confinements with braces are ignored.
                        $this->userTS_text = implode(chr(10).'[GLOBAL]'.chr(10),$this->TSdataArray);    // Imploding with "[global]" will make sure that non-ended confinements with braces are ignored.
-                       $hash = md5('userTS:'.$this->userTS_text);
-                       $cachedContent = t3lib_BEfunc::getHash($hash,0);
-                       if (isset($cachedContent) && !$this->userTS_dontGetCached)      {
-                               $this->userTS = unserialize($cachedContent);
+
+                       if ($GLOBALS['TYPO3_CONF_VARS']['BE']['TSconfigConditions'] && !$this->userTS_dontGetCached) {
+                                       // Perform TS-Config parsing with condition matching
+                               $parseObj = t3lib_div::makeInstance('t3lib_TSparser_TSconfig');
+                               $res = $parseObj->parseTSconfig($this->userTS_text, 'userTS');
+                               if ($res) {
+                                       $this->userTS = $res['TSconfig'];
+                                       $this->userTSUpdated = ($res['cached'] ? 0 : 1);
+                               }
                        } else {
                        } else {
-                               $parseObj = t3lib_div::makeInstance('t3lib_TSparser');
-                               $parseObj->parse($this->userTS_text);
-                               $this->userTS = $parseObj->setup;
-                               t3lib_BEfunc::storeHash($hash,serialize($this->userTS),'BE_USER_TSconfig');
-                                       // Update UC:
-                               $this->userTSUpdated=1;
+                                       // Parsing the user TSconfig (or getting from cache)
+                               $hash = md5('userTS:' . $this->userTS_text);
+                               $cachedContent = t3lib_BEfunc::getHash($hash);
+                               if (isset($cachedContent) && !$this->userTS_dontGetCached) {
+                                       $this->userTS = unserialize($cachedContent);
+                               } else {
+                                       $parseObj = t3lib_div::makeInstance('t3lib_TSparser');
+                                       $parseObj->parse($this->userTS_text);
+                                       $this->userTS = $parseObj->setup;
+                                       t3lib_BEfunc::storeHash($hash, serialize($this->userTS), 'BE_USER_TSconfig');
+                                               // Update UC:
+                                       $this->userTSUpdated=1;
+                               }
                        }
 
                                // Processing webmounts
                        }
 
                                // Processing webmounts
@@ -1112,9 +1233,11 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                        }
 
                                // Processing filemounts
                        }
 
                                // Processing filemounts
+                       t3lib_div::loadTCA('sys_filemounts');
+                       $orderBy = $GLOBALS['TCA']['sys_filemounts']['ctrl']['default_sortby'] ? $GLOBALS['TYPO3_DB']->stripOrderBy($GLOBALS['TCA']['sys_filemounts']['ctrl']['default_sortby']) : 'sorting';
                        $this->dataLists['filemount_list'] = t3lib_div::uniqueList($this->dataLists['filemount_list']);
                        if ($this->dataLists['filemount_list']) {
                        $this->dataLists['filemount_list'] = t3lib_div::uniqueList($this->dataLists['filemount_list']);
                        if ($this->dataLists['filemount_list']) {
-                               $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_filemounts', 'deleted=0 AND hidden=0 AND pid=0 AND uid IN ('.$this->dataLists['filemount_list'].')');
+                               $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_filemounts', 'deleted=0 AND hidden=0 AND pid=0 AND uid IN ('.$this->dataLists['filemount_list'].')', '', $orderBy);
                                while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
                                        $this->addFileMount($row['title'], $row['path'], $row['path'], $row['base']?1:0, '');
                                }
                                while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
                                        $this->addFileMount($row['title'], $row['path'], $row['path'], $row['base']?1:0, '');
                                }
@@ -1130,6 +1253,7 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                        $this->groupData['allowed_languages'] = t3lib_div::uniqueList($this->dataLists['allowed_languages']);
                        $this->groupData['custom_options'] = t3lib_div::uniqueList($this->dataLists['custom_options']);
                        $this->groupData['modules'] = t3lib_div::uniqueList($this->dataLists['modList']);
                        $this->groupData['allowed_languages'] = t3lib_div::uniqueList($this->dataLists['allowed_languages']);
                        $this->groupData['custom_options'] = t3lib_div::uniqueList($this->dataLists['custom_options']);
                        $this->groupData['modules'] = t3lib_div::uniqueList($this->dataLists['modList']);
+                       $this->groupData['fileoper_perms'] = $this->dataLists['fileoper_perms'];
                        $this->groupData['workspace_perms'] = $this->dataLists['workspace_perms'];
 
                                // populating the $this->userGroupsUID -array with the groups in the order in which they were LAST included.!!
                        $this->groupData['workspace_perms'] = $this->dataLists['workspace_perms'];
 
                                // populating the $this->userGroupsUID -array with the groups in the order in which they were LAST included.!!
@@ -1169,17 +1293,17 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                global $TYPO3_CONF_VARS;
 
                        // Fetching records of the groups in $grList (which are not blocked by lockedToDomain either):
                global $TYPO3_CONF_VARS;
 
                        // Fetching records of the groups in $grList (which are not blocked by lockedToDomain either):
-               $lockToDomain_SQL = ' AND (lockToDomain=\'\' OR lockToDomain=\''.t3lib_div::getIndpEnv('HTTP_HOST').'\')';
+               $lockToDomain_SQL = ' AND (lockToDomain=\'\' OR lockToDomain IS NULL OR lockToDomain=\''.t3lib_div::getIndpEnv('HTTP_HOST').'\')';
                $whereSQL = 'deleted=0 AND hidden=0 AND pid=0 AND uid IN ('.$grList.')'.$lockToDomain_SQL;
 
                        // Hook for manipulation of the WHERE sql sentence which controls which BE-groups are included
                if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['fetchGroupQuery'])) {
                $whereSQL = 'deleted=0 AND hidden=0 AND pid=0 AND uid IN ('.$grList.')'.$lockToDomain_SQL;
 
                        // Hook for manipulation of the WHERE sql sentence which controls which BE-groups are included
                if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['fetchGroupQuery'])) {
-                   foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['fetchGroupQuery'] as $classRef) {
-                       $hookObj = &t3lib_div::getUserObj($classRef);
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['fetchGroupQuery'] as $classRef) {
+                       $hookObj = t3lib_div::getUserObj($classRef);
                        if(method_exists($hookObj,'fetchGroupQuery_processQuery')){
                        if(method_exists($hookObj,'fetchGroupQuery_processQuery')){
-                           $whereSQL = $hookObj->fetchGroupQuery_processQuery($this, $grList, $idList, $whereSQL);
+                               $whereSQL = $hookObj->fetchGroupQuery_processQuery($this, $grList, $idList, $whereSQL);
+                       }
                        }
                        }
-                   }
                }
 
                $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $this->usergroup_table, $whereSQL);
                }
 
                $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $this->usergroup_table, $whereSQL);
@@ -1234,6 +1358,9 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                                        $this->dataLists['custom_options'].= ','.$row['custom_options'];
                                }
 
                                        $this->dataLists['custom_options'].= ','.$row['custom_options'];
                                }
 
+                               // Setting fileoperation permissions
+                               $this->dataLists['fileoper_perms'] |= (int)$row['fileoper_perms'];
+
                                        // Setting workspace permissions:
                                $this->dataLists['workspace_perms'] |= $row['workspace_perms'];
 
                                        // Setting workspace permissions:
                                $this->dataLists['workspace_perms'] |= $row['workspace_perms'];
 
@@ -1399,6 +1526,11 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                                $this->addFileMount($row['title'], $row['path'], $row['path'], $row['base']?1:0, '');
                        }
                }
                                $this->addFileMount($row['title'], $row['path'], $row['path'], $row['base']?1:0, '');
                        }
                }
+
+               if ($allowed_languages = $this->getTSConfigVal('options.workspaces.allowed_languages.'.$this->workspace))       {
+                       $this->groupData['allowed_languages'] = $allowed_languages;
+                       $this->groupData['allowed_languages'] = t3lib_div::uniqueList($this->groupData['allowed_languages']);
+               }
        }
 
        /**
        }
 
        /**
@@ -1643,7 +1775,7 @@ class t3lib_userAuthGroup extends t3lib_userAuth {
                if ($email)     {
 
                                // get last flag set in the log for sending
                if ($email)     {
 
                                // get last flag set in the log for sending
-                       $theTimeBack = time()-$secondsBack;
+                       $theTimeBack = $GLOBALS['EXEC_TIME'] - $secondsBack;
                        $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
                                                        'tstamp',
                                                        'sys_log',
                        $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
                                                        'tstamp',
                                                        'sys_log',
@@ -1676,13 +1808,13 @@ This is a dump of the failures:
 ';
                                while($testRows = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))  {
                                        $theData = unserialize($testRows['log_data']);
 ';
                                while($testRows = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))  {
                                        $theData = unserialize($testRows['log_data']);
-                                       $email_body.=date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'].' H:i',$testRows['tstamp']).':  '.@sprintf($testRows['details'],''.$theData[0],''.$theData[1],''.$theData[2]);
-                                       $email_body.=chr(10);
+                                       $email_body.= date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'].' '.$GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'],$testRows['tstamp']).':  '.@sprintf($testRows['details'],''.$theData[0],''.$theData[1],''.$theData[2]);
+                                       $email_body.= chr(10);
                                }
                                mail(   $email,
                                }
                                mail(   $email,
-                                               $subject,
-                                               $email_body,
-                                               'From: TYPO3 Login WARNING<>'
+                                       $subject,
+                                       $email_body,
+                                       'From: TYPO3 Login WARNING<>'
                                );
                                $this->writelog(255,4,0,3,'Failure warning (%s failures within %s seconds) sent by email to %s',Array($GLOBALS['TYPO3_DB']->sql_num_rows($res),$secondsBack,$email));   // Logout written to log
                        }
                                );
                                $this->writelog(255,4,0,3,'Failure warning (%s failures within %s seconds) sent by email to %s',Array($GLOBALS['TYPO3_DB']->sql_num_rows($res),$secondsBack,$email));   // Logout written to log
                        }
@@ -1695,4 +1827,5 @@ This is a dump of the failures:
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_userauthgroup.php'])    {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_userauthgroup.php']);
 }
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_userauthgroup.php'])    {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_userauthgroup.php']);
 }
-?>
+
+?>
\ No newline at end of file