Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00102 // Need this for parsing User TSconfig 00103 require_once (PATH_t3lib.'class.t3lib_tsparser.php'); 00104 00105 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117 00118 00119 00120 00121 00122 00123 00124 00135 class t3lib_userAuthGroup extends t3lib_userAuth { 00136 var $usergroup_column = 'usergroup'; // Should be set to the usergroup-column (id-list) in the user-record 00137 var $usergroup_table = 'be_groups'; // The name of the group-table 00138 00139 // internal 00140 var $groupData = Array( // This array holds lists of eg. tables, fields and other values related to the permission-system. See fetchGroupData 00141 'filemounts' => Array() // Filemounts are loaded here 00142 ); 00143 var $workspace = -99; // User workspace. -99 is ERROR (none available), -1 is offline, 0 is online, >0 is custom workspaces. 00144 var $workspaceRec = array(); // Custom workspace record if any 00145 00146 var $userGroups = Array(); // This array will hold the groups that the user is a member of 00147 var $userGroupsUID = Array(); // This array holds the uid's of the groups in the listed order 00148 var $groupList =''; // This is $this->userGroupsUID imploded to a comma list... Will correspond to the 'usergroup_cached_list' 00149 var $dataLists=array( // Used internally to accumulate data for the user-group. DONT USE THIS EXTERNALLY! Use $this->groupData instead 00150 'webmount_list'=>'', 00151 'filemount_list'=>'', 00152 'modList'=>'', 00153 'tables_select'=>'', 00154 'tables_modify'=>'', 00155 'pagetypes_select'=>'', 00156 'non_exclude_fields'=>'', 00157 'explicit_allowdeny'=>'', 00158 'allowed_languages' => '', 00159 'workspace_perms' => '', 00160 'custom_options' => '', 00161 ); 00162 var $includeHierarchy=array(); // For debugging/display of order in which subgroups are included. 00163 var $includeGroupArray=array(); // List of group_id's in the order they are processed. 00164 00165 var $OS=''; // Set to 'WIN', if windows 00166 var $TSdataArray=array(); // Used to accumulate the TSconfig data of the user 00167 var $userTS_text = ''; // Contains the non-parsed user TSconfig 00168 var $userTS = array(); // Contains the parsed user TSconfig 00169 var $userTSUpdated=0; // Set internally if the user TSconfig was parsed and needs to be cached. 00170 var $userTS_dontGetCached=0; // Set this from outside if you want the user TSconfig to ALWAYS be parsed and not fetched from cache. 00171 00172 var $RTE_errors = array(); // RTE availability errors collected. 00173 var $errorMsg = ''; // Contains last error message 00174 00175 var $checkWorkspaceCurrent_cache=NULL; // Cache for checkWorkspaceCurrent() 00176 00177 00178 00179 00180 00181 00182 00183 00184 00185 00186 00187 /************************************ 00188 * 00189 * Permission checking functions: 00190 * 00191 ************************************/ 00192 00199 function isAdmin() { 00200 return (($this->user['admin']&1) ==1); 00201 } 00202 00211 function isMemberOfGroup($groupId) { 00212 $groupId = intval($groupId); 00213 if ($this->groupList && $groupId) { 00214 return $this->inList($this->groupList, $groupId); 00215 } 00216 } 00217 00233 function doesUserHaveAccess($row,$perms) { 00234 $userPerms = $this->calcPerms($row); 00235 return ($userPerms & $perms)==$perms; 00236 } 00237 00250 function isInWebMount($id,$readPerms='',$exitOnError=0) { 00251 if (!$GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts'] || $this->isAdmin()) return 1; 00252 $id = intval($id); 00253 if (!$readPerms) $readPerms = $this->getPagePermsClause(1); 00254 if ($id>0) { 00255 $wM = $this->returnWebmounts(); 00256 $rL = t3lib_BEfunc::BEgetRootLine($id,' AND '.$readPerms); 00257 00258 foreach($rL as $v) { 00259 if ($v['uid'] && in_array($v['uid'],$wM)) { 00260 return $v['uid']; 00261 } 00262 } 00263 } 00264 if ($exitOnError) { 00265 t3lib_BEfunc::typo3PrintError ('Access Error','This page is not within your DB-mounts',0); 00266 exit; 00267 } 00268 } 00269 00277 function modAccess($conf,$exitOnError) { 00278 if (!t3lib_BEfunc::isModuleSetInTBE_MODULES($conf['name'])) { 00279 if ($exitOnError) { 00280 t3lib_BEfunc::typo3PrintError ('Fatal Error','This module "'.$conf['name'].'" is not enabled in TBE_MODULES',0); 00281 exit; 00282 } 00283 return FALSE; 00284 } 00285 00286 // Workspaces check: 00287 if ($conf['workspaces']) { 00288 if (($this->workspace===0 && t3lib_div::inList($conf['workspaces'],'online')) || 00289 ($this->workspace===-1 && t3lib_div::inList($conf['workspaces'],'offline')) || 00290 ($this->workspace>0 && t3lib_div::inList($conf['workspaces'],'custom'))) { 00291 // ok, go on... 00292 } else { 00293 if ($exitOnError) { 00294 t3lib_BEfunc::typo3PrintError ('Workspace Error','This module "'.$conf['name'].'" is not available under the current workspace',0); 00295 exit; 00296 } 00297 return FALSE; 00298 } 00299 } 00300 00301 // Returns true if conf[access] is not set at all or if the user is admin 00302 if (!$conf['access'] || $this->isAdmin()) return TRUE; 00303 00304 // If $conf['access'] is set but not with 'admin' then we return true, if the module is found in the modList 00305 if (!strstr($conf['access'],'admin') && $conf['name']) { 00306 $acs = $this->check('modules',$conf['name']); 00307 } 00308 if (!$acs && $exitOnError) { 00309 t3lib_BEfunc::typo3PrintError ('Access Error','You don\'t have access to this module.',0); 00310 exit; 00311 } else return $acs; 00312 } 00313 00328 function getPagePermsClause($perms) { 00329 global $TYPO3_CONF_VARS; 00330 if (is_array($this->user)) { 00331 if ($this->isAdmin()) { 00332 return ' 1=1'; 00333 } 00334 00335 $perms = intval($perms); // Make sure it's integer. 00336 $str= ' ('. 00337 '(pages.perms_everybody & '.$perms.' = '.$perms.')'. // Everybody 00338 'OR(pages.perms_userid = '.$this->user['uid'].' AND pages.perms_user & '.$perms.' = '.$perms.')'; // User 00339 if ($this->groupList){$str.='OR(pages.perms_groupid in ('.$this->groupList.') AND pages.perms_group & '.$perms.' = '.$perms.')';} // Group (if any is set) 00340 $str.=')'; 00341 00342 // **************** 00343 // getPagePermsClause-HOOK 00344 // **************** 00345 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['getPagePermsClause'])) { 00346 00347 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['getPagePermsClause'] as $_funcRef) { 00348 $_params = array('currentClause' => $str, 'perms' => $perms); 00349 $str = t3lib_div::callUserFunction($_funcRef, $_params, $this); 00350 } 00351 } 00352 00353 return $str; 00354 } else { 00355 return ' 1=0'; 00356 } 00357 } 00358 00367 function calcPerms($row) { 00368 global $TYPO3_CONF_VARS; 00369 if ($this->isAdmin()) {return 31;} // Return 31 for admin users. 00370 00371 $out=0; 00372 if (isset($row['perms_userid']) && isset($row['perms_user']) && isset($row['perms_groupid']) && isset($row['perms_group']) && isset($row['perms_everybody']) && isset($this->groupList)) { 00373 if ($this->user['uid']==$row['perms_userid']) { 00374 $out|=$row['perms_user']; 00375 } 00376 if ($this->isMemberOfGroup($row['perms_groupid'])) { 00377 $out|=$row['perms_group']; 00378 } 00379 $out|=$row['perms_everybody']; 00380 } 00381 00382 // **************** 00383 // CALCPERMS hook 00384 // **************** 00385 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['calcPerms'])) { 00386 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['calcPerms'] as $_funcRef) { 00387 $_params = array( 00388 'row' => $row, 00389 'outputPermissions' => $out 00390 ); 00391 $out = t3lib_div::callUserFunction($_funcRef, $_params, $this); 00392 } 00393 } 00394 00395 return $out; 00396 } 00397 00405 function isRTE() { 00406 global $CLIENT; 00407 00408 // Start: 00409 $this->RTE_errors = array(); 00410 if (!$this->uc['edit_RTE']) 00411 $this->RTE_errors[] = 'RTE is not enabled for user!'; 00412 if (!$GLOBALS['TYPO3_CONF_VARS']['BE']['RTEenabled']) 00413 $this->RTE_errors[] = 'RTE is not enabled in $TYPO3_CONF_VARS["BE"]["RTEenabled"]'; 00414 00415 00416 // Acquire RTE object: 00417 $RTE = &t3lib_BEfunc::RTEgetObj(); 00418 if (!is_object($RTE)) { 00419 $this->RTE_errors = array_merge($this->RTE_errors, $RTE); 00420 } 00421 00422 if (!count($this->RTE_errors)) { 00423 return TRUE; 00424 } else { 00425 return FALSE; 00426 } 00427 } 00428 00439 function check($type,$value) { 00440 if (isset($this->groupData[$type])) { 00441 if ($this->isAdmin() || $this->inList($this->groupData[$type],$value)) { 00442 return 1; 00443 } 00444 } 00445 } 00446 00456 function checkAuthMode($table,$field,$value,$authMode) { 00457 global $TCA; 00458 00459 // Admin users can do anything: 00460 if ($this->isAdmin()) return TRUE; 00461 00462 // Allow all blank values: 00463 if (!strcmp($value,'')) return TRUE; 00464 00465 // Certain characters are not allowed in the value 00466 if (ereg('[:|,]',$value)) { 00467 return FALSE; 00468 } 00469 00470 // Initialize: 00471 $testValue = $table.':'.$field.':'.$value; 00472 $out = TRUE; 00473 00474 // Checking value: 00475 switch((string)$authMode) { 00476 case 'explicitAllow': 00477 if (!$this->inList($this->groupData['explicit_allowdeny'],$testValue.':ALLOW')) { 00478 $out = FALSE; 00479 } 00480 break; 00481 case 'explicitDeny': 00482 if ($this->inList($this->groupData['explicit_allowdeny'],$testValue.':DENY')) { 00483 $out = FALSE; 00484 } 00485 break; 00486 case 'individual': 00487 t3lib_div::loadTCA($table); 00488 if (is_array($TCA[$table]) && is_array($TCA[$table]['columns'][$field])) { 00489 $items = $TCA[$table]['columns'][$field]['config']['items']; 00490 if (is_array($items)) { 00491 foreach($items as $iCfg) { 00492 if (!strcmp($iCfg[1],$value) && $iCfg[4]) { 00493 switch((string)$iCfg[4]) { 00494 case 'EXPL_ALLOW': 00495 if (!$this->inList($this->groupData['explicit_allowdeny'],$testValue.':ALLOW')) { 00496 $out = FALSE; 00497 } 00498 break; 00499 case 'EXPL_DENY': 00500 if ($this->inList($this->groupData['explicit_allowdeny'],$testValue.':DENY')) { 00501 $out = FALSE; 00502 } 00503 break; 00504 } 00505 break; 00506 } 00507 } 00508 } 00509 } 00510 break; 00511 } 00512 00513 return $out; 00514 } 00515 00522 function checkLanguageAccess($langValue) { 00523 if (strcmp($this->groupData['allowed_languages'],'')) { // The users language list must be non-blank - otherwise all languages are allowed. 00524 $langValue = intval($langValue); 00525 if ($langValue != -1 && !$this->check('allowed_languages',$langValue)) { // Language must either be explicitly allowed OR the lang Value be "-1" (all languages) 00526 return FALSE; 00527 } 00528 } 00529 return TRUE; 00530 } 00531 00544 function recordEditAccessInternals($table,$idOrRow,$newRecord=FALSE) { 00545 global $TCA; 00546 00547 if (isset($TCA[$table])) { 00548 t3lib_div::loadTCA($table); 00549 00550 // Always return true for Admin users. 00551 if ($this->isAdmin()) return TRUE; 00552 00553 // Fetching the record if the $idOrRow variable was not an array on input: 00554 if (!is_array($idOrRow)) { 00555 $idOrRow = t3lib_BEfunc::getRecord($table, $idOrRow); 00556 if (!is_array($idOrRow)) { 00557 $this->errorMsg = 'ERROR: Record could not be fetched.'; 00558 return FALSE; 00559 } 00560 } 00561 00562 // Checking languages: 00563 if ($TCA[$table]['ctrl']['languageField']) { 00564 if (isset($idOrRow[$TCA[$table]['ctrl']['languageField']])) { // Language field must be found in input row - otherwise it does not make sense. 00565 if (!$this->checkLanguageAccess($idOrRow[$TCA[$table]['ctrl']['languageField']])) { 00566 $this->errorMsg = 'ERROR: Language was not allowed.'; 00567 return FALSE; 00568 } 00569 } else { 00570 $this->errorMsg = 'ERROR: The "languageField" field named "'.$TCA[$table]['ctrl']['languageField'].'" was not found in testing record!'; 00571 return FALSE; 00572 } 00573 } 00574 00575 // Checking authMode fields: 00576 if (is_array($TCA[$table]['columns'])) { 00577 foreach($TCA[$table]['columns'] as $fN => $fV) { 00578 if (isset($idOrRow[$fN])) { // 00579 if ($fV['config']['type']=='select' && $fV['config']['authMode'] && !strcmp($fV['config']['authMode_enforce'],'strict')) { 00580 if (!$this->checkAuthMode($table,$fN,$idOrRow[$fN],$fV['config']['authMode'])) { 00581 $this->errorMsg = 'ERROR: authMode "'.$fV['config']['authMode'].'" failed for field "'.$fN.'" with value "'.$idOrRow[$fN].'" evaluated'; 00582 return FALSE; 00583 } 00584 } 00585 } 00586 } 00587 } 00588 00589 // Checking "editlock" feature (doesn't apply to new records) 00590 if (!$newRecord && $TCA[$table]['ctrl']['editlock']) { 00591 if (isset($idOrRow[$TCA[$table]['ctrl']['editlock']])) { 00592 if ($idOrRow[$TCA[$table]['ctrl']['editlock']]) { 00593 $this->errorMsg = 'ERROR: Record was locked for editing. Only admin users can change this state.'; 00594 return FALSE; 00595 } 00596 } else { 00597 $this->errorMsg = 'ERROR: The "editLock" field named "'.$TCA[$table]['ctrl']['editlock'].'" was not found in testing record!'; 00598 return FALSE; 00599 } 00600 } 00601 00602 // Checking record permissions 00603 // THIS is where we can include a check for "perms_" fields for other records than pages... 00604 00605 // Finally, return true if all is well. 00606 return TRUE; 00607 } 00608 } 00609 00619 function isPSet($lCP,$table,$type='') { 00620 if ($this->isAdmin()) return true; 00621 if ($table=='pages') { 00622 if ($type=='edit') return $lCP & 2; 00623 if ($type=='new') return ($lCP & 8) || ($lCP & 16); // Create new page OR pagecontent 00624 if ($type=='delete') return $lCP & 4; 00625 if ($type=='editcontent') return $lCP & 16; 00626 } else { 00627 return $lCP & 16; 00628 } 00629 } 00630 00636 function mayMakeShortcut() { 00637 return $this->getTSConfigVal('options.shortcutFrame') && !$this->getTSConfigVal('options.mayNotCreateEditShortcuts'); 00638 } 00639 00650 function workspaceCannotEditRecord($table,$recData) { 00651 00652 if ($this->workspace!==0) { // Only test offline spaces: 00653 00654 if (!is_array($recData)) { 00655 $recData = t3lib_BEfunc::getRecord($table,$recData,'pid'.($GLOBALS['TCA'][$table]['ctrl']['versioningWS']?',t3ver_wsid,t3ver_stage':'')); 00656 } 00657 00658 if (is_array($recData)) { 00659 if ((int)$recData['pid']===-1) { // We are testing a "version" (identified by a pid of -1): it can be edited provided that workspace matches and versioning is enabled for the table. 00660 if (!$GLOBALS['TCA'][$table]['ctrl']['versioningWS']) { // No versioning, basic error, inconsistency even! Such records should not have a pid of -1! 00661 return 'Versioning disabled for table'; 00662 } elseif ((int)$recData['t3ver_wsid']!==$this->workspace) { // So does workspace match? 00663 return 'Workspace ID of record didn\'t match current workspace'; 00664 } else { // So what about the stage of the version, does that allow editing for this user? 00665 return $this->workspaceCheckStageForCurrent($recData['t3ver_stage']) ? FALSE : 'Record stage "'.$recData['t3ver_stage'].'" and users access level did not allow for editing'; 00666 } 00667 } else { // We are testing a "live" record: 00668 if ($res = $this->workspaceAllowLiveRecordsInPID($recData['pid'], $table)) { // For "Live" records, check that PID for table allows editing 00669 // Live records are OK in this branch, but what about the stage of branch point, if any: 00670 return $res>0 ? FALSE : 'Stage for versioning root point and users access level did not allow for editing'; // OK 00671 } else { // If not offline and not in versionized branch, output error: 00672 return 'Online record was not in versionized branch!'; 00673 } 00674 } 00675 } else return 'No record'; 00676 } else { 00677 return FALSE; // OK because workspace is 0 00678 } 00679 } 00680 00689 function workspaceCannotEditOfflineVersion($table,$recData) { 00690 if ($GLOBALS['TCA'][$table]['ctrl']['versioningWS']) { 00691 00692 if (!is_array($recData)) { 00693 $recData = t3lib_BEfunc::getRecord($table,$recData,'uid,pid,t3ver_wsid,t3ver_stage'); 00694 } 00695 if (is_array($recData)) { 00696 if ((int)$recData['pid']===-1) { 00697 return $this->workspaceCannotEditRecord($table,$recData); 00698 } else return 'Not an offline version'; 00699 } else return 'No record'; 00700 } else return 'Table does not support versioning.'; 00701 } 00702 00712 function workspaceAllowLiveRecordsInPID($pid, $table) { 00713 00714 // Always for Live workspace AND if live-edit is enabled and tables are completely without versioning it is ok as well. 00715 if ($this->workspace===0 || ($this->workspaceRec['live_edit'] && !$GLOBALS['TCA'][$table]['ctrl']['versioningWS'])) { 00716 return 2; // OK to create for this table. 00717 } 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. 00718 // Now, check what the stage of that "page" or "branch" version type is: 00719 $stage = t3lib_BEfunc::isPidInVersionizedBranch($pid, $table, TRUE); 00720 return $this->workspaceCheckStageForCurrent($stage) ? 1 : -1; 00721 } else { 00722 return FALSE; // If the answer is FALSE it means the only valid way to create or edit records in the PID is by versioning 00723 } 00724 } 00725 00733 function workspaceCreateNewRecord($pid, $table) { 00734 if ($res = $this->workspaceAllowLiveRecordsInPID($pid,$table)) { // If LIVE records cannot be created in the current PID due to workspace restrictions, prepare creation of placeholder-record 00735 if ($res<0) { 00736 return FALSE; // Stage for versioning root point and users access level did not allow for editing 00737 } 00738 } elseif (!$GLOBALS['TCA'][$table]['ctrl']['versioningWS']) { // So, if no live records were allowed, we have to create a new version of this record: 00739 return FALSE; 00740 } 00741 return TRUE; 00742 } 00743 00752 function workspaceAllowAutoCreation($table,$id,$recpid) { 00753 // Auto-creation of version: In offline workspace, test if versioning is enabled and look for workspace version of input record. If there is no versionized record found we will create one and save to that. 00754 if ($this->workspace!==0 // Only in draft workspaces 00755 && !$this->workspaceRec['disable_autocreate'] // Auto-creation must not be disabled. 00756 && $GLOBALS['TCA'][$table]['ctrl']['versioningWS'] // Table must be versionizable 00757 && $recpid >= 0 // The PID of the record must NOT be -1 or less (would indicate that it already was a version!) 00758 && !t3lib_BEfunc::getWorkspaceVersionOfRecord($this->workspace, $table, $id, 'uid') // There must be no existing version of this record in workspace. 00759 && !t3lib_BEfunc::isPidInVersionizedBranch($recpid, $table)) { // PID must NOT be in a versionized branch either 00760 return TRUE; 00761 } 00762 } 00763 00772 function workspaceCheckStageForCurrent($stage) { 00773 if ($this->isAdmin()) return TRUE; 00774 00775 if ($this->workspace>0) { 00776 $stat = $this->checkWorkspaceCurrent(); 00777 if (($stage<=0 && $stat['_ACCESS']==='member') || 00778 ($stage<=1 && $stat['_ACCESS']==='reviewer') || 00779 ($stat['_ACCESS']==='owner')) { 00780 return TRUE; // OK for these criteria 00781 } 00782 } else return TRUE; // Always OK for live and draft workspaces. 00783 } 00784 00795 function workspacePublishAccess($wsid) { 00796 if ($this->isAdmin()) return TRUE; 00797 00798 // If no access to workspace, of course you cannot publish! 00799 $retVal = FALSE; 00800 00801 $wsAccess = $this->checkWorkspace($wsid); 00802 if ($wsAccess) { 00803 switch($wsAccess['uid']) { 00804 case 0: // Live workspace 00805 $retVal = TRUE; // If access to Live workspace, no problem. 00806 break; 00807 case -1: // Default draft workspace 00808 $retVal = $this->checkWorkspace(0) ? TRUE : FALSE; // If access to Live workspace, no problem. 00809 break; 00810 default: // Custom workspace 00811 $retVal = $wsAccess['_ACCESS'] === 'owner' || ($this->checkWorkspace(0) && !($wsAccess['publish_access']&2)); // Either be an adminuser OR have access to online workspace which is OK as well as long as publishing access is not limited by workspace option. 00812 break; 00813 } 00814 } 00815 return $retVal; 00816 } 00817 00823 function workspaceSwapAccess() { 00824 if ($this->workspace>0 && (int)$this->workspaceRec['swap_modes']===2) { 00825 return FALSE; 00826 } else return TRUE; 00827 } 00828 00835 function workspaceVersioningTypeAccess($type) { 00836 $retVal = FALSE; 00837 00838 if ($this->workspace>0 && !$this->isAdmin()) { 00839 $stat = $this->checkWorkspaceCurrent(); 00840 if ($stat['_ACCESS']!=='owner') { 00841 00842 $type = t3lib_div::intInRange($type,-1); 00843 switch((int)$type) { 00844 case -1: 00845 $retVal = $this->workspaceRec['vtypes']&1 ? FALSE : TRUE; 00846 break; 00847 case 0: 00848 $retVal = $this->workspaceRec['vtypes']&2 ? FALSE : TRUE; 00849 break; 00850 default: 00851 $retVal = $this->workspaceRec['vtypes']&4 ? FALSE : TRUE; 00852 break; 00853 } 00854 } else $retVal = TRUE; 00855 } else $retVal = TRUE; 00856 00857 return $retVal; 00858 } 00859 00866 function workspaceVersioningTypeGetClosest($type) { 00867 $type = t3lib_div::intInRange($type,-1); 00868 00869 if ($this->workspace>0) { 00870 switch((int)$type) { 00871 case -1: 00872 $type = -1; 00873 break; 00874 case 0: 00875 $type = $this->workspaceVersioningTypeAccess($type) ? $type : -1; 00876 break; 00877 default: 00878 $type = $this->workspaceVersioningTypeAccess($type) ? $type : ($this->workspaceVersioningTypeAccess(0) ? 0 : -1); 00879 break; 00880 } 00881 } 00882 return $type; 00883 } 00884 00885 00886 00887 00888 00889 00890 00891 00892 00893 00894 /************************************* 00895 * 00896 * Miscellaneous functions 00897 * 00898 *************************************/ 00899 00909 function getTSConfig($objectString,$config='') { 00910 if (!is_array($config)) { 00911 $config=$this->userTS; // Getting Root-ts if not sent 00912 } 00913 $TSConf=array(); 00914 $parts = explode('.',$objectString,2); 00915 $key = $parts[0]; 00916 if (trim($key)) { 00917 if (count($parts)>1 && trim($parts[1])) { 00918 // Go on, get the next level 00919 if (is_array($config[$key.'.'])) $TSConf = $this->getTSConfig($parts[1],$config[$key.'.']); 00920 } else { 00921 $TSConf['value']=$config[$key]; 00922 $TSConf['properties']=$config[$key.'.']; 00923 } 00924 } 00925 return $TSConf; 00926 } 00927 00935 function getTSConfigVal($objectString) { 00936 $TSConf = $this->getTSConfig($objectString); 00937 return $TSConf['value']; 00938 } 00939 00947 function getTSConfigProp($objectString) { 00948 $TSConf = $this->getTSConfig($objectString); 00949 return $TSConf['properties']; 00950 } 00951 00959 function inList($in_list,$item) { 00960 return strstr(','.$in_list.',', ','.$item.','); 00961 } 00962 00970 function returnWebmounts() { 00971 return (string)($this->groupData['webmounts'])!='' ? explode(',',$this->groupData['webmounts']) : Array(); 00972 } 00973 00980 function returnFilemounts() { 00981 return $this->groupData['filemounts']; 00982 } 00983 00997 function jsConfirmation($bitmask) { 00998 $alertPopup = $GLOBALS['BE_USER']->getTSConfig('options.alertPopups'); 00999 if (empty($alertPopup['value'])) { 01000 $alertPopup = 255; // default: show all warnings 01001 } else { 01002 $alertPopup = (int)$alertPopup['value']; 01003 } 01004 if(($alertPopup&$bitmask) == $bitmask) { // show confirmation 01005 return 1; 01006 } else { // don't show confirmation 01007 return 0; 01008 } 01009 } 01010 01011 01012 01013 01014 01015 01016 01017 01018 01019 /************************************* 01020 * 01021 * Authentication methods 01022 * 01023 *************************************/ 01024 01025 01035 function fetchGroupData() { 01036 if ($this->user['uid']) { 01037 01038 // Get lists for the be_user record and set them as default/primary values. 01039 $this->dataLists['modList'] = $this->user['userMods']; // Enabled Backend Modules 01040 $this->dataLists['allowed_languages'] = $this->user['allowed_languages']; // Add Allowed Languages 01041 $this->dataLists['workspace_perms'] = $this->user['workspace_perms']; // Set user value for workspace permissions. 01042 $this->dataLists['webmount_list'] = $this->user['db_mountpoints']; // Database mountpoints 01043 $this->dataLists['filemount_list'] = $this->user['file_mountpoints']; // File mountpoints 01044 01045 // Setting default User TSconfig: 01046 $this->TSdataArray[]=$this->addTScomment('From $GLOBALS["TYPO3_CONF_VARS"]["BE"]["defaultUserTSconfig"]:'). 01047 $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig']; 01048 01049 // Default TSconfig for admin-users 01050 if ($this->isAdmin()) { 01051 $this->TSdataArray[]=$this->addTScomment('"admin" user presets:').' 01052 admPanel.enable.all = 1 01053 options.shortcutFrame = 1 01054 '; 01055 if (t3lib_extMgm::isLoaded('sys_note')) { 01056 $this->TSdataArray[]=' 01057 // Setting defaults for sys_note author / email... 01058 TCAdefaults.sys_note.author = '.$this->user['realName'].' 01059 TCAdefaults.sys_note.email = '.$this->user['email'].' 01060 '; 01061 } 01062 } 01063 01064 // FILE MOUNTS: 01065 // Admin users has the base fileadmin dir mounted 01066 if ($this->isAdmin() && $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir']) { 01067 $this->addFileMount($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '', PATH_site.$GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], 0, ''); 01068 } 01069 01070 // If userHomePath is set, we attempt to mount it 01071 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['userHomePath']) { 01072 // First try and mount with [uid]_[username] 01073 $didMount=$this->addFileMount($this->user['username'], '',$GLOBALS['TYPO3_CONF_VARS']['BE']['userHomePath'].$this->user['uid'].'_'.$this->user['username'].$GLOBALS['TYPO3_CONF_VARS']['BE']['userUploadDir'], 0, 'user'); 01074 if (!$didMount) { 01075 // If that failed, try and mount with only [uid] 01076 $this->addFileMount($this->user['username'], '', $GLOBALS['TYPO3_CONF_VARS']['BE']['userHomePath'].$this->user['uid'].$GLOBALS['TYPO3_CONF_VARS']['BE']['userUploadDir'], 0, 'user'); 01077 } 01078 } 01079 01080 // BE_GROUPS: 01081 // Get the groups... 01082 # $grList = t3lib_BEfunc::getSQLselectableList($this->user[$this->usergroup_column],$this->usergroup_table,$this->usergroup_table); 01083 $grList = $GLOBALS['TYPO3_DB']->cleanIntList($this->user[$this->usergroup_column]); // 240203: Since the group-field never contains any references to groups with a prepended table name we think it's safe to just intExplode and re-implode - which should be much faster than the other function call. 01084 if ($grList) { 01085 // Fetch groups will add a lot of information to the internal arrays: modules, accesslists, TSconfig etc. Refer to fetchGroups() function. 01086 $this->fetchGroups($grList); 01087 } 01088 01089 // Add the TSconfig for this specific user: 01090 $this->TSdataArray[] = $this->addTScomment('USER TSconfig field').$this->user['TSconfig']; 01091 // Check include lines. 01092 $this->TSdataArray = t3lib_TSparser::checkIncludeLines_array($this->TSdataArray); 01093 01094 // Parsing the user TSconfig (or getting from cache) 01095 $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. 01096 $hash = md5('userTS:'.$this->userTS_text); 01097 $cachedContent = t3lib_BEfunc::getHash($hash,0); 01098 if (isset($cachedContent) && !$this->userTS_dontGetCached) { 01099 $this->userTS = unserialize($cachedContent); 01100 } else { 01101 $parseObj = t3lib_div::makeInstance('t3lib_TSparser'); 01102 $parseObj->parse($this->userTS_text); 01103 $this->userTS = $parseObj->setup; 01104 t3lib_BEfunc::storeHash($hash,serialize($this->userTS),'BE_USER_TSconfig'); 01105 // Update UC: 01106 $this->userTSUpdated=1; 01107 } 01108 01109 // Processing webmounts 01110 if ($this->isAdmin() && !$this->getTSConfigVal('options.dontMountAdminMounts')) { // Admin's always have the root mounted 01111 $this->dataLists['webmount_list']='0,'.$this->dataLists['webmount_list']; 01112 } 01113 01114 // Processing filemounts 01115 $this->dataLists['filemount_list'] = t3lib_div::uniqueList($this->dataLists['filemount_list']); 01116 if ($this->dataLists['filemount_list']) { 01117 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_filemounts', 'deleted=0 AND hidden=0 AND pid=0 AND uid IN ('.$this->dataLists['filemount_list'].')'); 01118 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 01119 $this->addFileMount($row['title'], $row['path'], $row['path'], $row['base']?1:0, ''); 01120 } 01121 } 01122 01123 // The lists are cleaned for duplicates 01124 $this->groupData['webmounts'] = t3lib_div::uniqueList($this->dataLists['webmount_list']); 01125 $this->groupData['pagetypes_select'] = t3lib_div::uniqueList($this->dataLists['pagetypes_select']); 01126 $this->groupData['tables_select'] = t3lib_div::uniqueList($this->dataLists['tables_modify'].','.$this->dataLists['tables_select']); 01127 $this->groupData['tables_modify'] = t3lib_div::uniqueList($this->dataLists['tables_modify']); 01128 $this->groupData['non_exclude_fields'] = t3lib_div::uniqueList($this->dataLists['non_exclude_fields']); 01129 $this->groupData['explicit_allowdeny'] = t3lib_div::uniqueList($this->dataLists['explicit_allowdeny']); 01130 $this->groupData['allowed_languages'] = t3lib_div::uniqueList($this->dataLists['allowed_languages']); 01131 $this->groupData['custom_options'] = t3lib_div::uniqueList($this->dataLists['custom_options']); 01132 $this->groupData['modules'] = t3lib_div::uniqueList($this->dataLists['modList']); 01133 $this->groupData['workspace_perms'] = $this->dataLists['workspace_perms']; 01134 01135 // populating the $this->userGroupsUID -array with the groups in the order in which they were LAST included.!! 01136 $this->userGroupsUID = array_reverse(array_unique(array_reverse($this->includeGroupArray))); 01137 01138 // Finally this is the list of group_uid's in the order they are parsed (including subgroups!) and without duplicates (duplicates are presented with their last entrance in the list, which thus reflects the order of the TypoScript in TSconfig) 01139 $this->groupList = implode(',',$this->userGroupsUID); 01140 $this->setCachedList($this->groupList); 01141 01142 // Checking read access to webmounts: 01143 if (trim($this->groupData['webmounts'])!=='') { 01144 $webmounts = explode(',',$this->groupData['webmounts']); // Explode mounts 01145 $MProws = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', 'pages', 'deleted=0 AND uid IN ('.$this->groupData['webmounts'].') AND '.$this->getPagePermsClause(1),'','','','uid'); // Selecting all webmounts with permission clause for reading 01146 foreach($webmounts as $idx => $mountPointUid) { 01147 if ($mountPointUid>0 && !isset($MProws[$mountPointUid])) { // If the mount ID is NOT found among selected pages, unset it: 01148 unset($webmounts[$idx]); 01149 } 01150 } 01151 $this->groupData['webmounts'] = implode(',',$webmounts); // Implode mounts in the end. 01152 } 01153 01154 // Setting up workspace situation (after webmounts are processed!): 01155 $this->workspaceInit(); 01156 } 01157 } 01158 01168 function fetchGroups($grList,$idList='') { 01169 global $TYPO3_CONF_VARS; 01170 01171 // Fetching records of the groups in $grList (which are not blocked by lockedToDomain either): 01172 $lockToDomain_SQL = ' AND (lockToDomain=\'\' OR lockToDomain=\''.t3lib_div::getIndpEnv('HTTP_HOST').'\')'; 01173 $whereSQL = 'deleted=0 AND hidden=0 AND pid=0 AND uid IN ('.$grList.')'.$lockToDomain_SQL; 01174 01175 // Hook for manipulation of the WHERE sql sentence which controls which BE-groups are included 01176 if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['fetchGroupQuery'])) { 01177 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['fetchGroupQuery'] as $classRef) { 01178 $hookObj = &t3lib_div::getUserObj($classRef); 01179 if(method_exists($hookObj,'fetchGroupQuery_processQuery')){ 01180 $whereSQL = $hookObj->fetchGroupQuery_processQuery($this, $grList, $idList, $whereSQL); 01181 } 01182 } 01183 } 01184 01185 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $this->usergroup_table, $whereSQL); 01186 01187 // The userGroups array is filled 01188 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 01189 $this->userGroups[$row['uid']] = $row; 01190 } 01191 01192 // Traversing records in the correct order 01193 $include_staticArr = t3lib_div::intExplode(',',$grList); 01194 reset($include_staticArr); 01195 while(list(,$uid)=each($include_staticArr)) { // traversing list 01196 01197 // Get row: 01198 $row=$this->userGroups[$uid]; 01199 if (is_array($row) && !t3lib_div::inList($idList,$uid)) { // Must be an array and $uid should not be in the idList, because then it is somewhere previously in the grouplist 01200 01201 // Include sub groups 01202 if (trim($row['subgroup'])) { 01203 $theList = implode(',',t3lib_div::intExplode(',',$row['subgroup'])); // Make integer list 01204 $this->fetchGroups($theList, $idList.','.$uid); // Call recursively, pass along list of already processed groups so they are not recursed again. 01205 } 01206 // Add the group uid, current list, TSconfig to the internal arrays. 01207 $this->includeGroupArray[]=$uid; 01208 $this->includeHierarchy[]=$idList; 01209 $this->TSdataArray[] = $this->addTScomment('Group "'.$row['title'].'" ['.$row['uid'].'] TSconfig field:').$row['TSconfig']; 01210 01211 // Mount group database-mounts 01212 if (($this->user['options']&1) == 1) { $this->dataLists['webmount_list'].= ','.$row['db_mountpoints']; } 01213 01214 // Mount group file-mounts 01215 if (($this->user['options']&2) == 2) { $this->dataLists['filemount_list'].= ','.$row['file_mountpoints']; } 01216 01217 // Mount group home-dirs 01218 if (($this->user['options']&2) == 2) { 01219 // If groupHomePath is set, we attempt to mount it 01220 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['groupHomePath']) { 01221 $this->addFileMount($row['title'], '', $GLOBALS['TYPO3_CONF_VARS']['BE']['groupHomePath'].$row['uid'], 0, 'group'); 01222 } 01223 } 01224 01225 // The lists are made: groupMods, tables_select, tables_modify, pagetypes_select, non_exclude_fields, explicit_allowdeny, allowed_languages, custom_options 01226 if ($row['inc_access_lists']==1) { 01227 $this->dataLists['modList'].= ','.$row['groupMods']; 01228 $this->dataLists['tables_select'].= ','.$row['tables_select']; 01229 $this->dataLists['tables_modify'].= ','.$row['tables_modify']; 01230 $this->dataLists['pagetypes_select'].= ','.$row['pagetypes_select']; 01231 $this->dataLists['non_exclude_fields'].= ','.$row['non_exclude_fields']; 01232 $this->dataLists['explicit_allowdeny'].= ','.$row['explicit_allowdeny']; 01233 $this->dataLists['allowed_languages'].= ','.$row['allowed_languages']; 01234 $this->dataLists['custom_options'].= ','.$row['custom_options']; 01235 } 01236 01237 // Setting workspace permissions: 01238 $this->dataLists['workspace_perms'] |= $row['workspace_perms']; 01239 01240 // If this function is processing the users OWN group-list (not subgroups) AND if the ->firstMainGroup is not set, then the ->firstMainGroup will be set. 01241 if (!strcmp($idList,'') && !$this->firstMainGroup) { 01242 $this->firstMainGroup=$uid; 01243 } 01244 } 01245 } 01246 01247 // **************** 01248 // HOOK: fetchGroups_postProcessing 01249 // **************** 01250 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['fetchGroups_postProcessing'])) { 01251 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['fetchGroups_postProcessing'] as $_funcRef) { 01252 $_params = array(); 01253 t3lib_div::callUserFunction($_funcRef, $_params, $this); 01254 } 01255 } 01256 } 01257 01266 function setCachedList($cList) { 01267 if ((string)$cList != (string)$this->user['usergroup_cached_list']) { 01268 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('be_users', 'uid='.intval($this->user['uid']), array('usergroup_cached_list' => $cList)); 01269 } 01270 } 01271 01286 function addFileMount($title, $altTitle, $path, $webspace, $type) { 01287 // Return false if fileadminDir is not set and we try to mount a relative path 01288 if ($webspace && !$GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir']) return false; 01289 01290 // Trimming and pre-processing 01291 $path=trim($path); 01292 if ($this->OS=='WIN') { // with WINDOWS convert backslash to slash!! 01293 $path=str_replace('\\','/',$path); 01294 } 01295 // If the path is true and validates as a valid path string: 01296 if ($path && t3lib_div::validPathStr($path)) { 01297 // these lines remove all slashes and dots before and after the path 01298 $path=ereg_replace('^[\/\. ]*','',$path); 01299 $path=trim(ereg_replace('[\/\. ]*$','',$path)); 01300 01301 01302 if ($path) { // there must be some chars in the path 01303 $fdir=PATH_site.$GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir']; // fileadmin dir, absolute 01304 if ($webspace) { 01305 $path=$fdir.$path; // PATH_site + fileadmin dir is prepended 01306 } else { 01307 if ($this->OS!='WIN') { // with WINDOWS no prepending!! 01308 $path='/'.$path; // root-level is the start... 01309 } 01310 } 01311 $path.='/'; 01312 01313 // We now have a path with slash after and slash before (if unix) 01314 if (@is_dir($path) && 01315 (($GLOBALS['TYPO3_CONF_VARS']['BE']['lockRootPath'] && t3lib_div::isFirstPartOfStr($path,$GLOBALS['TYPO3_CONF_VARS']['BE']['lockRootPath'])) || t3lib_div::isFirstPartOfStr($path,$fdir))) { 01316 // Alternative title? 01317 $name = $title ? $title : $altTitle; 01318 // Adds the filemount. The same filemount with same name, type and path cannot be set up twice because of the hash string used as key. 01319 $this->groupData['filemounts'][md5($name.'|'.$path.'|'.$type)] = Array('name'=>$name, 'path'=>$path, 'type'=>$type); 01320 // Return true - went well, success! 01321 return 1; 01322 } 01323 } 01324 } 01325 } 01326 01333 function addTScomment($str) { 01334 $delimiter = '# ***********************************************'; 01335 01336 $out = $delimiter.chr(10); 01337 $lines = t3lib_div::trimExplode(chr(10),$str); 01338 foreach($lines as $v) { 01339 $out.= '# '.$v.chr(10); 01340 } 01341 $out.= $delimiter.chr(10); 01342 return $out; 01343 } 01344 01345 01346 01347 01348 01349 01350 01351 01352 01353 01354 01355 01356 /************************************ 01357 * 01358 * Workspaces 01359 * 01360 ************************************/ 01361 01369 function workspaceInit() { 01370 01371 // Initializing workspace by evaluating and setting the workspace, possibly updating it in the user record! 01372 $this->setWorkspace($this->user['workspace_id']); 01373 01374 // Setting up the db mount points of the (custom) workspace, if any: 01375 if ($this->workspace>0 && trim($this->workspaceRec['db_mountpoints'])!=='') { 01376 01377 // Initialize: 01378 $newMounts = array(); 01379 $readPerms = '1=1'; // Notice: We cannot call $this->getPagePermsClause(1); as usual because the group-list is not available at this point. But bypassing is fine because all we want here is check if the workspace mounts are inside the current webmounts rootline. The actual permission checking on page level is done elsewhere as usual anyway before the page tree is rendered. 01380 01381 // Traverse mount points of the 01382 $mountPoints = t3lib_div::intExplode(',',$this->workspaceRec['db_mountpoints']); 01383 foreach($mountPoints as $mpId) { 01384 if ($this->isInWebMount($mpId,$readPerms)) { 01385 $newMounts[] = $mpId; 01386 } 01387 } 01388 01389 // Re-insert webmounts: 01390 $this->groupData['webmounts'] = implode(',',array_unique($newMounts)); 01391 } 01392 01393 // Setting up the file mount points of the (custom) workspace, if any: 01394 if ($this->workspace!==0) $this->groupData['filemounts'] = array(); 01395 if ($this->workspace>0 && trim($this->workspaceRec['file_mountpoints'])!=='') { 01396 01397 // Processing filemounts 01398 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_filemounts', 'deleted=0 AND hidden=0 AND pid=0 AND uid IN ('.$GLOBALS['TYPO3_DB']->cleanIntList($this->workspaceRec['file_mountpoints']).')'); 01399 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 01400 $this->addFileMount($row['title'], $row['path'], $row['path'], $row['base']?1:0, ''); 01401 } 01402 } 01403 } 01404 01412 function checkWorkspace($wsRec,$fields='uid,title,adminusers,members,reviewers,publish_access,stagechg_notification') { 01413 $retVal = FALSE; 01414 01415 // If not array, look up workspace record: 01416 if (!is_array($wsRec)) { 01417 switch((string)$wsRec) { 01418 case '0': 01419 case '-1': 01420 $wsRec = array('uid' => $wsRec); 01421 break; 01422 default: 01423 list($wsRec) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 01424 $fields, 01425 'sys_workspace', 01426 'pid=0 AND uid='.intval($wsRec). 01427 t3lib_BEfunc::deleteClause('sys_workspace'), 01428 '', 01429 'title' 01430 ); 01431 break; 01432 } 01433 } 01434 01435 // If wsRec is set to an array, evaluate it: 01436 if (is_array($wsRec)) { 01437 if ($this->isAdmin()) { 01438 return array_merge($wsRec,array('_ACCESS' => 'admin')); 01439 } else { 01440 01441 switch((string)$wsRec['uid']) { 01442 case '0': 01443 $retVal = ($this->groupData['workspace_perms']&1) ? array_merge($wsRec,array('_ACCESS' => 'online')) : FALSE; 01444 break; 01445 case '-1': 01446 $retVal = ($this->groupData['workspace_perms']&2) ? array_merge($wsRec,array('_ACCESS' => 'offline')) : FALSE; 01447 break; 01448 default: 01449 // Checking if the guy is admin: 01450 if (t3lib_div::inList($wsRec['adminusers'],$this->user['uid'])) { 01451 return array_merge($wsRec, array('_ACCESS' => 'owner')); 01452 } 01453 // Checking if he is reviewer user: 01454 if (t3lib_div::inList($wsRec['reviewers'],'be_users_'.$this->user['uid'])) { 01455 return array_merge($wsRec, array('_ACCESS' => 'reviewer')); 01456 } 01457 // Checking if he is reviewer through a user group of his: 01458 foreach($this->userGroupsUID as $groupUid) { 01459 if (t3lib_div::inList($wsRec['reviewers'],'be_groups_'.$groupUid)) { 01460 return array_merge($wsRec, array('_ACCESS' => 'reviewer')); 01461 } 01462 } 01463 // Checking if he is member as user: 01464 if (t3lib_div::inList($wsRec['members'],'be_users_'.$this->user['uid'])) { 01465 return array_merge($wsRec, array('_ACCESS' => 'member')); 01466 } 01467 // Checking if he is member through a user group of his: 01468 foreach($this->userGroupsUID as $groupUid) { 01469 if (t3lib_div::inList($wsRec['members'],'be_groups_'.$groupUid)) { 01470 return array_merge($wsRec, array('_ACCESS' => 'member')); 01471 } 01472 } 01473 break; 01474 } 01475 } 01476 } 01477 01478 return $retVal; 01479 } 01480 01487 function checkWorkspaceCurrent() { 01488 if (!isset($this->checkWorkspaceCurrent_cache)) { 01489 $this->checkWorkspaceCurrent_cache = $this->checkWorkspace($this->workspace); 01490 } 01491 return $this->checkWorkspaceCurrent_cache; 01492 } 01493 01500 function setWorkspace($workspaceId) { 01501 01502 // Check workspace validity and if not found, revert to default workspace. 01503 if ($this->workspaceRec = $this->checkWorkspace($workspaceId,'*')) { 01504 // Set workspace ID internally 01505 $this->workspace = (int)$workspaceId; 01506 } else { 01507 $this->workspace = (int)$this->getDefaultWorkspace(); 01508 $this->workspaceRec = $this->checkWorkspace($this->workspace,'*'); 01509 } 01510 01511 // Unset access cache: 01512 unset($this->checkWorkspaceCurrent_cache); 01513 01514 // If ID is different from the stored one, change it: 01515 if (strcmp($this->workspace, $this->user['workspace_id'])) { 01516 $this->user['workspace_id'] = $this->workspace; 01517 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('be_users','uid='.intval($this->user['uid']),array('workspace_id' => $this->user['workspace_id'])); 01518 $this->simplelog('User changed workspace to "'.$this->workspace.'"'); 01519 } 01520 } 01521 01528 function setWorkspacePreview($previewState) { 01529 $this->user['workspace_preview'] = $previewState; 01530 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('be_users','uid='.intval($this->user['uid']),array('workspace_preview' => $this->user['workspace_preview'])); 01531 } 01532 01538 function getDefaultWorkspace() { 01539 01540 if ($this->checkWorkspace(0)) { // Check online 01541 return 0; 01542 } elseif ($this->checkWorkspace(-1)) { // Check offline 01543 return -1; 01544 } else { // Traverse custom workspaces: 01545 $workspaces = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,title,adminusers,members,reviewers','sys_workspace','pid=0'.t3lib_BEfunc::deleteClause('sys_workspace'),'','title'); 01546 foreach($workspaces as $rec) { 01547 if ($this->checkWorkspace($rec)) { 01548 return $rec['uid']; 01549 } 01550 } 01551 } 01552 return -99; 01553 } 01554 01555 01556 01557 01558 01559 01560 01561 01562 01563 01564 01565 /************************************ 01566 * 01567 * Logging 01568 * 01569 ************************************/ 01570 01589 function writelog($type,$action,$error,$details_nr,$details,$data,$tablename='',$recuid='',$recpid='',$event_pid=-1,$NEWid='',$userId=0) { 01590 01591 $fields_values = Array ( 01592 'userid' => $userId ? $userId : intval($this->user['uid']), 01593 'type' => intval($type), 01594 'action' => intval($action), 01595 'error' => intval($error), 01596 'details_nr' => intval($details_nr), 01597 'details' => $details, 01598 'log_data' => serialize($data), 01599 'tablename' => $tablename, 01600 'recuid' => intval($recuid), 01601 # 'recpid' => intval($recpid), 01602 'IP' => t3lib_div::getIndpEnv('REMOTE_ADDR'), 01603 'tstamp' => $GLOBALS['EXEC_TIME'], 01604 'event_pid' => intval($event_pid), 01605 'NEWid' => $NEWid, 01606 'workspace' => $this->workspace 01607 ); 01608 01609 $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_log', $fields_values); 01610 return $GLOBALS['TYPO3_DB']->sql_insert_id(); 01611 } 01612 01621 function simplelog($message, $extKey='', $error=0) { 01622 return $this->writelog( 01623 4, 01624 0, 01625 $error, 01626 0, 01627 ($extKey?'['.$extKey.'] ':'').$message, 01628 array() 01629 ); 01630 } 01631 01642 function checkLogFailures($email, $secondsBack=3600, $max=3) { 01643 01644 if ($email) { 01645 01646 // get last flag set in the log for sending 01647 $theTimeBack = time()-$secondsBack; 01648 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 01649 'tstamp', 01650 'sys_log', 01651 'type=255 AND action=4 AND tstamp>'.intval($theTimeBack), 01652 '', 01653 'tstamp DESC', 01654 '1' 01655 ); 01656 if ($testRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 01657 $theTimeBack = $testRow['tstamp']; 01658 } 01659 01660 // Check for more than $max number of error failures with the last period. 01661 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 01662 '*', 01663 'sys_log', 01664 'type=255 AND action=3 AND error!=0 AND tstamp>'.intval($theTimeBack), 01665 '', 01666 'tstamp' 01667 ); 01668 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res) > $max) { 01669 // OK, so there were more than the max allowed number of login failures - so we will send an email then. 01670 $subject = 'TYPO3 Login Failure Warning (at '.$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'].')'; 01671 $email_body = ' 01672 There has been numerous attempts ('.$GLOBALS['TYPO3_DB']->sql_num_rows($res).') to login at the TYPO3 01673 site "'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'].'" ('.t3lib_div::getIndpEnv('HTTP_HOST').'). 01674 01675 This is a dump of the failures: 01676 01677 '; 01678 while($testRows = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 01679 $theData = unserialize($testRows['log_data']); 01680 $email_body.=date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'].' H:i',$testRows['tstamp']).': '.@sprintf($testRows['details'],''.$theData[0],''.$theData[1],''.$theData[2]); 01681 $email_body.=chr(10); 01682 } 01683 mail( $email, 01684 $subject, 01685 $email_body, 01686 'From: TYPO3 Login WARNING<>' 01687 ); 01688 $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 01689 } 01690 } 01691 } 01692 } 01693 01694 01695 01696 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_userauthgroup.php']) { 01697 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_userauthgroup.php']); 01698 } 01699 ?>