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

Revision 314 (checked in by danfreak, 2 years 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      */
544     function register()
545     {
546         // let's clean the user_temp table
547         // if we use registration with e-mail verification
548         if (!$this->CI->config->item('FAL_register_direct'))
549         {
550            $this->cleanExpiredUserTemp();
551         }
552         
553         // let's check if the system is turned on and if we allow users to register
554         if (!$this->CI->config->item('FAL') OR $this->CI->config->item('FAL_allow_user_registration')!=TRUE)
555             return false;
556
557         if ($this->CI->db_session)
558         {   
559         
560             $values = $this->getRegistrationForm();
561             $username = (isset($values['user_name']) ? $values['user_name'] : false);
562             $password = (isset($values['password']) ? $values['password'] : false);
563             $email = (isset($values['email']) ? $values['email'] : false);
564
565             if (($username != false) && ($password != false) && ($email != false))
566             {
567                 $password_email=$password;
568                 $password = $this->_encode($password);
569                 
570                 // reassignement to the encoded password
571                 $values['password'] = $password;
572                 
573                 // if we go for standard activation with e-mail verification
574                 // namely i.e. $config['FAL_register_direct'] = FALSE
575                 if (!$this->CI->config->item('FAL_register_direct'))
576                 {
577                     // generates the activation code
578                     $activation_code = $this->_generateRandomString();
579                     $values['activation_code'] = $activation_code;
580                     $query = $this->CI->UserTemp->insertUserForRegistration($values);
581                     
582                     // Use the input username and password and check against 'user_temp' table
583                     // needed to find the user_temp ID for the activation link
584                     $query = $this->CI->UserTemp->getUserLoginData($username, $password);
585
586                     $user_id = 0;
587                     if (($query != null) && ($query->num_rows() > 0))
588                     {
589                         $row = $query->row();
590                         $user_id = $row->id;
591     
592                         $this->_sendActivationEmail($user_id, $username, $password_email, $email, $activation_code);
593     
594                         return true;
595                     }
596                 }
597                 // do we skipp e-mail verification?
598                 // namely if we go for direct activation
599                 // i.e. $config['FAL_register_direct'] = TRUE
600                 else
601                 {
602                     // let's insert the values in the user table
603                     $query = $this->CI->usermodel->insertUser($values);
604                     
605                     // if affected rows ==1 set a flash message and redirect to login
606                     if ($this->CI->db->affected_rows() == 1)
607                     {
608                         // if we want the user profile as well
609                         if($this->CI->config->item('FAL_create_user_profile'))
610                         {   
611                             // let's get the last insert id
612                             $data_profile['id'] = $this->CI->db->insert_id();
613                             $this->CI->userprofile->insertUserProfile($data_profile);
614                         }
615                         
616                         flashMsg( $this->CI->lang->line('FAL_activation_success_message') );
617                         return true;
618                     }
619                     
620                     
621                 }
622             }
623             else
624             {
625                 // set FLASH MESSAGE
626                 flashMsg( $this->CI->lang->line('FAL_invalid_register_message') );
627                 // FIXME : if false is returned, no redirection is done in FAL_front
628                 return false;
629             }
630         }
631     }
632     
633      // --------------------------------------------------------------------
634         /**
635      * Handles the user activation requests.
636      *
637      * @param int $id user id
638      * @param varchar $activation_code user activation code
639      * @var $id user id
640      * @var $activation_code user activation code
641      * @return true if successful activation, false if unsucessful
642      */
643     function activation($id, $activation_code)
644     {   
645         // let's clean the user_temp table
646         // if we use registration with e-mail verification
647         if (!$this->CI->config->item('FAL_register_direct'))
648         {
649            $this->cleanExpiredUserTemp();
650         }
651               
652         if (($id > 0) && ($activation_code != ''))
653         {
654             // gets userdata from USER_TEMP table
655             $query = $this->CI->UserTemp->getUserForActivation($id, $activation_code);
656             
657             // deletes the record from USER_TEMP
658             $this->CI->UserTemp->deleteUserAfterActivation($id);
659             
660             if ($query->num_rows() > 0)
661             {
662                  foreach ($query->result() as $row)
663                     {
664                        $data['user_name'] = $row->user_name;
665                        $data['country_id'] = $row->country_id;
666                        $data['password'] = $row->password;
667                        $data['email'] = $row->email;
668                     }
669                     
670                     // let's insert the new data               
671                     // inserts the new user data in USER table
672                     $this->CI->usermodel->insertUser($data);
673                     
674                     // if we want the user profile as well
675                     if($this->CI->config->item('FAL_create_user_profile'))
676                     {   
677                         //let's get the last insert id
678                         $data_profile['id'] = $this->CI->db->insert_id();
679                         $this->CI->userprofile->insertUserProfile($data_profile);
680                     }
681
682                 return true;
683             }
684         }
685
686         return false;
687     }
688     
689     // --------------------------------------------------------------------
690     
691     /**
692      * Handles the user forgotten password $_POST requests
693      * returns true if password sent to user, false otherwise
694      * @return true if password sent to user
695      */
696     function forgotten_password()
697     {
698         if ($this->CI->db_session)
699         {
700             $email = $this->CI->input->post('email');
701             
702             // if $email not false
703             // checks the relative password for that user querying the DB
704             if (($email != false))
705             {
706                 $query = $this->CI->usermodel->getUserForForgottenPassword($email);
707
708                 if (($query != null) && ($query->num_rows() > 0))
709                 {
710                     $row = $query->row();
711                     $user_id = $row->{'id'};
712                     $user = $row->{'user_name'};
713                     
714                     //generates the activation code
715                     $activation_code = $this->_generateRandomString(50, 50);
716                     
717                     //updates the user table
718                     $this->CI->usermodel->updateUserForForgottenPassword($user_id, $activation_code);
719                     
720                     //sends e-mail to user
721                     $this->_sendForgottenPasswordEmail($user_id, $user, $email, $activation_code);
722                     
723                     return true;
724                 }
725             }
726             
727             //set unsuccess FLASH MESSAGE
728             $msg = $this->CI->lang->line('FAL_forgotten_password_user_not_found_message');
729             flashMsg($msg);
730             // FIXME : if false is returned, no redirection is done in FAL_front
731             return false;
732         }
733     }
734     
735     // --------------------------------------------------------------------
736     
737     /**
738      * Handles the user forgotten password reset requests,
739      * when the user clicks on the e-mail link.
740      * Returns true if the process has been successful, false otherwise
741      *
742      * @param integer $id
743      * @param varchar $activation_code
744      * @return true
745      */
746     function forgotten_password_reset($id, $activation_code)
747     {   
748         // checks if $id>0 and if $activation_code not null
749         if (($id > 0) && ($activation_code != ''))
750         {   
751             /**
752              * recalls the function getUserForForgottenPasswordReset($id, $activation_code)
753              * from the class usermodel
754              * it queries the database looking for the user's $id and $activation_code
755              */
756             $query = $this->CI->usermodel->getUserForForgottenPasswordReset($id, $activation_code);
757             
758             // if the query returns at least a result namely num_rows() > 0
759             if ($query->num_rows() > 0)
760             {
761                 $row = $query->row();
762                 $user_id = $row->{'id'};
763                 $user = $row->{'user_name'};
764                 $email = $row->{'email'};
765
766                 // generates a random password
767                 $password = $this->_generateRandomString($this->CI->config->item('FAL_user_password_min'), $this->CI->config->item('FAL_user_password_max'));
768                 
769                 // encrypts the random password using the md5 encryption
770                 $encrypted_password = $this->_encode($password);
771
772                 // sends the new generated password to the user
773                 $this->_sendForgottenPasswordResetEmail($user_id, $user, $email, $password);
774
775                 // updates the password in the database
776                 $this->CI->usermodel->updateUserForForgottenPasswordReset($user_id, $encrypted_password);
777
778                 return true;
779             }
780         }
781
782         return false;
783     }
784     
785     // --------------------------------------------------------------------
786     
787     /**
788      * Handles the user change password $_POST requests
789      * returns true if password sent to user, false otherwise
790      * @return true if password sent to user
791      */
792     function _change_password()
793     {
794         if ($this->CI->db_session)
795         {
796             $username = $this->CI->input->post('user_name');
797             $old_password = $this->CI->input->post('old_password');
798             $new_password = $this->CI->input->post('password');
799
800             // if $email not false checks the relative password for that user querying the DB
801             if ($username != false AND $old_password != false AND $new_password != false)
802             {
803                 $query = $this->CI->usermodel->getUserForLogin($username, $this->_encode($old_password));
804
805                 if (($query != null) && ($query->num_rows() == 1))
806                 {
807                     $row = $query->row();
808                     $user_id = $row->{'id'};
809                     $user = $row->{'user_name'};
810                     $email = $row->{'email'};
811
812                     // clear text password for e-mail
813                     $password_email = $new_password;
814                     
815                     // encrypts the password for DB update
816                     $new_password = $this->_encode($new_password);
817                     
818                     // updates the user table
819                     $this->CI->usermodel->updateUserForForgottenPasswordReset($user_id, $new_password);
820
821                     // sends e-mail to user
822                     $this->_sendChangePasswordEmail($user_id, $user, $email, $password_email);
823                     
824                     return true;
825                 }
826             }
827             
828             // set unsuccess FLASH MESSAGE
829             $msg = $this->CI->lang->line('FAL_change_password_failed_message');
830             flashMsg($msg);
831             
832             redirect($this->CI->config->item('FAL_changePassword_uri'), 'location');
833         }
834     }
835     
836     // --------------------------------------------------------------------
837     
838     /**
839      * Sets the userdata in the Db_session table
840      * and updates the user table for Last_login
841      *
842      * @param array $userdata
843      */
844     function _set_logindata($userdata)
845     {
846         //updates the Last_visit field in the user table
847         $this->CI->usermodel->updateUserForLogin($userdata['id']);
848         $this->CI->db_session->set_userdata($userdata);
849     }
850
851
852     // --------------------------------------------------------------------
853     
854     /**
855      * Unsets user data in session_data DB field of table ci_session
856      *
857      * @param integer $user_id
858      */
859     function _unset_user($_username)
860     {
861         $users = $this->CI->db_session->userdata('user_name');
862         
863         if (isset($users))
864         {
865             unset($users);
866             // is better to do a 1 call to unset_userdata passing an array?
867             $this->CI->db_session->unset_userdata('id');
868             $this->CI->db_session->unset_userdata('user_name');
869             $this->CI->db_session->unset_userdata('role');
870         }
871         
872     }
873
874
875     // --------------------------------------------------------------------
876     /**
877      * Needed to clean the UserTemp table from not completed registration
878      * The records get removed if older than what you set in the configuration
879      * file $config['FreakAuthL_temporary_users_expiration']
880      * Cleaning get performed after activation and on new registrations
881      *
882      */
883     function cleanExpiredUserTemp()
884     {
885         $expiration = $this->CI->config->item('FAL_temporary_users_expiration');
886         
887         $query = $this->CI->UserTemp->getUserTempCreated();
888         
889         if ($query->num_rows() > 0)
890         {
891             foreach ($query->result() as $row)
892             {
893                 if (time()>($row->created + $expiration))
894                 {
895                     $this->CI->UserTemp->deleteUserAfterActivation($row->id);
896                 }
897             }
898         }
899     }
900       
901
902     // --------------------------------------------------------------------
903     /**
904      * Returns the currently logged in user's name
905      * Returns an empty string if no user is logged in
906      * uses Class db_session method "userdata".
907      *
908      * @return username string of currently logged in user
909      * @return empty string if user not logged in
910      */
911     function getUserName()
912     {
913         if ($this->CI->config->item('FAL') && $this->CI->db_session)
914             
915             // returns username string of currently logged in user
916             return $this->CI->db_session->userdata('user_name');
917         
918         // returns empty string if user not logged in
919         return '';
920     }
921     
922     // --------------------------------------------------------------------
923     /**
924      * Returns the currently logged in user's property from the session.
925      *
926      * A property is what he gave when registering (like 'email'),
927      * or something calculated server-side (like 'last_visit').
928      * Returns an empty string if no user is logged in.
929      *
930      * Uses Class db_session method "userdata".
931      *
932      * @param string $prop can be 'id', 'user_name', 'country_id', 'email', 'role', 'last_visit', 'created', 'modified'
933      * @return prop string of currently logged in user
934      * @return empty string if user not logged in or prop unknown
935      */
936     function getUserProperty($prop)
937     {
938         if ($this->CI->config->item('FAL') && $this->CI->db_session)
939             
940             // returns property string of currently logged in user
941             return $this->CI->db_session->userdata($prop);
942         
943         // returns empty string if user not logged in
944         return '';
945     }
946     
947     // --------------------------------------------------------------------
948     /**
949      * Returns the property $prop of the user identified by $id from the database.
950      *
951      * A property is what he gave when registering (like 'email'),
952      * or something calculated server-side (like 'last_visit').
953      *
954      * @param integer $id the id of the user you are interested in
955      * @param string $prop can be 'id', 'user_name', 'country_id', 'email', 'role', 'last_visit', 'created', 'modified'
956      * @return prop string of the user identified by $id
957      * @return 'unknown user'  if user unknown
958      * @return empty string if prop unknow
959      */
960     function getUserPropertyFromId($id, $prop)
961     {
962         $query = $this->CI->usermodel->getUserById($id);
963         if ($query->num_rows() == 1)
964         {
965             $row = $query->row();
966             if (isset($row->{$prop})) return $row->{$prop};
967             else return '';
968         }
969         else
970         {
971             $this->CI->lang->load('freakauth');
972             return $this->CI->lang->line('FAL_unknown_user');
973         }
974     }
975     
976
977     // --------------------------------------------------------------------
978     /**
979      * Checks if Captcha is required
980      * if it is required in the config settings recalls function _generateCaptcha()
981      * to build it
982      */
983     function captcha_init($action)
984     {   
985         //checks FreakAuth security code configuration
986         if (!$this->CI->config->item('FAL_use_captcha'.$action))
987             
988             //if not set or FALSE
989             return;
990         
991         //ELSE unsets userdata from session table
992         $this->CI->db_session->unset_userdata('FreakAuth_captcha');
993         
994         //loads the captcha plugin
995         //$this->CI->load->plugin('captcha');
996         list($usec, $sec) = explode(" ", microtime());
997         $now = ((float)$usec + (float)$sec);
998         
999         //deletes captcha images
1000         $this->_deleteOldCaptcha($now);
1001         
1002         //generates security code image
1003         $this->_generateCaptcha($now);
1004     }
1005
1006     // --------------------------------------------------------------------
1007     /**
1008      * Deletes the captcha images generated
1009      * it deletes them if they "expired". The "expiration" (in seconds)
1010      * signifies how long an image will remain in the root/tmp folder before it
1011      * will be deleted.  The default is 10 minutes. Change the value
1012      * of $expiration if you want them to be deleted more or less often
1013      *
1014      * @param float $now
1015      * @todo move expiration time in a config variable
1016      */
1017     function _deleteOldCaptcha($now)
1018     {
1019         list($usec, $sec) = explode(" ", microtime());
1020         
1021         // sets the expiration time of the captcha image
1022         $expiration=60*10; //10 min
1023             
1024         $current_dir = @opendir($this->CI->config->item('FAL_captcha_image_path'));
1025         
1026         while($filename = @readdir($current_dir))
1027         {
1028             if ($filename != "." AND $filename != ".." AND $filename != "index.html")
1029             {
1030                 $name = str_replace(".jpg", "", $filename);
1031             
1032                 if (($name + $expiration) < $now)
1033                 {
1034                     @unlink($this->CI->config->item('FAL_captcha_image_path').$filename);
1035                 }
1036             }
1037         }
1038         
1039         @closedir($current_dir);
1040     }
1041     
1042     // --------------------------------------------------------------------
1043     
1044     /**
1045      * Creates a random security code image (Captcha).
1046      *
1047      * @return unknown
1048      */
1049     function _generateCaptcha($now)
1050     {
1051         
1052             $securityCode = $this->_generateRandomString($this->CI->config->item('FAL_captcha_min'), $this->CI->config->item('FAL_captcha_max'));
1053             //$image = 'security-'.$this->_generateRandomString(16, 32).'.jpg';
1054             $image = $now.'.jpg';
1055             $this->CI->config->set_item('FAL_captcha_image', $image);
1056             
1057             $config['image_library'] = $this->CI->config->item('FAL_captcha_image_library');
1058             $config['source_image'] = $this->CI->config->item('FAL_captcha_base_image_path').$this->CI->config->item('FAL_captcha_image_base_image');
1059             $config['new_image'] = $this->CI->config->item('FAL_captcha_image_path').$image;
1060             $config['wm_text'] = $securityCode;
1061             $config['wm_type'] = 'text';
1062             $config['wm_font_path'] = $this->CI->config->item('FAL_captcha_image_font');
1063             $config['wm_font_size'] = $this->CI->config->item('FAL_captcha_image_font_size');
1064             $config['wm_font_color'] = $this->CI->config->item('FAL_captcha_image_font_color');
1065             $config['wm_vrt_alignment'] = 'top';
1066             $config['wm_hor_alignment'] = 'left';
1067             $config['wm_padding'] = '10';
1068
1069             $image =& get_instance();
1070             $image->load->library('image_lib');
1071             $image->image_lib->initialize($config);
1072             
1073             if ( ! $image->image_lib->watermark())
1074             {
1075                 echo $image->image_lib->display_errors();
1076             };
1077             
1078             $this->CI->db_session->set_userdata('FreakAuth_captcha', $securityCode);           
1079             return $this->CI->config->item('FAL_captcha_image');
1080             
1081         
1082     }
1083     
1084     // --------------------------------------------------------------------
1085     
1086     /**
1087      * Generates a random string.
1088      *
1089      * @param integer $minLength
1090      * @param integer $maxLength
1091      * @param boolean $useUpper
1092      * @param boolean $useNumbers
1093      * @param boolean $useSpecial
1094      * @return $key random string
1095      */
1096     function _generateRandomString()
1097     {
1098         $charset = "abcdefghijklmnopqrstuvwxyz";
1099         if ($this->CI->config->item('FAL_captcha_upper_lower_case'))
1100             $charset .= "ABCDEFGHIJKLMNPQRSTUVWXYZ";
1101         if ($this->CI->config->item('FAL_captcha_use_numbers'))
1102             $charset .= "23456789";
1103         if ($this->CI->config->item('FAL_captcha_use_specials'))
1104             $charset .= "~@#$%^*()_+-={}|][";
1105             
1106         $length = mt_rand($this->CI->config->item('FAL_captcha_min'), $this->CI->config->item('FAL_captcha_max'));
1107         if ($this->CI->config->item('FAL_captcha_min') > $this->CI->config->item('FAL_captcha_max'))
1108             $length = mt_rand($this->CI->config->item('FAL_captcha_max'), $this->CI->config->item('FAL_captcha_min'));
1109
1110         $key = '';
1111         for ($i = 0; $i < $length; $i++)
1112             $key .= $charset[(mt_rand(0, (strlen($charset)-1)))];
1113
1114         return $key;
1115     }
1116
1117     // --------------------------------------------------------------------
1118     
1119     /**
1120      * Sends an email from the system to a given email address.
1121      *
1122      * @access private
1123      * @param varchar $email
1124      * @param varchar $subject
1125      * @param text $message
1126      */
1127     function _sendEmail($email, $subject, $message)
1128     {
1129         $tobj =& get_instance();
1130         $tobj->load->library('email');
1131         $tobj->email->clear();
1132         $tobj->email->from($this->CI->config->item('FAL_user_support'), $this->CI->config->item('FAL_website_name').' '.$this->CI->config->item('FAL_email_from'));
1133         $tobj->email->to($email);
1134         $tobj->email->subject($subject);
1135         $tobj->email->message($message);
1136         $tobj->email->send();
1137     }
1138     
1139     // --------------------------------------------------------------------
1140     
1141     /**
1142      * Sends an activation email from the system to the newly registered user
1143      *
1144      * @access private
1145      * @param integer $id
1146      * @param unknown_type $user
1147      * @param unknown_type $email
1148      * @param varchar $activation_code
1149      */
1150     function _sendActivationEmail($id, $user, $password_email, $email, $activation_code)
1151     {
1152         $activation_url = site_url($this->CI->config->item('FAL_activation_uri').'/'.$id.'/'.$activation_code);
1153         $data = array('activation_url' => $activation_url,
1154                       'user_name' => $user,
1155                       'password'=>$password_email);
1156
1157         $message = $this->CI->load->view($this->CI->config->item('FAL_activation_email'), $data, true);
1158         
1159         $subject= '['.$this->CI->config->item('FAL_website_name').'] '.$this->CI->lang->line('FAL_activation_email_subject');
1160         $this->_sendEmail($email, $subject , $message);
1161     }
1162     
1163     // --------------------------------------------------------------------
1164     
1165     /**
1166      * Sends an email from the system to the user that has forgotten the
1167      * password the e-mail contains the link to make the reset password start.
1168      *
1169      * @access private
1170      * @param unknown_type $id
1171      * @param unknown_type $user
1172      * @param unknown_type $email
1173      * @param unknown_type $activation_code
1174      */
1175     function _sendForgottenPasswordEmail($id, $user, $email, $activation_code)
1176     {
1177         $activation_url = site_url($this->CI->config->item('FAL_forgottenPasswordReset_uri').'/'.$id.'/'.$activation_code);
1178         $data = array('activation_url' => $activation_url,
1179                       'user_name' => $user);
1180
1181         $message = $this->CI->load->view($this->CI->config->item('FAL_forgotten_password_email'), $data, true);
1182         
1183         $subject= '['.$this->CI->config->item('FAL_website_name').'] '.$this->CI->lang->line('FAL_forgotten_password_email_subject');
1184         
1185         $this->_sendEmail($email, $subject, $message);
1186     }
1187
1188     // --------------------------------------------------------------------
1189     
1190     /**
1191      * Sends and e-mail to the user after resetting the password
1192      * The e-mail contains the new login informations
1193      *
1194      * @access private
1195      * @param integer $id
1196      * @param varchar $user
1197      * @param varchar $email
1198      * @param varchar $password
1199      */
1200     function _sendForgottenPasswordResetEmail($id, $user, $email, $password)
1201     {
1202         $data = array('password' => $password,
1203                       'user_name' => $user,
1204                       'change_password_link'=> site_url($this->CI->config->item('FAL_changePassword_uri'))
1205                       );
1206                       
1207         
1208         // displays message to the user on screen
1209         $message = $this->CI->load->view($this->CI->config->item('FAL_forgotten_password_reset_email'), $data, true);
1210         
1211         $subject= '['.$this->CI->config->item('FAL_website_name').'] '.$this->CI->lang->line('FAL_forgotten_password_email_reset_subject');
1212         // sends e-mail to the user to reset password
1213         $this->_sendEmail($email, $subject, $message);
1214     }
1215     
1216     // --------------------------------------------------------------------
1217     
1218     /**
1219      * Sends an email from the system to the user that has changed the password
1220      * the e-mail has the newly generated password.
1221      * @access private
1222      * @param unknown_type $id
1223      * @param unknown_type $user
1224      * @param unknown_type $email
1225      * @param unknown_type $activation_code
1226      */
1227     function _sendChangePasswordEmail($id, $user, $email, $password_email)
1228     {
1229         $data = array('user_name' => $user,
1230                       'password'=>$password_email);
1231
1232         $message = $this->CI->load->view($this->CI->config->item('FAL_change_password_email'), $data, true);
1233         
1234         $subject= '['.$this->CI->config->item('FAL_website_name').'] '.$this->CI->lang->line('FAL_forgotten_password_email_reset_subject');
1235         $this->_sendEmail($email, $subject , $message);
1236     }
1237     
1238
1239     // --------------------------------------------------------------------
1240     
1241     /**
1242      * Gets login form input values.
1243      *
1244      * @return array
1245      */
1246     function getLoginForm()
1247     {
1248         $values['user_name'] = $this->CI->input->post('user_name');
1249         $values['password'] = $this->CI->input->post('password');
1250         
1251         //$values[$this->CI->config->item('FAL_<your field>_field')] = $this->CI->input->post($this->CI->config->item('FAL_<your field>_field'));
1252         
1253         return $values;
1254     }
1255
1256     // --------------------------------------------------------------------
1257
1258     /**
1259      * Gets registration form input values.
1260      *
1261      * @return array
1262      */
1263     function getRegistrationForm()
1264     {
1265         $values['user_name'] = $this->CI->input->post('user_name', TRUE);
1266         $values['password'] = $this->CI->input->post('password');
1267         $values['email'] = $this->CI->input->post('email');
1268         if ($this->CI->config->item('FAL_use_country'))
1269             $values['country_id'] = $this->CI->input->post('country_id');
1270             
1271         //$values[$this->CI->config->item('FAL_<your field>_field')] = $this->CI->input->post($this->CI->config->item('FAL_<your field>_field'));
1272         
1273         return $values;
1274     }
1275     
1276       // --------------------------------------------------------------------
1277       /**
1278        * Custom encoding method for added security
1279        *
1280        * @param string $_password
1281        * @return encoded password
1282        */
1283       function _encode($password)
1284       {
1285         $majorsalt=null;
1286         
1287         // if you set your encryption key let's use it
1288           if ($this->CI->config->item('encryption_key')!='')
1289         {
1290             // conctenates the encryption key and the password
1291             $_password = $this->CI->config->item('encryption_key').$password;
1292         }
1293         else {$_password=$password;}
1294         
1295         // if PHP5
1296         if (function_exists('str_split'))
1297         {
1298             $_pass = str_split($_password);       
1299         }
1300         // if PHP4
1301         else
1302         {
1303             $_pass = array();
1304             if (is_string($_password))
1305             {
1306                 for ($i = 0; $i < strlen($_password); $i++)
1307                 {
1308                     array_push($_pass, $_password[$i]);
1309                 }
1310              }
1311         }
1312         
1313         // encrypts every single letter of the password
1314         foreach ($_pass as $_hashpass)
1315         {
1316             $majorsalt .= md5($_hashpass);
1317         }
1318         
1319         // encrypts the string combinations of every single encrypted letter
1320         // and finally returns the encrypted password
1321         return $password=md5($majorsalt);
1322         
1323       }
1324       
1325       // --------------------------------------------------------------------
1326       
1327       /**
1328        * Needed to display and edit user profile data
1329        *
1330        * @param integer user id $id
1331        * @return array of user profile data-> $data['user_profile']
1332        */
1333       function _getUserProfile($id)
1334       {   
1335           
1336                   //lets get fields names from config
1337           $field_name=$this->CI->config->item('FAL_user_profile_fields_names');
1338           
1339           //lets get fields validation rules from config
1340           $field_rule=$this->CI->config->item('FAL_user_profile_fields_validation_rules');
1341           
1342           
1343           //array of fields
1344           $db_fields=$this->CI->userprofile->getTableFields();
1345
1346           //number of DB fields -1
1347           //I put a -1 because I must subtract the 'id' field
1348           $num_db_fields=count($db_fields) - 1;
1349           
1350           
1351           if ($num_db_fields!=0)
1352           {   
1353             
1354               $query=$this->CI->userprofile->getUserProfileById($id);
1355                   
1356               if ($query->num_rows() == 1)
1357             {
1358                 $row = $query->row();
1359         
1360                 for ($i=1; $i<=$num_db_fields$i++)
1361                 {
1362                      $field = $db_fields[$i];
1363                      $data[$field]=$row->$db_fields[$i];                         
1364                 }
1365                       
1366                  return $data;
1367
1368             }
1369               else
1370             {
1371                //set_error_flash_message
1372                //set FLASH MESSAGE
1373                // $this->CI->db_session->set_flashdata('flashMessage', 'No profile found for this user');
1374               
1375                // grahack: removed this flash message since there is no redirection
1376                // (message was displayed in the next page)
1377                // anyway, the view file
1378                // views/FreakAuth_light/template_admin/users/detail.php
1379                // displays "no data in DB: please add them"
1380             }
1381           }
1382         else
1383             {
1384                return false;
1385             }
1386           
1387       }
1388       
1389       // --------------------------------------------------------------------
1390       
1391       /**
1392        * Needed to dynamically build rules and fields from config array for add
1393      * and edit custom user profile.
1394        *
1395        * @return array of data['rules'] and data['fields']
1396        */
1397       function _buildUserProfileFieldsRules()
1398       {
1399           // lets get fields names from config
1400           $field_name=$this->CI->config->item('FAL_user_profile_fields_names');
1401           
1402           // lets get fields validation rules from config
1403           $field_rule=$this->CI->config->item('FAL_user_profile_fields_validation_rules');
1404       
1405           
1406           // array of fields
1407           $db_fields=$this->CI->userprofile->getTableFields();
1408
1409           // number of DB fields -1
1410           // I put a -1 because I must subtract the 'id' field
1411           $num_db_fields=count($db_fields) - 1;
1412         
1413           // I use 'for' instead of 'foreach' because I have to escape the
1414         // 'id' field that has key=0 in my array
1415           for ($i=1; $i<=$num_db_fields$i++)
1416         {
1417              $field = $db_fields[$i];
1418              // creates rules
1419              // $data['rules'][$field] = $field_rule[$field];
1420              // if the rule for the fields in DB has been specified in the
1421              // config array
1422              // let's assign it, otherwise don't assign anything
1423              array_key_exists($field, $field_rule) ? $data['rules'][$field] = $field_rule[$field] : '';
1424              // creates fields
1425              // if the custom field name for the field in DB has been specified
1426              // in the config array
1427              // let's assign it otherwise let's call it with the name in DB
1428              array_key_exists($field, $field_name) ? $data['fields'][$field] = $field_name[$field] : $data['fields'][$field] = $field;
1429         }
1430
1431         
1432         return $data;
1433       }
1434           
1435 }
Note: See TracBrowser for help on using the browser.