Updated copyright notices to show "2004"
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / tslib / class.tslib_feuserauth.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2004 Kasper Skaarhoj (kasper@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Front End session user. Login and session data
29 * Included from index_ts.php
30 *
31 * $Id$
32 * Revised for TYPO3 3.6 June/2003 by Kasper Skaarhoj
33 *
34 * @author Kasper Skaarhoj <kasper@typo3.com>
35 */
36 /**
37 * [CLASS/FUNCTION INDEX of SCRIPT]
38 *
39 *
40 *
41 * 77: class tslib_feUserAuth extends t3lib_userAuth
42 * 141: function fetchGroupData()
43 * 187: function getUserTSconf()
44 *
45 * SECTION: Session data management functions
46 * 232: function fetchSessionData()
47 * 258: function storeSessionData()
48 * 283: function getKey($type,$key)
49 * 308: function setKey($type,$key,$data)
50 * 333: function record_registration($recs)
51 *
52 * TOTAL FUNCTIONS: 7
53 * (This index is automatically created/updated by the extension "extdeveval")
54 *
55 */
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 /**
71 * Extension class for Front End User Authentication.
72 *
73 * @author Kasper Skaarhoj <kasper@typo3.com>
74 * @package TYPO3
75 * @subpackage tslib
76 */
77 class tslib_feUserAuth extends t3lib_userAuth {
78 var $session_table = 'fe_sessions'; // Table to use for session data.
79 var $name = 'fe_typo_user'; // Session/Cookie name
80 var $get_name = 'ftu'; // Session/GET-var name
81
82 var $user_table = 'fe_users'; // Table in database with userdata
83 var $username_column = 'username'; // Column for login-name
84 var $userident_column = 'password'; // Column for password
85 var $userid_column = 'uid'; // Column for user-id
86 var $lastLogin_column = 'lastlogin';
87
88 var $enablecolumns = Array (
89 'deleted' => 'deleted',
90 'disabled' => 'disable',
91 'starttime' => 'starttime',
92 'endtime' => 'endtime'
93 );
94 var $formfield_uname = 'user'; // formfield with login-name
95 var $formfield_uident = 'pass'; // formfield with password
96 var $formfield_chalvalue = 'challenge'; // formfield with a unique value which is used to encrypt the password and username
97 var $formfield_status = 'logintype'; // formfield with status: *'login', 'logout'
98 var $security_level = ''; // sets the level of security. *'normal' = clear-text. 'challenged' = hashed password/username from form in $formfield_uident. 'superchallenged' = hashed password hashed again with username.
99
100 var $auth_include = ''; // this is the name of the include-file containing the login form. If not set, login CAN be anonymous. If set login IS needed.
101
102 var $auth_timeout_field = 6000; // if > 0 : session-timeout in seconds. if false/<0 : no timeout. if string: The string is fieldname from the usertable where the timeout can be found.
103
104 var $lifetime = 0; // 0 = Session-cookies. If session-cookies, the browser will stop session when the browser is closed. Else it keeps the session for $lifetime seconds.
105 var $sendNoCacheHeaders = 0;
106 var $getFallBack = 1; // If this is set, authentication is also accepted by the HTTP_GET_VARS. Notice that the identification is NOT 128bit MD5 hash but reduced. This is done in order to minimize the size for mobile-devices, such as WAP-phones
107 var $hash_length = 10;
108 var $getMethodEnabled = 1; // Login may be supplied by url.
109
110 var $usergroup_column = 'usergroup';
111 var $usergroup_table = 'fe_groups';
112 var $groupData = Array(
113 'title' =>Array(),
114 'uid' =>Array(),
115 'pid' =>Array()
116 );
117 var $TSdataArray=array(); // Used to accumulate the TSconfig data of the user
118 var $userTS = array();
119 var $userTSUpdated=0;
120 var $showHiddenRecords=0;
121
122 // Session and user data:
123 /*
124 There are two types of data that can be stored: UserData and Session-Data. Userdata is for the login-user, and session-data for anyone viewing the pages.
125 'Keys' are keys in the internal dataarray of the data. When you get or set a key in one of the data-spaces (user or session) you decide the type of the variable (not object though)
126 'Reserved' keys are:
127 - 'recs': Array: Used to 'register' records, eg in a shopping basket. Structure: [recs][tablename][record_uid]=number
128 - sys: Reserved for TypoScript standard code.
129 */
130 var $sesData = Array();
131 var $sesData_change = 0;
132 var $userData_change = 0;
133
134
135 /**
136 * Will select all fe_groups records that the current fe_user is member of - and which groups are also allowed in the current domain.
137 * It also accumulates the TSconfig for the fe_user/fe_groups in ->TSdataArray
138 *
139 * @return integer Returns the number of usergroups for the frontend users (if the internal user record exists and the usergroup field contains a value)
140 */
141 function fetchGroupData() {
142 $this->TSdataArray=array();
143 $this->userTS = array();
144 $this->userTSUpdated=0;
145
146 // Setting default configuration:
147 $this->TSdataArray[]=$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultUserTSconfig'];
148
149 if (is_array($this->user) && $this->user['usergroup']) {
150 $groups = t3lib_div::intExplode(',',$this->user['usergroup']);
151 $list = implode($groups,',');
152 $lockToDomain_SQL = ' AND (lockToDomain="" OR lockToDomain="'.t3lib_div::getIndpEnv('HTTP_HOST').'")';
153 if (!$this->showHiddenRecords) $hiddenP = 'AND NOT hidden ';
154 $query='SELECT * FROM '.$this->usergroup_table.' WHERE NOT deleted '.$hiddenP.'AND uid IN ('.$list.')'.$lockToDomain_SQL;
155 $res = mysql(TYPO3_db,$query);
156 while ($row=mysql_fetch_assoc($res)) {
157 $this->groupData['title'][$row['uid']]=$row['title'];
158 $this->groupData['uid'][$row['uid']]=$row['uid'];
159 $this->groupData['pid'][$row['uid']]=$row['pid'];
160 $this->groupData['TSconfig'][$row['uid']]=$row['TSconfig'];
161 }
162 if (mysql_num_rows($res)) {
163 // TSconfig:
164 reset($groups);
165 while(list(,$TSuid)=each($groups)) {
166 $this->TSdataArray[]=$this->groupData['TSconfig'][$TSuid];
167 }
168 $this->TSdataArray[]=$this->user['TSconfig'];
169
170 // Sort information
171 ksort($this->groupData['title']);
172 ksort($this->groupData['uid']);
173 ksort($this->groupData['pid']);
174 return count($this->groupData['uid']);
175 } else {
176 return 0;
177 }
178 }
179 }
180
181 /**
182 * Returns the parsed TSconfig for the fe_user
183 * First time this function is called it will parse the TSconfig and store it in $this->userTS. Subsequent requests will not re-parse the TSconfig but simply return what is already in $this->userTS
184 *
185 * @return array TSconfig array for the fe_user
186 */
187 function getUserTSconf() {
188 if (!$this->userTSUpdated) {
189 // Parsing the user TS (or getting from cache)
190 $this->TSdataArray = t3lib_TSparser::checkIncludeLines_array($this->TSdataArray);
191 $userTS = implode($this->TSdataArray,chr(10).'[GLOBAL]'.chr(10));
192 $parseObj = t3lib_div::makeInstance('t3lib_TSparser');
193 $parseObj->parse($userTS);
194 $this->userTS = $parseObj->setup;
195
196 $this->userTSUpdated=1;
197 }
198 return $this->userTS;
199 }
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217 /*****************************************
218 *
219 * Session data management functions
220 *
221 ****************************************/
222
223 /**
224 * Fetches the session data for the user (from the fe_session_data table) based on the ->id of the current user-session.
225 * The session data is restored to $this->sesData
226 * 1/100 calls will also do a garbage collection.
227 *
228 * @return void
229 * @access private
230 * @see storeSessionData()
231 */
232 function fetchSessionData() {
233 // Gets SesData if any
234 if ($this->id) {
235 $query='SELECT * FROM fe_session_data WHERE hash = "'.$this->id.'"';
236 $dbres=mysql(TYPO3_db,$query);
237 echo mysql_error();
238 if ($sesDataRow = mysql_fetch_assoc($dbres)) {
239 $this->sesData = unserialize($sesDataRow['content']);
240 }
241 }
242 // delete old data:
243 if ((rand()%100) <= 1) { // a possibility of 1 % for garbage collection.
244 $query='DELETE FROM fe_session_data WHERE tstamp < "'.(time()-3600*24).'"'; // all data older than 24 hours are deleted.
245 $dbres=mysql(TYPO3_db,$query);
246 echo mysql_error();
247 }
248 }
249
250 /**
251 * Will write UC and session data.
252 * If the flag $this->userData_change has been set, the function ->writeUC is called (which will save persistent user session data)
253 * If the flag $this->sesData_change has been set, the fe_session_data table is updated with the content of $this->sesData (deleting any old record, inserting new)
254 *
255 * @return void
256 * @see fetchSessionData(), getKey(), setKey()
257 */
258 function storeSessionData() {
259 // Saves UC and SesData if changed.
260 if ($this->userData_change) {
261 $this->writeUC('');
262 }
263 if ($this->sesData_change) {
264 if ($this->id) {
265 $query='DELETE FROM fe_session_data WHERE hash = "'.$this->id.'"';
266 $dbres=mysql(TYPO3_db,$query);
267 echo mysql_error();
268 $query='INSERT INTO fe_session_data (hash, content, tstamp) VALUES ("'.$this->id.'", "'.addslashes(serialize($this->sesData)).'", "'.time().'")';
269 $dbres=mysql(TYPO3_db,$query);
270 echo mysql_error();
271 }
272 }
273 }
274
275 /**
276 * Returns session data for the fe_user; Either persistent data following the fe_users uid/profile (requires login) or current-session based (not available when browse is closed, but does not require login)
277 *
278 * @param string Session data type; Either "user" (persistent, bound to fe_users profile) or "ses" (temporary, bound to current session cookie)
279 * @param string Key from the data array to return; The session data (in either case) is an array ($this->uc / $this->sesData) and this value determines which key to return the value for.
280 * @return mixed Returns whatever value there was in the array for the key, $key
281 * @see setKey()
282 */
283 function getKey($type,$key) {
284 if ($key) {
285 switch($type) {
286 case 'user':
287 return $this->uc[$key];
288 break;
289 case 'ses':
290 return $this->sesData[$key];
291 break;
292 }
293 }
294 }
295
296 /**
297 * Saves session data, either persistent or bound to current session cookie. Please see getKey() for more details.
298 * When a value is set the flags $this->userData_change or $this->sesData_change will be set so that the final call to ->storeSessionData() will know if a change has occurred and needs to be saved to the database.
299 * Notice: The key "recs" is already used by the function record_registration() which stores table/uid=value pairs in that key. This is used for the shopping basket among other things.
300 * Notice: Simply calling this function will not save the data to the database! The actual saving is done in storeSessionData() which is called as some of the last things in index_ts.php. So if you exit before this point, nothing gets saved of course! And the solution is to call $GLOBALS['TSFE']->storeSessionData(); before you exit.
301 *
302 * @param string Session data type; Either "user" (persistent, bound to fe_users profile) or "ses" (temporary, bound to current session cookie)
303 * @param string Key from the data array to store incoming data in; The session data (in either case) is an array ($this->uc / $this->sesData) and this value determines in which key the $data value will be stored.
304 * @param mixed The data value to store in $key
305 * @return void
306 * @see setKey(), storeSessionData(), record_registration()
307 */
308 function setKey($type,$key,$data) {
309 if ($key) {
310 switch($type) {
311 case 'user':
312 if ($this->user['uid']) {
313 $this->uc[$key]=$data;
314 $this->userData_change=1;
315 }
316 break;
317 case 'ses':
318 $this->sesData[$key]=$data;
319 $this->sesData_change=1;
320 break;
321 }
322 }
323 }
324
325 /**
326 * Registration of records/"shopping basket" in session data
327 * This will take the input array, $recs, and merge into the current "recs" array found in the session data.
328 * If a change in the recs storage happens (which it probably does) the function setKey() is called in order to store the array again.
329 *
330 * @param array The data array to merge into/override the current recs values. The $recs array is constructed as [table]][uid] = scalar-value (eg. string/integer).
331 * @return void
332 */
333 function record_registration($recs) {
334 if ($recs['clear_all']) {
335 $this->setKey('ses','recs','');
336 }
337 $change=0;
338 $recs_array=$this->getKey('ses','recs');
339 reset($recs);
340 while(list($table,$data)=each($recs)) {
341 if (is_array($data)) {
342 reset($data);
343 while(list($rec_id,$value)=each($data)) {
344 if ($value != $recs_array[$table][$rec_id]) {
345 $recs_array[$table][$rec_id] = stripslashes($value);
346 $change=1;
347 }
348 }
349 }
350 }
351 if ($change) {
352 $this->setKey('ses','recs',$recs_array);
353 }
354 }
355 }
356
357
358 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_feuserauth.php']) {
359 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_feuserauth.php']);
360 }
361 ?>