]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/adodb/pear/Auth/Container/ADOdb.php
Upgrade adodb
[SourceForge/phpwiki.git] / lib / WikiDB / 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 ?>