Use include() rather than require_once() in Authentication::_setupDatabase()
[bugdar.git] / includes / auth / auth.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # Bugdar
5 || # Copyright (c)2004-2009 Blue Static
6 || #
7 || # This program is free software; you can redistribute it and/or modify
8 || # it under the terms of the GNU General Public License as published by
9 || # the Free Software Foundation; version 2 of the License.
10 || #
11 || # This program is distributed in the hope that it will be useful, but
12 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 || # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 || # more details.
15 || #
16 || # You should have received a copy of the GNU General Public License along
17 || # with this program; if not, write to the Free Software Foundation, Inc.,
18 || # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 || ###################################################################
20 \*=====================================================================*/
21
22 require_once('./includes/api_user.php');
23
24 /**
25 * Abstract Authentication
26 *
27 * This is an abstract class that is used to provide authentication for
28 * Bugdar.
29 *
30 * @author Blue Static
31 * @copyright Copyright (c)2002 - 2007, Blue Static
32 * @version $Revision$
33 * @package Bugdar
34 *
35 */
36 class Authentication
37 {
38 /**
39 * The database connection to AUTHENTICATE against; can be to a separate database
40 * @var object
41 */
42 var $authDb;
43
44 /**
45 * The database connection to the BUGDAR database
46 * @var object
47 */
48 var $db;
49
50 /**
51 * Array of user data from the AUTHENTICATION database
52 * @var array
53 */
54 var $authUser;
55
56 /**
57 * Array of user data from the BUGDAR database
58 * @var array
59 */
60 var $bugdarUser;
61
62 /**
63 * Mapping of Bugdar fields to authentication database fields; these will be synced between databases upon login.
64 * AT THE VERY MINIMUM, YOU MUST MAP THESE FIELDS:
65 * @var array
66 */
67 var $fieldMap = array(
68 'authid' => null,
69 'displayname' => null,
70 'email' => null,
71 );
72
73 // ###################################################################
74 /**
75 * Constructor
76 */
77 function __construct()
78 {
79 $this->db = BSApp::$db;
80
81 BSApp::debug('authentication system: ' . get_class($this));
82
83 $this->_setupDatabase();
84 }
85
86 // ###################################################################
87 /**
88 * (PHP 4) Constructor
89 */
90 function Authentication()
91 {
92 $this->__construct();
93 }
94
95 // ###################################################################
96 /**
97 * Returns the information array for the Bugdar user. This must be
98 * called after an authentication method.
99 */
100 function fetchBugdarUser()
101 {
102 return $this->bugdarUser;
103 }
104
105 // ###################################################################
106 /**
107 * Sets up the database to authenticate against. You can create a new
108 * database object here. Whatever you choose, you need to reference
109 * Authentication->authDb to the object
110 */
111 function _setupDatabase()
112 {
113 // connect to the DB
114 $this->authDb = new BSDBMySQLI();
115
116 include 'includes/auth/config.php';
117 $this->authDb->connect(
118 $config['auth']['dbServer'],
119 $config['auth']['dbUser'],
120 $config['auth']['dbPassword'],
121 $config['auth']['dbName']
122 );
123 }
124
125 // ###################################################################
126 /**
127 * Returns the sanitized value of the user ID or unique identifier
128 * found in the cookie of an already-authenticated user.
129 */
130 function _fetchCookieUniqueId() {}
131
132 // ###################################################################
133 /**
134 * Returns the sanitized value of the authentication key or cookie-safe
135 * password found in the cookies of an already-authenticated user.
136 */
137 function _fetchCookiePassword() {}
138
139 // ###################################################################
140 /**
141 * Returns an array of user data fetched using the user information
142 * values found in cookies. It should NOT be responsible for verifying
143 * the authentication information, but only fetching it.
144 */
145 function _fetchUserUsingCookies() {}
146
147 // ###################################################################
148 /**
149 * Returns TRUE if the cookie data values are valid in the data array
150 * returned from _fetchUserUsingCookies(), and FALSE if they are not.
151 */
152 function _verifyCookieData() {}
153
154 // ###################################################################
155 /**
156 * Authenticates the user using cookie data. You shouldn't need to
157 * customize this method if you implement all the helpers correctly.
158 * Returns TRUE if the cookies are valid and the user is logged in.
159 */
160 function authenticateCookies()
161 {
162 if (!$this->_fetchCookieUniqueId() OR !$this->_fetchCookiePassword())
163 {
164 return false;
165 }
166
167 $this->authUser = $this->_fetchUserUsingCookies();
168 if (!$this->authUser)
169 {
170 $this->authUser = null;
171 return false;
172 }
173
174 if ($this->_verifyCookieData())
175 {
176 $this->_setCookies(true);
177 $this->bugdarUser = $this->_fetchBugdarUserFromAuthUser();
178 if ($this->_syncBugdarUser())
179 {
180 $this->bugdarUser = $this->_fetchBugdarUserFromAuthUser();
181 }
182 return true;
183 }
184 else
185 {
186 $this->authUser = null;
187 $this->clearCookies();
188 return false;
189 }
190 }
191
192 // ###################################################################
193 /**
194 * Returns an array with the authentication user information, found
195 * by the unique login identifier passed to the function.
196 */
197 function _fetchUserWithIdentifier($string) {}
198
199 // ###################################################################
200 /**
201 * Verifies that the authUser's password matches the plain-text password
202 * passed to this function. This is basically the transformation of
203 * the plaintext to the hashed password and the result of the comparison.
204 */
205 function _verifyLoginUser($password) {}
206
207 // ###################################################################
208 /**
209 * Authenticates a user at login from two keys: an identifier and
210 * a password. In Bugdar, the identifier is an email, but it can be
211 * any unique string found in the authentication database. Returns
212 * TRUE if the authentication is successful, and FALSE if not. Also
213 * determines if the cookies are sticky ("rememember me" login)
214 */
215 function authenticateLogin($string, $password, $sticky = false)
216 {
217 $this->authUser = $this->_fetchUserWithIdentifier($string);
218
219 if (!$this->authUser)
220 {
221 $this->authUser = null;
222 return false;
223 }
224
225 if ($this->_verifyLoginUser($password))
226 {
227 $this->_setCookies($sticky);
228 $this->bugdarUser = $this->_fetchBugdarUserFromAuthUser();
229 $this->_syncBugdarUser();
230 return true;
231 }
232 else
233 {
234 $this->authUser = null;
235 return false;
236 }
237 }
238
239 // ###################################################################
240 /**
241 * Returns the BUGDAR user array from the data in the AUTHENTICATION user
242 * array. If the Bugdar user does not exist, call _createBugdarUser()
243 * to add the user into the Bugdar database. This is necessary so Bugdar options
244 * can be saved in the Bugdar database (and not in the auth one), however
245 * authentication details will NOT be stored in the Bugdar database.
246 */
247 function _fetchBugdarUserFromAuthUser()
248 {
249 $user = $this->db->queryFirst("SELECT * FROM " . TABLE_PREFIX . "user WHERE authid = '" . $this->authUser[ $this->fieldMap['authid'] ] . "'");
250 if (!$user)
251 {
252 $this->_createBugdarUser();
253 return $this->_fetchBugdarUserFromAuthUser();
254 }
255 return $user;
256 }
257
258 // ###################################################################
259 /**
260 * Creates a Bugdar user with the authentication details specified in
261 * the auth array and returns it. You need to call this in
262 * _fetchBugdarUserFromAuthUser() and use the UserAPI to create the user.
263 * This will create a new user in Bugdar with the data from the authentication DB
264 * with the fields specified in fieldMap.
265 */
266 function _createBugdarUser()
267 {
268 $user = new UserAPI($this->registry);
269
270 // if the email already exists in the DB, it must be the same person so just hook up the authid
271 if ($check = $this->db->queryFirst("SELECT * FROM " . TABLE_PREFIX . "user WHERE email = '" . $this->db->escape_string($this->authUser[ $this->fieldMap['email'] ]) . "'"))
272 {
273 $user->set('userid', $check['userid']);
274 $user->set_condition();
275 $user->set('authid', $this->authUser[ $this->fieldMap['authid'] ]);
276 $user->update();
277 $user->fetch();
278
279 return $user->record;
280 }
281 else
282 {
283 $user = new UserAPI($this->registry);
284 foreach ($this->fieldMap AS $bugdar => $authdb)
285 {
286 $user->set($bugdar, $this->authUser["$authdb"]);
287 }
288 $user->set('usergroupid', 2);
289 $user->set('password', $this->registry->funct->rand());
290 $user->insert();
291
292 return $user->values;
293 }
294 }
295
296 // ###################################################################
297 /**
298 * Syncs a Bugdar user's fieldMap'ed values to the authentication DB's
299 * values. This allows the users to stay mostly-in-sync for the most
300 * basic of information (like email, timezone, etc.). Passwords are
301 * NOT synced. Returns TRUE if the user data was changed.
302 */
303 function _syncBugdarUser()
304 {
305 $fields = $this->fieldMap;
306 unset($fields['authid']);
307 unset($fields['password']);
308
309 $change = false;
310
311 $user = new UserAPI($this->registry);
312 $user->set('userid', $this->bugdarUser['userid']);
313 $user->set_condition();
314 foreach ($fields AS $bugdar => $auth)
315 {
316 if ($this->bugdarUser["$bugdar"] != $this->authUser["$auth"])
317 {
318 $user->set($bugdar, $this->authUser["$auth"]);
319 $change = true;
320 }
321 }
322 if ($change)
323 {
324 $user->update();
325 }
326
327 return $change;
328 }
329
330 // ###################################################################
331 /**
332 * Responsible for unsetting all authentication cookies because they
333 * are invalid
334 */
335 function clearCookies() {}
336
337 // ###################################################################
338 /**
339 * Sets the authentication cookies; this is done both at login and
340 * for renewing the cookies upon successful cookie validation. The
341 * option it takes determines whether the cookies are sticky or not.
342 */
343 function _setCookies($permanent = false) {}
344 }
345
346 ?>