root/FreakAuth/tags/1.1/www/system/application/libraries/Freakauth_light.php

Revision 314 (checked in by danfreak, 1 year ago)

changing @version 1.1

Line 
1 <?php if (!defined('BASEPATH')) exit('No direct script access allowed');
2 /**
3  * FreakAuth_light Class
4  * Security handler that provides functionality to handle login, logout,
5  * registration, and reset password requests.
6  * It also can verify the logged in status of 3 user classes
7  *
8  * => superadmin (has permissions on everything and can also create other admin)
9  * => admin      (you can choose what to let him manage)
10  * => user       (it is a registered user, and you can decide to give in rights
11  *               to access some specific areas (controllers) of your application
12  *
13  * The class requires the use of
14  *
15  * => Database CI official library
16  * => Db_session, FAL_validation and the FAL_front library (included in the download)
17  * => URL, FORM and FreakAuth_light (included in the download) helpers
18  *
19  * The FreakAuth_light library should be auto loaded in the core classes section
20  * of the autoloader.
21  *
22  * Passwords are encripted with md5 algorithm by the method _encode($password)
23  *
24  * -----------------------------------------------------------------------------
25  * Copyright (C) 2007  Daniel Vecchiato (4webby.com)
26  * -----------------------------------------------------------------------------
27  *This library is free software; you can redistribute it and/or
28  *modify it under the terms of the GNU Lesser General Public
29  *License as published by the Free Software Foundation; either
30  *version 2.1 of the License, or (at your option) any later version.
31  *
32  *This library is distributed in the hope that it will be useful,
33  *but WITHOUT ANY WARRANTY; without even the implied warranty of
34  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
35  *Lesser General Public License for more details.
36  *
37  *You should have received a copy of the GNU Lesser General Public
38  *License along with this library; if not, write to the Free Software
39  *Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
40  *------------------------------------------------------------------------------
41  * @package     FreakAuth_light
42  * @subpackage  Libraries
43  * @category    Authentication
44  * @author      Daniel Vecchiato (danfreak) & Christophe Gragnic (grahack)
45  * @copyright   Copyright (c) 2007, 4webby.com
46  * @license        http://www.gnu.org/licenses/lgpl.html
47  * @link         http://4webby.com/freakauth
48  * @version     1.1
49  *
50  */
51
52 // ------------------------------------------------------------------------
53
54 /**
55  * Security handler that provides functionality to handle logins and logout
56  * requests.  It also can verify the logged in status of a user and permissions.
57  * The class requires the use of the Database and Encrypt CI libraries and the
58  * URL, and CI helper.  It also requires the use of the 3rd party DB_Session
59  * library.  The Auth library should be auto loaded in the core classes section
60  * of the autoloader.
61  *
62  * Passwords are encripted with md5 algorithm.
63  */
64 class Freakauth_light
65 {
66     // --------------------------------------------------------------------
67     
68     /**
69     * Function FreakAuth inizialises the class loading the right libraries,
70     * helpers and models
71     *
72     * @uses libraries (encrypt, db_session)
73     * @uses helpers (form, url, FreakAuth)
74     * @uses modules (usermodel)
75     */
76     function Freakauth_light()
77     {
78         $this->CI=& get_instance();
79
80         log_message('debug', "FreakAuth Class Initialized");
81
82         $this->CI->load->library('db_session');
83         $this->CI->load->helper('form');
84         $this->CI->load->helper('url');
85         $this->CI->load->helper('freakauth_light');
86         $this->CI->load->model('FreakAuth_light/usertemp', 'UserTemp');
87         $this->CI->load->model('usermodel', 'usermodel');
88         if($this->CI->config->item('FAL_create_user_profile'))
89             $this->CI->load->model('Userprofile', 'userprofile');
90
91         $this->_init();
92     }
93
94     // --------------------------------------------------------------------
95     
96     /**
97      * Initializes the security settings and checks for autologin
98      *
99      * @return boolean
100      */
101     function _init()
102     {
103         // checks if the Freakauth system is turned on
104         if (!$this->CI->config->item('FAL'))
105         {
106             // preparing the message
107             $this->CI->lang->load('freakauth');
108             $website_name = $this->CI->config->item('FAL_website_name');
109             $message = sprintf(
110                 $this->CI->lang->line('FAL_turned_off_message'),
111                 $website_name
112             );
113             $data['website_name'] = $website_name;
114             $data['message'] = $message;
115             echo $this->CI->load->view($this->CI->config->item('FAL_template_dir').'content/turned_off', $data, true);
116             exit;
117         }
118
119     }
120
121     // --------------------------------------------------------------------
122       
123     /**
124      * Method used to restrict access to controllers or methods of controllers
125      * to the specified category of users.
126      * It requires 2 optional parameters:
127      *  - the first parameter specifies the user group i.e. ('admin')
128      *  - the second parameter specifies whether the area is reserved ONLY to
129      *    that group (true) or if it is accessible by groups higher in the
130      *    hierarchy
131      *
132      * example usage in a controller
133      *
134      * 1) $this->freakauth_light->check()
135      *    this restricts access to registered users and user-groups higher in
136      *    the hierarchy (i.e. admin, superadmin)
137      * 2) $this->freakauth_light->check('admin')
138      *    this restricts access to 'admin' users and users who belong to roles
139      *    higher in the hierarchy (i.e. 'superadmin')
140      * 3) $this->freakauth_light->check('admin', true)
141      *    this restricts access to 'admin' users ONLY
142      *
143      * @param string (the role to whom the area is restricted to) $lock_to_role
144      * @param boolean (true/false) $only
145      */
146     function check($_lock_to_role=null, $_only=null)
147     {
148
149             // check who did the request and build role hierarchy
150             $_who_is = $this->CI->db_session->userdata('role');
151             
152             // if we have a role stored in DB session for this user
153             if ($this->CI->db_session AND $this->CI->config->item('FAL') AND !empty($_who_is))
154             {
155                 
156                 // gets the locked role hierarchy value
157                 $_hierarchy = $this->CI->config->item('FAL_roles');
158                 
159                 // if we didn't specify to who we will reserve the action
160                 // let's restrict it to registered users
161                 if ($_lock_to_role==null){$_lock_to_role='user';}
162                 
163                 // let's see who did we reserve the area to
164                 $_lock_hierarchy = $_hierarchy[$_lock_to_role];
165                 // let's see who requested to access this area
166                 $_request_hierarchy = $_hierarchy[$_who_is];
167
168                 // let's see if we decided to restrict access ONLY to a given category
169                 switch ($_only)
170                 {
171                     case true:
172                         $_request_hierarchy == $_lock_hierarchy ? $_condition = true : $_condition = false;
173                         break;
174                     
175                     // only false or not specified   
176                     default:
177                         $_request_hierarchy <= $_lock_hierarchy ? $_condition = true : $_condition = false;
178                         break;
179                         
180                 }
181                 
182                 // if who did the request doesn't have enough credentials
183                 if ($_condition==false)
184                 {
185                     $this->denyAccess($_who_is);
186                 }
187             }
188             // it means it is a guest because it has no role stored in DB_session
189             else
190             {
191                 $this->denyAccess($_who_is);
192             }
193     }
194
195     // --------------------------------------------------------------------
196
197     /**
198      * Handles the case where the one who did the request
199      * doesn't have enough credentials
200      *
201      * if FAL_deny_with_flash_message == true in config file, displays a flash
202      * message and redirects to the referer page (or homepage if none)
203      *
204      * else displays the FAL_denied_page (see config file)
205      * -------------------------------
206      * EXAMPLE USAGE (in a controller)
207      * -------------------------------
208      * $this->freakauth_light->denyAccess('user')
209      *
210      * @param string the role of the one we are denying the access
211      */
212     function denyAccess($role)
213     {
214         $this->CI->lang->load('freakauth');
215         if ($this->CI->config->item('FAL_deny_with_flash_message'))
216         {
217             // if visitor is a GUEST
218             if ($role == '')
219             {
220                 // First, we have to store the requested page in order
221                 // to serve it back to the visitor after a successful login.
222                 $this->CI->db_session->set_flashdata('requested_page',
223                     $this->CI->uri->uri_string());
224                 
225                 // Then we redirect to the login form with a 'access denied'
226                 // message. Maybe if the visitor can log in,
227                 // he'll get some more permissions...
228                 $msg = $this->CI->lang->line('FAL_no_credentials_guest');
229                 flashMsg($msg);
230                 redirect($this->CI->config->item('FAL_login_uri'), 'location');
231             }
232             // else if visitor is a USER
233             else
234             {
235                 $msg = $this->CI->lang->line('FAL_no_credentials_user');
236                 flashMsg($msg);
237                 
238                 // if visitor came to this site with an http_referer
239                 if (isset($_SERVER['HTTP_REFERER']))
240                 {
241                     $referer = $_SERVER['HTTP_REFERER'];
242                     if (preg_match("|^".base_url()."|", $referer) == 0)
243                     {
244                         // if http_referer is from an external site,
245                         // users are taken to the page defined in the config file
246                         redirect($this->CI->config->item('FAL_denied_from_ext_location'));
247                     }
248                     else
249                     {
250                         // if we came from our website, just go to this page back
251                         // but maybe we arrived here because of the
252                         // 'redirect to requested page', so in order not to
253                         $this->CI->db_session->keep_flashdata('requested_page');
254                         header("location:".$_SERVER['HTTP_REFERER']);
255                         exit();
256                     }
257                 }
258                 // if visitor did not come to this site with an http_referer,
259                 // redirect to the page defined in the config file too
260                 else
261                 {
262                     redirect($this->CI->config->item('FAL_denied_from_ext_location'), 'location');
263                 }
264             }
265         }
266         else
267         {
268             $page = $this->CI->config->item('FAL_denied_page');
269             $data['role'] = $role;
270             // this is how we stop the execution
271             echo $this->CI->load->view($page, $data, true);
272             exit();
273         }
274     }
275     
276     
277     
278     // --------------------------------------------------------------------
279
280     /**
281      * Checks to see if a user is an administrator
282      * uses Class Db_session method userdata
283      * Returns false if FreakAuth system is not activated
284      * Returns true if admin or superadmin, otherwise false
285      *
286      * @return true if admin/superadmin or false otherwise
287      */
288     function isAdmin()
289     {
290
291         if ($this->CI->db_session AND $this->CI->config->item('FAL'))
292         {
293             $_username = $this->CI->db_session->userdata('user_name');
294             $_role = $this->CI->db_session->userdata('role');
295             
296             if ($_username != false && $_role != false AND ($_role=='admin' OR $_role=='superadmin'))
297                 
298                 //returns the user id
299                 return true;
300         }
301         
302         // if user_id not activated or not existent
303         return false;
304     }
305
306     // --------------------------------------------------------------------
307
308     /**
309      * Checks to see if an administrator has superadmin credentials
310      * uses Class Db_session method userdata
311      * Returns false if FreakAuth system is not activated
312      * Returns true if superadmin, otherwise false
313      *
314      * @return boolean
315      */
316     function isSuperAdmin()
317     {
318
319         if ($this->CI->db_session AND $this->CI->config->item('FAL'))
320         {
321             $_username = $this->CI->db_session->userdata('user_name');
322             $_role = $this->CI->db_session->userdata('role');
323             
324             if ($_username != false AND $_role != false AND $_role=='superadmin')
325                 
326                 return true;
327         }
328
329         return false;
330     }
331     // --------------------------------------------------------------------
332     
333     /**
334      * Checks to see if a user is logged in
335      * Returns false if FreakAuth system is not activated
336      * Returns true if a valid user is logged, false otherwise
337      *
338      * @return boolean
339      */
340     function isValidUser()
341     {
342
343         if ($this->CI->db_session AND $this->CI->config->item('FAL'))
344         {
345             if ($this->getUserName() != '')
346                 return true;
347         }
348
349         // if user not activated or not existent
350         return false;
351     }
352     
353     // --------------------------------------------------------------------
354     
355     /**
356      * Method used to used to check if a logged in members belongs to the custom
357      * role (group) specified in the first parameter.
358      * It requires 2 optional parameters:
359      *  - the first specifies the user roles as a comma separated string
360      *  - the second specifies whether we want to check to the specified roles
361      *    ONLY or for AT LEAST those group membership in the hierarchy
362      *    (returns true also if the logged user belongs to a group higher
363      *     in the hierarchy)
364      *
365      * example usage in a controller
366      * (see the relative helper belongsToGroup() to use it in views)
367      *
368      * 1) $this->freakauth_light->belongsToGroup()
369      *    returns true if the visitor is logged in and he is AT LEAST an user
370      * 2) $this->freakauth_light->belongsToGroup('user,editor')
371      *    returns true if the visitor is logged in and he is AT LEAST an user
372      *    or an editor (therefore it returns true also if he belongs to
373      *    user-groups higher in the hierarchy (i.e. superadmin)
374      * 3) $this->freakauth_light->belongsToGroup('admin', true)
375      *    this true if the visitor is logged in and is an 'admin' ONLY
376      *
377      * @param string with comma separated user roles: "user,editor,moderator" $_group
378      * @param boolean $_only
379      * @return true/false
380      */
381     function belongsToGroup($_group=null, $_only=null)
382     {
383         if ($this->CI->db_session AND $this->CI->config->item('FAL'))
384         {
385             $_username = $this->CI->db_session->userdata('user_name');
386             $_who_is = $this->CI->db_session->userdata('role');
387             
388             if ($_username != false AND $_who_is != false)
389             {
390                 // if we didn't specify who we are looking for
391                 // let's look if the request comes from an 'user'
392                 if ($_group==null){$_group='user';}
393  
394                 $_groups = explode(",", $_group);
395     
396                 $_group = array();
397                 // eliminate possible whitespaces at the beginning and end
398                 // of groups names passed as parameters to this function
399                 foreach($_groups as $_grp)
400                 {
401                     $_group[] = trim($_grp);
402                 }
403
404                 // let's see if we decided to check if
405                 // it belongs ONLY to a given group
406                 switch ($_only)
407                 {   
408                     // $_only = true
409                     case true: //we decided to check if it belongs ONLY to a given group
410                         in_array($_who_is, $_group) ? $_condition = true : $_condition = false;
411                         break;
412                     
413                     // $_only false or not specified
414                     // we decided to check if it belongs AT LEAST to a given group   
415                     default:
416                         // gets the locked role hierarchy value
417                         $_hierarchy = $this->CI->config->item('FAL_roles');
418                         // let's see who we are looking for
419                         
420
421                             foreach ($_group as $value)
422                             {
423                                 $_group_hierarchy []= $_hierarchy[$value];
424                             }
425
426                             $_group_hierarchy = max($_group_hierarchy);
427                         
428                         // let's see who accessed. we need to get the
429                         // role-hierarchy-value of the visitor that did the request
430                         $_who_hierarchy = $_hierarchy[$_who_is];
431
432                         $_who_hierarchy <= $_group_hierarchy ? $_condition = true : $_condition = false;
433                         break;
434                         
435                 }
436                 
437                 // if who did the request doesn't have enough credentials
438                 if ($_condition==true)
439                 {
440                     return TRUE;
441                 }
442             }
443         }
444     // if condition==false, db_session turner off or user not found (namely not logged in) in ci_session
445     return false;
446     }
447       
448     // --------------------------------------------------------------------
449
450     /**
451      * Performs the login procedure both for user login
452      * and form administrators login
453      *
454      * @return unknown
455      */
456     function login()
457     {
458         if (!$this->CI->config->item('FAL'))
459         {
460             redirect($this->CI->config->item('FAL_login_success_action'), 'location');
461         }
462
463         $message = $this->CI->lang->line('FAL_invalid_user_message');
464
465         if ($this->CI->db_session)
466         {
467             $values = $this->getLoginForm();
468             $username = (isset($values['user_name']) ? $values['user_name'] : false);
469             $password = (isset($values['password']) ? $values['password'] : false);
470
471             if (($username != false) && ($password != false))
472             {
473                 $password = $this->_encode($password);
474
475                     // Use the input username and password and check against
476                     // 'user' table to check if user banned
477                     $query = $this->CI->usermodel->getUserForLogin($username, $password);
478
479
480                 if ($query->num_rows() == 1)
481                 {
482                     $row = $query->row();
483                     $fields = array('id', 'user_name', 'country_id', 'email',
484                                   'role', 'last_visit', 'created', 'modified');
485                     foreach($fields as $field) $userdata[$field] = $row->{$field};
486
487                     // verifies if a user has not been banned from the site
488                     // (i.e. user table, banned=1)
489                     if ($row->{'banned'} == 0)
490                     {
491                         $this->_set_logindata($userdata);
492                         
493                         // set FLASH MESSAGE
494                         // (redirection is done in FAL_front if TRUE is returned)
495                         flashMsg( $this->CI->lang->line('FAL_login_message') );
496                         return true;
497                     }
498                     else
499                     {
500                         $message = $this->CI->lang->line('FAL_banned_user_message');
501                     }
502                 }
503             }
504         }
505
506         // On error send user back to login page, and add error message
507         // set FLASH MESSAGE
508         flashMsg( $message );
509         // FIXME : if false is returned, no redirection is done in FAL_front
510         return false;
511     }
512     
513     // --------------------------------------------------------------------
514     /**
515      * Performs the logout procedure
516      *
517      */
518     function logout()
519     {       
520         // checks if a session exists
521         if ($this->CI->db_session)
522         {
523             $_username = $this->CI->db_session->userdata('user_name');
524
525             if ($_username != false)
526                 // deletes the userdata stored in DB for the user that logged out
527                 $this->_unset_user($_username);
528         }
529       
530         // set FLASH MESSAGE
531        $msg = $this->CI->lang->line('FAL_logout_message');
532        flashMsg($msg);
533         
534        redirect($this->CI->config->item('FAL_logout_success_action'), 'location');
535     }
536     
537     // --------------------------------------------------------------------
538     /**
539      * Performs the registration procedure
540      * Returns true if successful registration, false if unsucessful
541      *
542      * @return boolean
543