Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

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