Subversion Repositories Applications.papyrus

Rev

Rev 1713 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1173 jp_milcent 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
3
 
4
/**
5
 * Reduced storage driver for use against PEAR DB
6
 *
7
 * PHP versions 4 and 5
8
 *
9
 * LICENSE: This source file is subject to version 3.01 of the PHP license
10
 * that is available through the world-wide-web at the following URI:
11
 * http://www.php.net/license/3_01.txt.  If you did not receive a copy of
12
 * the PHP License and are unable to obtain it through the web, please
13
 * send a note to license@php.net so we can mail you a copy immediately.
14
 *
15
 * @category   Authentication
16
 * @package    Auth
17
 * @author     Martin Jansen <mj@php.net>
18
 * @author     Adam Ashley <aashley@php.net>
19
 * @copyright  2001-2006 The PHP Group
20
 * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
21
 * @version    CVS: $Id: DBLite.php,v 1.1 2006-12-14 15:04:28 jp_milcent Exp $
22
 * @link       http://pear.php.net/package/Auth
23
 * @since      File available since Release 1.3.0
24
 */
25
 
26
/**
27
 * Include Auth_Container base class
28
 */
29
require_once 'Auth/Container.php';
30
/**
31
 * Include PEAR DB package
32
 */
33
require_once 'DB.php';
34
 
35
/**
36
 * A lighter storage driver for fetching login data from a database
37
 *
38
 * This driver is derived from the DB storage container but
39
 * with the user manipulation function removed for smaller file size
40
 * by the PEAR DB abstraction layer to fetch login data.
41
 *
42
 * @category   Authentication
43
 * @package    Auth
44
 * @author     Martin Jansen <mj@php.net>
45
 * @author     Adam Ashley <aashley@php.net>
46
 * @copyright  2001-2006 The PHP Group
47
 * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
48
 * @version    Release: 1.4.3  File: $Revision: 1.1 $
49
 * @link       http://pear.php.net/package/Auth
50
 * @since      Class available since Release 1.3.0
51
 */
52
class Auth_Container_DBLite extends Auth_Container
53
{
54
 
55
    // {{{ properties
56
 
57
    /**
58
     * Additional options for the storage container
59
     * @var array
60
     */
61
    var $options = array();
62
 
63
    /**
64
     * DB object
65
     * @var object
66
     */
67
    var $db = null;
68
    var $dsn = '';
69
 
70
    /**
71
     * User that is currently selected from the DB.
72
     * @var string
73
     */
74
    var $activeUser = '';
75
 
76
    // }}}
77
    // {{{ Auth_Container_DBLite() [constructor]
78
 
79
    /**
80
     * Constructor of the container class
81
     *
82
     * Initate connection to the database via PEAR::DB
83
     *
84
     * @param  string Connection data or DB object
85
     * @return object Returns an error object if something went wrong
86
     */
87
    function Auth_Container_DBLite($dsn)
88
    {
89
        $this->options['table']       = 'auth';
90
        $this->options['usernamecol'] = 'username';
91
        $this->options['passwordcol'] = 'password';
92
        $this->options['dsn']         = '';
93
        $this->options['db_fields']   = '';
94
        $this->options['cryptType']   = 'md5';
95
        $this->options['db_options']  = array();
96
        $this->options['auto_quote']  = true;
97
 
98
        if (is_array($dsn)) {
99
            $this->_parseOptions($dsn);
100
            if (empty($this->options['dsn'])) {
101
                PEAR::raiseError('No connection parameters specified!');
102
            }
103
        } else {
104
            $this->options['dsn'] = $dsn;
105
        }
106
    }
107
 
108
    // }}}
109
    // {{{ _connect()
110
 
111
    /**
112
     * Connect to database by using the given DSN string
113
     *
114
     * @access private
115
     * @param  string DSN string
116
     * @return mixed  Object on error, otherwise bool
117
     */
118
    function _connect(&$dsn)
119
    {
120
        if (is_string($dsn) || is_array($dsn)) {
121
            $this->db =& DB::connect($dsn, $this->options['db_options']);
122
        } elseif (is_subclass_of($dsn, "db_common")) {
123
            $this->db =& $dsn;
124
        } else {
125
            return PEAR::raiseError("Invalid dsn or db object given");
126
        }
127
 
128
        if (DB::isError($this->db) || PEAR::isError($this->db)) {
129
            return PEAR::raiseError($this->db->getMessage(), $this->db->getCode());
130
        } else {
131
            return true;
132
        }
133
    }
134
 
135
    // }}}
136
    // {{{ _prepare()
137
 
138
    /**
139
     * Prepare database connection
140
     *
141
     * This function checks if we have already opened a connection to
142
     * the database. If that's not the case, a new connection is opened.
143
     *
144
     * @access private
145
     * @return mixed True or a DB error object.
146
     */
147
    function _prepare()
148
    {
149
        if (!DB::isConnection($this->db)) {
150
            $res = $this->_connect($this->options['dsn']);
151
            if (DB::isError($res) || PEAR::isError($res)) {
152
                return $res;
153
            }
154
        }
155
        if ($this->options['auto_quote'] && $this->db->dsn['phptype'] != 'sqlite') {
156
            $this->options['final_table'] = $this->db->quoteIdentifier($this->options['table']);
157
            $this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol']);
158
            $this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol']);
159
        } else {
160
            $this->options['final_table'] = $this->options['table'];
161
            $this->options['final_usernamecol'] = $this->options['usernamecol'];
162
            $this->options['final_passwordcol'] = $this->options['passwordcol'];
163
        }
164
        return true;
165
    }
166
 
167
    // }}}
168
    // {{{ _parseOptions()
169
 
170
    /**
171
     * Parse options passed to the container class
172
     *
173
     * @access private
174
     * @param  array
175
     */
176
    function _parseOptions($array)
177
    {
178
        foreach ($array as $key => $value) {
179
            if (isset($this->options[$key])) {
180
                $this->options[$key] = $value;
181
            }
182
        }
183
    }
184
 
185
    // }}}
186
    // {{{ _quoteDBFields()
187
 
188
    /**
189
     * Quote the db_fields option to avoid the possibility of SQL injection.
190
     *
191
     * @access private
192
     * @return string A properly quoted string that can be concatenated into a
193
     * SELECT clause.
194
     */
195
    function _quoteDBFields()
196
    {
197
        if (isset($this->options['db_fields'])) {
198
            if (is_array($this->options['db_fields'])) {
199
                if ($this->options['auto_quote']) {
200
                    $fields = array();
201
                    foreach ($this->options['db_fields'] as $field) {
202
                        $fields[] = $this->db->quoteIdentifier($field);
203
                    }
204
                    return implode(', ', $fields);
205
                } else {
206
                    return implode(', ', $this->options['db_fields']);
207
                }
208
            } else {
209
                if (strlen($this->options['db_fields']) > 0) {
210
                    if ($this->options['auto_quote']) {
211
                        return $this->db->quoteIdentifier($this->options['db_fields']);
212
                    } else {
213
                        $this->options['db_fields'];
214
                    }
215
                }
216
            }
217
        }
218
 
219
        return '';
220
    }
221
 
222
    // }}}
223
    // {{{ fetchData()
224
 
225
    /**
226
     * Get user information from database
227
     *
228
     * This function uses the given username to fetch
229
     * the corresponding login data from the database
230
     * table. If an account that matches the passed username
231
     * and password is found, the function returns true.
232
     * Otherwise it returns false.
233
     *
234
     * @param   string Username
235
     * @param   string Password
236
     * @return  mixed  Error object or boolean
237
     */
238
    function fetchData($username, $password)
239
    {
240
        // Prepare for a database query
241
        $err = $this->_prepare();
242
        if ($err !== true) {
243
            return PEAR::raiseError($err->getMessage(), $err->getCode());
244
        }
245
 
246
        // Find if db_fields contains a *, if so assume all col are selected
247
        if (is_string($this->options['db_fields'])
248
            && strstr($this->options['db_fields'], '*')) {
249
            $sql_from = "*";
250
        } else {
251
            $sql_from = $this->options['final_usernamecol'].
252
                ", ".$this->options['final_passwordcol'];
253
 
254
            if (strlen($fields = $this->_quoteDBFields()) > 0) {
255
                $sql_from .= ', '.$fields;
256
            }
257
        }
258
 
259
        $query = "SELECT ".$sql_from.
260
                " FROM ".$this->options['final_table'].
261
                " WHERE ".$this->options['final_usernamecol']." = ".$this->db->quoteSmart($username);
262
        $res = $this->db->getRow($query, null, DB_FETCHMODE_ASSOC);
263
 
264
        if (DB::isError($res)) {
265
            return PEAR::raiseError($res->getMessage(), $res->getCode());
266
        }
267
        if (!is_array($res)) {
268
            $this->activeUser = '';
269
            return false;
270
        }
271
        if ($this->verifyPassword(trim($password, "\r\n"),
272
                                  trim($res[$this->options['passwordcol']], "\r\n"),
273
                                  $this->options['cryptType'])) {
274
            // Store additional field values in the session
275
            foreach ($res as $key => $value) {
276
                if ($key == $this->options['passwordcol'] ||
277
                    $key == $this->options['usernamecol']) {
278
                    continue;
279
                }
280
                // Use reference to the auth object if exists
281
                // This is because the auth session variable can change so a static call to setAuthData does not make sence
282
                if (is_object($this->_auth_obj)) {
283
                    $this->_auth_obj->setAuthData($key, $value);
284
                } else {
285
                    Auth::setAuthData($key, $value);
286
                }
287
            }
288
            $this->activeUser = $res[$this->options['usernamecol']];
289
            return true;
290
        }
291
        $this->activeUser = $res[$this->options['usernamecol']];
292
        return false;
293
    }
294
 
295
    // }}}
296
 
297
}
298
?>