Subversion Repositories Applications.papyrus

Rev

Rev 1087 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
320 jpm 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
// | Author: Lorenzo Alberton <l.alberton@quipo.it>                                  |
17
// +----------------------------------------------------------------------+
18
//
19
// $Id: MDB.php,v 1.1 2005-03-30 08:50:33 jpm Exp $
20
//
21
 
22
require_once 'Auth/Container.php';
23
require_once 'MDB.php';
24
 
25
/**
26
 * Storage driver for fetching login data from a database
27
 *
28
 * This storage driver can use all databases which are supported
29
 * by the PEAR MDB abstraction layer to fetch login data.
30
 *
31
 * @author   Lorenzo Alberton <l.alberton@quipo.it>
32
 * @package  Auth
33
 * @version  $Revision: 1.1 $
34
 */
35
class Auth_Container_MDB extends Auth_Container
36
{
37
 
38
    /**
39
     * Additional options for the storage container
40
     * @var array
41
     */
42
    var $options = array();
43
 
44
    /**
45
     * DB object
46
     * @var object
47
     */
48
    var $db = null;
49
    var $dsn = '';
50
 
51
    /**
52
     * User that is currently selected from the DB.
53
     * @var string
54
     */
55
    var $activeUser = '';
56
 
57
    // {{{ Constructor
58
 
59
    /**
60
     * Constructor of the container class
61
     *
62
     * Initate connection to the database via PEAR::DB
63
     *
64
     * @param  string Connection data or DB object
65
     * @return object Returns an error object if something went wrong
66
     */
67
    function Auth_Container_MDB($dsn)
68
    {
69
        $this->_setDefaults();
70
 
71
        if (is_array($dsn)) {
72
            $this->_parseOptions($dsn);
73
            if (empty($this->options['dsn'])) {
74
                PEAR::raiseError('No connection parameters specified!');
75
            }
76
        } else {
77
            $this->options['dsn'] = $dsn;
78
        }
79
    }
80
 
81
    // }}}
82
    // {{{ _connect()
83
 
84
    /**
85
     * Connect to database by using the given DSN string
86
     *
87
     * @access private
88
     * @param  string DSN string
89
     * @return mixed  Object on error, otherwise bool
90
     */
91
    function _connect($dsn)
92
    {
93
        if (is_string($dsn) || is_array($dsn)) {
94
            $this->db =& MDB::Connect($dsn);
95
        } elseif (get_parent_class($dsn) == "mdb_common") {
96
            $this->db = $dsn;
97
        } elseif (is_object($dsn) && MDB::isError($dsn)) {
98
            return PEAR::raiseError($dsn->getMessage(), $dsn->code);
99
        } else {
100
            return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
101
                                    41,
102
                                    PEAR_ERROR_RETURN,
103
                                    null,
104
                                    null
105
                                    );
106
 
107
        }
108
 
109
        if (MDB::isError($this->db) || PEAR::isError($this->db)) {
110
            return PEAR::raiseError($this->db->getMessage(), $this->db->code);
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
        return $this->_connect($this->options['dsn']);
131
    }
132
 
133
    // }}}
134
    // {{{ query()
135
 
136
    /**
137
     * Prepare query to the database
138
     *
139
     * This function checks if we have already opened a connection to
140
     * the database. If that's not the case, a new connection is opened.
141
     * After that the query is passed to the database.
142
     *
143
     * @access public
144
     * @param  string Query string
145
     * @return mixed  a MDB_result object or MDB_OK on success, a MDB
146
     *                or PEAR error on failure
147
     */
148
    function query($query)
149
    {
150
        $err = $this->_prepare();
151
        if ($err !== true) {
152
            return $err;
153
        }
154
        return $this->db->query($query);
155
    }
156
 
157
    // }}}
158
    // {{{ _setDefaults()
159
 
160
    /**
161
     * Set some default options
162
     *
163
     * @access private
164
     * @return void
165
     */
166
    function _setDefaults()
167
    {
168
        $this->options['table']       = 'auth';
169
        $this->options['usernamecol'] = 'username';
170
        $this->options['passwordcol'] = 'password';
171
        $this->options['dsn']         = '';
172
        $this->options['db_fields']   = '';
173
        $this->options['cryptType']   = 'md5';
174
    }
175
 
176
    // }}}
177
    // {{{ _parseOptions()
178
 
179
    /**
180
     * Parse options passed to the container class
181
     *
182
     * @access private
183
     * @param  array
184
     */
185
    function _parseOptions($array)
186
    {
187
        foreach ($array as $key => $value) {
188
            if (isset($this->options[$key])) {
189
                $this->options[$key] = $value;
190
            }
191
        }
192
 
193
        // Include additional fields if they exist
194
        if (!empty($this->options['db_fields'])) {
195
            if (is_array($this->options['db_fields'])) {
196
                $this->options['db_fields'] = join($this->options['db_fields'], ', ');
197
            }
198
            $this->options['db_fields'] = ', ' . $this->options['db_fields'];
199
        }
200
 
201
    }
202
 
203
    // }}}
204
    // {{{ fetchData()
205
 
206
    /**
207
     * Get user information from database
208
     *
209
     * This function uses the given username to fetch
210
     * the corresponding login data from the database
211
     * table. If an account that matches the passed username
212
     * and password is found, the function returns true.
213
     * Otherwise it returns false.
214
     *
215
     * @param   string Username
216
     * @param   string Password
217
     * @return  mixed  Error object or boolean
218
     */
219
    function fetchData($username, $password)
220
    {
221
        // Prepare for a database query
222
        $err = $this->_prepare();
223
        if ($err !== true) {
224
            return PEAR::raiseError($err->getMessage(), $err->getCode());
225
        }
226
 
227
        // Find if db_fileds contains a *, i so assume all col are selected
228
        if (strstr($this->options['db_fields'], '*')) {
229
            $sql_from = '*';
230
        } else{
231
            $sql_from = $this->options['usernamecol'] . ', '. $this->options['passwordcol'] . $this->options['db_fields'];
232
        }
233
 
234
        $query = sprintf("SELECT %s FROM %s WHERE %s = %s",
235
                         $sql_from,
236
                         $this->options['table'],
237
                         $this->options['usernamecol'],
238
                         $this->db->getTextValue($username)
239
                         );
240
 
241
        $res = $this->db->getRow($query, null, null, null, MDB_FETCHMODE_ASSOC);
242
 
243
        if (MDB::isError($res) || PEAR::isError($res)) {
244
            return PEAR::raiseError($res->getMessage(), $res->getCode());
245
        }
246
        if (!is_array($res)) {
247
            $this->activeUser = '';
248
            return false;
249
        }
250
        if ($this->verifyPassword(trim($password, "\r\n"),
251
                                  trim($res[$this->options['passwordcol']], "\r\n"),
252
                                  $this->options['cryptType'])) {
253
            // Store additional field values in the session
254
            foreach ($res as $key => $value) {
255
                if ($key == $this->options['passwordcol'] ||
256
                    $key == $this->options['usernamecol']) {
257
                    continue;
258
                }
259
                // Use reference to the auth object if exists
260
                // This is because the auth session variable can change so a static call to setAuthData does not make sence
261
                if(is_object($this->_auth_obj)){
262
                    $this->_auth_obj->setAuthData($key, $value);
263
                } else {
264
                    Auth::setAuthData($key, $value);
265
                }
266
            }
267
 
268
            return true;
269
        }
270
 
271
        $this->activeUser = $res[$this->options['usernamecol']];
272
        return false;
273
    }
274
 
275
    // }}}
276
    // {{{ listUsers()
277
 
278
    function listUsers()
279
    {
280
        $err = $this->_prepare();
281
        if ($err !== true) {
282
            return PEAR::raiseError($err->getMessage(), $err->getCode());
283
        }
284
 
285
        $retVal = array();
286
 
287
        // Find if db_fileds contains a *, i so assume all col are selected
288
        if (strstr($this->options['db_fields'], '*')) {
289
            $sql_from = '*';
290
        } else{
291
            $sql_from = $this->options['db_fields'];
292
        }
293
 
294
        $query = sprintf('SELECT %s FROM %s',
295
                         $sql_from,
296
                         $this->options['table']
297
                         );
298
 
299
        $res = $this->db->getAll($query, null, null, null, MDB_FETCHMODE_ASSOC);
300
 
301
        if (MDB::isError($res)) {
302
            return PEAR::raiseError($res->getMessage(), $res->getCode());
303
        } else {
304
            foreach ($res as $user) {
305
                $user['username'] = $user[$this->options['usernamecol']];
306
                $retVal[] = $user;
307
            }
308
        }
309
        return $retVal;
310
    }
311
 
312
    // }}}
313
    // {{{ addUser()
314
 
315
    /**
316
     * Add user to the storage container
317
     *
318
     * @access public
319
     * @param  string Username
320
     * @param  string Password
321
     * @param  mixed  Additional information that are stored in the DB
322
     *
323
     * @return mixed True on success, otherwise error object
324
     */
325
    function addUser($username, $password, $additional = "")
326
    {
327
        if (function_exists($this->options['cryptType'])) {
328
            $cryptFunction = $this->options['cryptType'];
329
        } else {
330
            $cryptFunction = 'md5';
331
        }
332
 
333
        $additional_key   = '';
334
        $additional_value = '';
335
 
336
        if (is_array($additional)) {
337
            foreach ($additional as $key => $value) {
338
                $additional_key   .= ', ' . $key;
339
                $additional_value .= ', ' . $this->db->getTextValue($value);
340
            }
341
        }
342
 
343
        $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)",
344
                         $this->options['table'],
345
                         $this->options['usernamecol'],
346
                         $this->options['passwordcol'],
347
                         $additional_key,
348
                         $this->db->getTextValue($username),
349
                         $this->db->getTextValue($cryptFunction($password)),
350
                         $additional_value
351
                         );
352
 
353
        $res = $this->query($query);
354
 
355
        if (MDB::isError($res)) {
356
            return PEAR::raiseError($res->getMessage(), $res->code);
357
        } else {
358
            return true;
359
        }
360
    }
361
 
362
    // }}}
363
    // {{{ removeUser()
364
 
365
    /**
366
     * Remove user from the storage container
367
     *
368
     * @access public
369
     * @param  string Username
370
     *
371
     * @return mixed True on success, otherwise error object
372
     */
373
    function removeUser($username)
374
    {
375
        $query = sprintf("DELETE FROM %s WHERE %s = %s",
376
                         $this->options['table'],
377
                         $this->options['usernamecol'],
378
                         $this->db->getTextValue($username)
379
                         );
380
 
381
        $res = $this->query($query);
382
 
383
        if (MDB::isError($res)) {
384
           return PEAR::raiseError($res->getMessage(), $res->code);
385
        } else {
386
          return true;
387
        }
388
    }
389
 
390
    // }}}
391
}
392
?>