[TASK] Update ADOdb to 5.18
[Packages/TYPO3.CMS.git] / typo3 / sysext / adodb / adodb / pear / Auth / Container / ADOdb.php
1 <?php
2 /*
3 V5.18 3 Sep 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
4 Released under both BSD license and Lesser GPL library license.
5 Whenever there is any discrepancy between the two licenses,
6 the BSD license will take precedence. See License.txt.
7 Set tabs to 4 for best viewing.
8
9 Latest version is available at http://adodb.sourceforge.net
10
11 Original Authors: Martin Jansen <mj#php.net>
12 Richard Tango-Lowy <richtl#arscognita.com>
13 */
14
15 require_once 'Auth/Container.php';
16 require_once 'adodb.inc.php';
17 require_once 'adodb-pear.inc.php';
18 require_once 'adodb-errorpear.inc.php';
19
20 /**
21 * Storage driver for fetching login data from a database using ADOdb-PHP.
22 *
23 * This storage driver can use all databases which are supported
24 * by the ADBdb DB abstraction layer to fetch login data.
25 * See http://php.weblogs.com/adodb for information on ADOdb.
26 * NOTE: The ADOdb directory MUST be in your PHP include_path!
27 *
28 * @author Richard Tango-Lowy <richtl@arscognita.com>
29 * @package Auth
30 * @version $Revision: 1.3 $
31 */
32 class Auth_Container_ADOdb extends Auth_Container
33 {
34
35 /**
36 * Additional options for the storage container
37 * @var array
38 */
39 var $options = array();
40
41 /**
42 * DB object
43 * @var object
44 */
45 var $db = null;
46 var $dsn = '';
47
48 /**
49 * User that is currently selected from the DB.
50 * @var string
51 */
52 var $activeUser = '';
53
54 // {{{ Constructor
55
56 /**
57 * Constructor of the container class
58 *
59 * Initate connection to the database via PEAR::ADOdb
60 *
61 * @param string Connection data or DB object
62 * @return object Returns an error object if something went wrong
63 */
64 function Auth_Container_ADOdb($dsn)
65 {
66 $this->_setDefaults();
67
68 if (is_array($dsn)) {
69 $this->_parseOptions($dsn);
70
71 if (empty($this->options['dsn'])) {
72 PEAR::raiseError('No connection parameters specified!');
73 }
74 } else {
75 // Extract db_type from dsn string.
76 $this->options['dsn'] = $dsn;
77 }
78 }
79
80 // }}}
81 // {{{ _connect()
82
83 /**
84 * Connect to database by using the given DSN string
85 *
86 * @access private
87 * @param string DSN string
88 * @return mixed Object on error, otherwise bool
89 */
90 function _connect($dsn)
91 {
92 if (is_string($dsn) || is_array($dsn)) {
93 if(!$this->db) {
94 $this->db = ADONewConnection($dsn);
95 if( $err = ADODB_Pear_error() ) {
96 return PEAR::raiseError($err);
97 }
98 }
99
100 } else {
101 return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
102 41,
103 PEAR_ERROR_RETURN,
104 null,
105 null
106 );
107 }
108
109 if(!$this->db) {
110 return PEAR::raiseError(ADODB_Pear_error());
111 } else {
112 return true;
113 }
114 }
115
116 // }}}
117 // {{{ _prepare()
118
119 /**
120 * Prepare database connection
121 *
122 * This function checks if we have already opened a connection to
123 * the database. If that's not the case, a new connection is opened.
124 *
125 * @access private
126 * @return mixed True or a DB error object.
127 */
128 function _prepare()
129 {
130 if(!$this->db) {
131 $res = $this->_connect($this->options['dsn']);
132 }
133 return true;
134 }
135
136 // }}}
137 // {{{ query()
138
139 /**
140 * Prepare query to the database
141 *
142 * This function checks if we have already opened a connection to
143 * the database. If that's not the case, a new connection is opened.
144 * After that the query is passed to the database.
145 *
146 * @access public
147 * @param string Query string
148 * @return mixed a DB_result object or DB_OK on success, a DB
149 * or PEAR error on failure
150 */
151 function query($query)
152 {
153 $err = $this->_prepare();
154 if ($err !== true) {
155 return $err;
156 }
157 return $this->db->query($query);
158 }
159
160 // }}}
161 // {{{ _setDefaults()
162
163 /**
164 * Set some default options
165 *
166 * @access private
167 * @return void
168 */
169 function _setDefaults()
170 {
171 $this->options['db_type'] = 'mysql';
172 $this->options['table'] = 'auth';
173 $this->options['usernamecol'] = 'username';
174 $this->options['passwordcol'] = 'password';
175 $this->options['dsn'] = '';
176 $this->options['db_fields'] = '';
177 $this->options['cryptType'] = 'md5';
178 }
179
180 // }}}
181 // {{{ _parseOptions()
182
183 /**
184 * Parse options passed to the container class
185 *
186 * @access private
187 * @param array
188 */
189 function _parseOptions($array)
190 {
191 foreach ($array as $key => $value) {
192 if (isset($this->options[$key])) {
193 $this->options[$key] = $value;
194 }
195 }
196
197 /* Include additional fields if they exist */
198 if(!empty($this->options['db_fields'])){
199 if(is_array($this->options['db_fields'])){
200 $this->options['db_fields'] = join($this->options['db_fields'], ', ');
201 }
202 $this->options['db_fields'] = ', '.$this->options['db_fields'];
203 }
204 }
205
206 // }}}
207 // {{{ fetchData()
208
209 /**
210 * Get user information from database
211 *
212 * This function uses the given username to fetch
213 * the corresponding login data from the database
214 * table. If an account that matches the passed username
215 * and password is found, the function returns true.
216 * Otherwise it returns false.
217 *
218 * @param string Username
219 * @param string Password
220 * @return mixed Error object or boolean
221 */
222 function fetchData($username, $password)
223 {
224 // Prepare for a database query
225 $err = $this->_prepare();
226 if ($err !== true) {
227 return PEAR::raiseError($err->getMessage(), $err->getCode());
228 }
229
230 // Find if db_fields contains a *, i so assume all col are selected
231 if(strstr($this->options['db_fields'], '*')){
232 $sql_from = "*";
233 }
234 else{
235 $sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields'];
236 }
237
238 $query = "SELECT ".$sql_from.
239 " FROM ".$this->options['table'].
240 " WHERE ".$this->options['usernamecol']." = " . $this->db->Quote($username);
241
242 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
243 $rset = $this->db->Execute( $query );
244 $res = $rset->fetchRow();
245
246 if (DB::isError($res)) {
247 return PEAR::raiseError($res->getMessage(), $res->getCode());
248 }
249 if (!is_array($res)) {
250 $this->activeUser = '';
251 return false;
252 }
253 if ($this->verifyPassword(trim($password, "\r\n"),
254 trim($res[$this->options['passwordcol']], "\r\n"),
255 $this->options['cryptType'])) {
256 // Store additional field values in the session
257 foreach ($res as $key => $value) {
258 if ($key == $this->options['passwordcol'] ||
259 $key == $this->options['usernamecol']) {
260 continue;
261 }
262 // Use reference to the auth object if exists
263 // This is because the auth session variable can change so a static call to setAuthData does not make sence
264 if(is_object($this->_auth_obj)){
265 $this->_auth_obj->setAuthData($key, $value);
266 } else {
267 Auth::setAuthData($key, $value);
268 }
269 }
270
271 return true;
272 }
273
274 $this->activeUser = $res[$this->options['usernamecol']];
275 return false;
276 }
277
278 // }}}
279 // {{{ listUsers()
280
281 function listUsers()
282 {
283 $err = $this->_prepare();
284 if ($err !== true) {
285 return PEAR::raiseError($err->getMessage(), $err->getCode());
286 }
287
288 $retVal = array();
289
290 // Find if db_fileds contains a *, i so assume all col are selected
291 if(strstr($this->options['db_fields'], '*')){
292 $sql_from = "*";
293 }
294 else{
295 $sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields'];
296 }
297
298 $query = sprintf("SELECT %s FROM %s",
299 $sql_from,
300 $this->options['table']
301 );
302 $res = $this->db->getAll($query, null, DB_FETCHMODE_ASSOC);
303
304 if (DB::isError($res)) {
305 return PEAR::raiseError($res->getMessage(), $res->getCode());
306 } else {
307 foreach ($res as $user) {
308 $user['username'] = $user[$this->options['usernamecol']];
309 $retVal[] = $user;
310 }
311 }
312 return $retVal;
313 }
314
315 // }}}
316 // {{{ addUser()
317
318 /**
319 * Add user to the storage container
320 *
321 * @access public
322 * @param string Username
323 * @param string Password
324 * @param mixed Additional information that are stored in the DB
325 *
326 * @return mixed True on success, otherwise error object
327 */
328 function addUser($username, $password, $additional = "")
329 {
330 if (function_exists($this->options['cryptType'])) {
331 $cryptFunction = $this->options['cryptType'];
332 } else {
333 $cryptFunction = 'md5';
334 }
335
336 $additional_key = '';
337 $additional_value = '';
338
339 if (is_array($additional)) {
340 foreach ($additional as $key => $value) {
341 $additional_key .= ', ' . $key;
342 $additional_value .= ", '" . $value . "'";
343 }
344 }
345
346 $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES ('%s', '%s'%s)",
347 $this->options['table'],
348 $this->options['usernamecol'],
349 $this->options['passwordcol'],
350 $additional_key,
351 $username,
352 $cryptFunction($password),
353 $additional_value
354 );
355
356 $res = $this->query($query);
357
358 if (DB::isError($res)) {
359 return PEAR::raiseError($res->getMessage(), $res->getCode());
360 } else {
361 return true;
362 }
363 }
364
365 // }}}
366 // {{{ removeUser()
367
368 /**
369 * Remove user from the storage container
370 *
371 * @access public
372 * @param string Username
373 *
374 * @return mixed True on success, otherwise error object
375 */
376 function removeUser($username)
377 {
378 $query = sprintf("DELETE FROM %s WHERE %s = '%s'",
379 $this->options['table'],
380 $this->options['usernamecol'],
381 $username
382 );
383
384 $res = $this->query($query);
385
386 if (DB::isError($res)) {
387 return PEAR::raiseError($res->getMessage(), $res->getCode());
388 } else {
389 return true;
390 }
391 }
392
393 // }}}
394 }
395
396 function showDbg( $string ) {
397 print "
398 -- $string</P>";
399 }
400 function dump( $var, $str, $vardump = false ) {
401 print "<H4>$str</H4><pre>";
402 ( !$vardump ) ? ( print_r( $var )) : ( var_dump( $var ));
403 print "</pre>";
404 }
405 ?>