12.23 php saved
stabb
Tags add more
 
Note
uses histories, login attempts tables, set to false if not using them
  1. <?php
  2.  
  3. /*
  4. * othAuth By othman ouahbi.
  5. * comments, bug reports are welcome crazylegs@gmail.com
  6. * @author CraZyLeGs
  7. * @version 0.5.0
  8. * @license MIT
  9. */
  10.  
  11. class othAuthComponent extends Object {
  12.    
  13. /**
  14. * Constants to modify the behaviour of othAuth Component
  15. */
  16.     // Form vars
  17.     var $user_login_var        = 'email';
  18.     var $user_passw_var        = 'password';
  19.     var $user_group_var        = 'group_id';
  20.     var $user_cookie_var       = 'cookie';
  21.    
  22.     // DB vars
  23.     var $user_table_login      = 'email';
  24.     var $user_table_passw      = 'password';
  25.     var $user_table_gid        = 'group_id';
  26.     var $user_table_active     = 'active';
  27.     var $user_table_last_visit = 'last_visit';
  28.     var $auth_url_redirect_var = 'from';
  29.     var $user_model       = 'User';
  30.     var $group_model      = 'Group';
  31.     var $permission_model = 'Permission';
  32.    
  33.     var $history_active   = true;
  34.     var $history_model    = 'UserHistory';
  35.  
  36.     /*
  37.      * Internals you don't normally need to edit those
  38.      */
  39.     var $components    = array('Session','RequestHandler');
  40.     var $controller    = true;
  41.     var $gid = 1;
  42.     var $redirect_page;
  43.     var $hashkey       = "beijing";
  44.     var $auto_redirect = true;
  45.    
  46.     var $login_page    = '/users/login';
  47.     var $logout_page   = '';
  48.     var $access_page   = '/users/access_page';
  49.     var $noaccess_page = "/users/login"; // session_flash, flash, back or a page url
  50.    
  51.     var $mode = 'oth';
  52.     var $pass_crypt_method         = 'md5'; // md5, sha1, crypt, crc32,callback
  53.     var $pass_crypt_callback       = null; // function name
  54.     var $pass_crypt_callback_file   = ''; // file where the function is declared ( in vendors )
  55.    
  56.     var $cookie_active      = true;
  57.     var $cookie_lifetime    = '+1 day';
  58.    
  59.     // asc : the most important group is the group with smallest value
  60.     // desc: the most important group is the group with greatest value
  61.     var $gid_order    = 'asc'; // asc desc
  62.     var $strict_gid_check   = true;
  63.    
  64.     var $kill_old_login     = true; // when true, form can have another login with the same hash and del the old
  65.    
  66.     var $allowedAssocUserModels       = array();
  67.     var $allowedAssocGroupModels      = array();
  68.     var $allowedAssocPermissionModels = array();
  69.    
  70.     var $error_number = 0;
  71.    
  72.     var $login_limit          = true; // flag to toggle login attempts feature
  73.     var $login_attempts_model   = 'LoginAttempts';
  74.     var $login_attempts_num     = 3;
  75.     var $login_attempts_timeout = 2; // in minutes
  76.     var $login_locked_out     = '+1 day';
  77.  
  78.    
  79.     function startup(&$controller)
  80.     {
  81.        //$this->controller = &$controller;
  82.        //pr($controller);
  83.     }
  84.    
  85.     function _getGidOp()
  86.     {
  87.         if($this->strict_gid_check) return '';
  88.         else return ($this->gid_order == 'desc')? '>=' : '<=';
  89.     }
  90.    
  91.     function _getHashOf($str)
  92.     {
  93.         switch($this->pass_crypt_method)
  94.         {
  95.             case 'sha1':
  96.                 return ($str == '')? '' : sha1($str);
  97.             break;
  98.             case 'crypt':
  99.                 return crypt($str);
  100.             break;
  101.             case 'callback':
  102.                 vendor($this->pass_crypt_callback_file);
  103.  
  104.                 if(function_exists($this->pass_crypt_callback))
  105.                     return call_user_func($this->pass_crypt_callback,$str);
  106.                
  107.                 return false;
  108.             break;
  109.             case 'md5':
  110.             default:
  111.                 return md5($str);
  112.             break;
  113.         }
  114.     }
  115.     function init($auth_config = null)
  116.     {
  117.         if(is_array($auth_config) && !is_null($auth_config) && !empty($auth_config))
  118.         {
  119.            
  120.             if(isset($auth_config['login_page']))
  121.                 $this->login_page = $auth_config['login_page'];
  122.            
  123.             if(isset($auth_config['logout_page']))
  124.                 $this->logout_page = $auth_config['logout_page'];
  125.            
  126.             if(isset($auth_config['access_page']))
  127.                 $this->access_page = $auth_config['access_page'];
  128.            
  129.             if(isset($auth_config['noaccess_page']))
  130.                 $this->noaccess_page = $auth_config['noaccess_page'];
  131.             else
  132.                 $this->noaccess_page = $this->login_page;
  133.  
  134.             if(isset($auth_config['auto_redirect']))
  135.                 $this->auto_redirect = (boolean) $auth_config['auto_redirect'];
  136.            
  137.             if(isset($auth_config['hashkey']))
  138.                 $this->hashkey = $auth_config['hashkey'];
  139.            
  140.             if(isset($auth_config['strict_gid_check']))
  141.                 $this->strict_gid_check = (boolean) $auth_config['strict_gid_check'];
  142.            
  143.             if(isset($auth_config['mode']))
  144.                 $this->mode = $auth_config['mode'];
  145.  
  146.             if(isset($auth_config['allowModels']) &&
  147.             is_array($auth_config['allowModels']))
  148.             {
  149.                 if(isset($auth_config['allowModels']['user']) &&  is_array($auth_config['allowModels']['user']))
  150.                     $this->allowedAssocUserModels = $auth_config['allowModels']['user'];
  151.                
  152.                 if(isset($auth_config['allowModels']['group']) && is_array($auth_config['allowModels']['group']))
  153.                     $this->allowedAssocGroupModels = $auth_config['allowModels']['group'];
  154.                
  155.                 if(isset($auth_config['allowModels']['permission']) && is_array($auth_config['allowModels']['permission']))
  156.                 {
  157.                     $this->allowedAssocPermissionModels = $auth_config['allowModels']['permission'];
  158.                 }
  159.             }
  160.         }
  161.        
  162.         // pass auth data to the view so it can be used by the helper
  163.         $this->_passAuthData();
  164.     }
  165.    
  166.    
  167.     function login($ap = 1,$order ='asc') // email,password,group
  168.    {
  169.        
  170.        if(!$this->_checkLoginAttempts())
  171.                return -3; // too many login attempts
  172.        
  173.        $params = null;
  174.        if(!empty($this->controller->data[$this->user_model]))
  175.                $params[$this->user_model] = $this->controller->data[$this->user_model];
  176.  
  177.         return $this->_login($params);
  178.    }
  179.    
  180.    function _login($params,$ignore_cookie = false)
  181.    {
  182.        switch ($this->mode)
  183.        {
  184.                case 'oth':
  185.                        return $this->othLogin($params,$ignore_cookie);
  186.                        break;
  187.                case 'nao':
  188.                        return $this->naoLogin($params,$ignore_cookie);
  189.                        break;
  190.                case 'acl':
  191.                        return $this->aclLogin($params,$ignore_cookie);
  192.                        break;
  193.                default:
  194.                        return $this->othLogin($params,$ignore_cookie);
  195.                        break;
  196.        }
  197.    }
  198.    
  199.     function othLogin($params,$ignore_cookie=false) // email,password,group
  200.     {
  201.          $params = $params[$this->user_model];
  202.          
  203.          if($this->Session->valid() && $this->Session->check('othAuth.'.$this->hashkey))
  204.              if(!$this->kill_old_login) return 1;
  205.  
  206.          if(($params == null) || !isset($params[$this->user_login_var]) || !isset($params[$this->user_passw_var]))
  207.              return 0;
  208.          
  209.          uses('sanitize');
  210.          $login = Sanitize::paranoid($params[$this->user_login_var],array('.','_','@'));
  211.          $passw = Sanitize::paranoid($params[$this->user_passw_var]);
  212.      
  213.          if($login == "" || $passw == "") return -1;
  214.        
  215.          if(!$ignore_cookie) $passw = $this->_getHashOf($passw);   
  216.        
  217.          $gid_check_op = $this->_getGidOp();//($this->strict_gid_check)?'':'<=';         
  218.          $conditions = array();
  219.          
  220.          if(isset($params[$this->user_group_var]))
  221.          {
  222.              $this->gid = (int) Sanitize::paranoid($params[$this->user_group_var]);
  223.              
  224.              // FIX
  225.             if( $this->gid < 1) $this->gid = 1;
  226.             $conditions[$this->user_model.'.'.$this->user_table_gid] = $gid_check_op.$this->gid;
  227.  
  228.          }
  229.  
  230.         $conditions[$this->user_model.'.'.$this->user_table_login] = $login;
  231.         $conditions[$this->user_model.'.'.$this->user_table_passw] = $passw;
  232.         $conditions[$this->user_model.'.'.$this->user_table_active] = 1;
  233.        
  234.         $UserModel = $this->_createModel();
  235.        
  236.         $row = $UserModel->find($conditions);
  237.        
  238.         if( empty($row) /* || $num_users != 1 */ )
  239.         {
  240.             $this->_saveLoginAttempts();
  241.             return -2;
  242.         }
  243.         else {
  244.             $this->_deleteLoginAttempts();
  245.            
  246.             if(!$ignore_cookie && !empty($params[$this->user_cookie_var]) )
  247.                 $this->_saveCookie($row);
  248.        
  249.             $this->_saveSession($row);
  250.            
  251.             // Update the last visit date to now
  252.             if(isset($this->user_table_last_visit))
  253.             {   
  254.                 $row[$this->user_model][$this->user_table_last_visit] = date('Y-m-d h:i:s');
  255.                 $res = $UserModel->save($row,false,array($this->user_table_last_visit));
  256.             }
  257.            
  258.             // 0.2.5 save history
  259.             if($this->history_active) $this->_addHistory($row);
  260.            
  261.             if($this->auto_redirect == true)
  262.             {
  263.                 if(!empty($row[$this->group_model]['redirect']))
  264.                     $goto = $row[$this->group_model]['redirect'];
  265.                 else
  266.                     $goto = $this->access_page;
  267.  
  268.                 $back = false;//isset($this->controller->params['url']['url'][$this->auth_url_redirect_var]);
  269.                 $this->redirect($goto,$back);
  270.             }
  271.             return 1;
  272.         }
  273.          
  274.     }
  275.    
  276.     function naoLogin($params,$ignore_cookie = false) // username,password,group
  277.     {
  278.          $params = $params[$this->user_model];
  279.          
  280.          if($this->Session->valid() && $this->Session->check('othAuth.'.$this->hashkey))
  281.          {
  282.              if(!$this->kill_old_login)
  283.              {
  284.                  return 1;
  285.              }
  286.          }
  287.          
  288.          if($params == null ||
  289.              !isset($params[$this->user_login_var]) ||
  290.              !isset($params[$this->user_passw_var]))
  291.          {
  292.              return 0;
  293.          }
  294.          
  295.          uses('sanitize');
  296.          $login = Sanitize::paranoid($params[$this->user_login_var]);
  297.          $passw = Sanitize::paranoid($params[$this->user_passw_var]);
  298.          if(isset($params[$this->user_group_var]))
  299.          {
  300.              
  301.              $this->gid = (int) Sanitize::paranoid($params[$this->user_group_var]);
  302.             if( $this->gid < 1)
  303.             {
  304.                 $this->gid = 1;
  305.             }
  306.          }
  307.      
  308.          if($login == "" || $passw == "")
  309.          {
  310.              return -1;
  311.          }
  312.          
  313.         if(!$ignore_cookie)
  314.         {
  315.             $passw = $this->_getHashOf($passw);   
  316.         }
  317.        
  318.         $conditions = array(
  319.                             "{$this->user_model}.".$this->user_table_login => "$login",
  320.                             "{$this->user_model}.".$this->user_table_passw => "$passw",
  321.                             "{$this->user_model}.".$this->user_table_active => 1);
  322.        
  323.         $UserModel =& new $this->user_model;
  324.         $UserModel->unbindAll(array('belongsTo'=>array($this->group_model)));
  325.         $UserModel->recursive = 2;
  326.  
  327.         $UserModel->{$this->group_model}->unbindAll(array('hasAndBelongsToMany'=>array($this->permission_model)));
  328.        
  329.         $row = $UserModel->find($conditions);
  330.        
  331.         $num_users = (int) $UserModel->findCount($conditions);
  332.  
  333.        $gids = array();
  334.  
  335.        if(!empty($row[$this->group_model])){
  336.                foreach ($row[$this->group_model] as $group){
  337.                        $gids[] = $group['level'];
  338.                }
  339.        }
  340.  
  341.        if($this->strict_gid_check)
  342.        {
  343.                $allowed = in_array($this->gid,$gids);
  344.        }
  345.        else
  346.        {
  347.                $allowed = false;
  348.                switch($this->gid_order)
  349.                {
  350.                    case 'asc':
  351.                        foreach($gids as $gid)
  352.                        {
  353.                            if($this->gid >= $gid)
  354.                            {
  355.                                $allowed = true;
  356.                                break;
  357.                            }
  358.                        }
  359.                    break;
  360.                    case 'desc':
  361.                        foreach($gids as $gid)
  362.                        {
  363.                            if($this->gid >= $gid)
  364.                            {
  365.                                $allowed = true;
  366.                                break;
  367.                            }
  368.                        }
  369.                    break;
  370.                }
  371.        }
  372.  
  373.        if( empty($row) || $num_users != 1 || !$allowed)
  374.        {
  375.                $this->_saveLoginAttempts();
  376.                return -2;
  377.        }
  378.        else
  379.        {
  380.             $this->_deleteLoginAttempts();
  381.            
  382.             if(!$ignore_cookie &&
  383.                 !empty($params[$this->user_cookie_var]) )
  384.             {
  385.                 $this->_saveCookie($row);
  386.             }
  387.            
  388.             $this->_saveSession($row);
  389.            
  390.             // Update the last visit date to now
  391.             if(isset($this->user_table_last_visit))
  392.             {   
  393.                 $row[$this->user_model][$this->user_table_last_visit] = date('Y-m-d h:i:s');
  394.                 $res = $UserModel->save($row,true,array($this->user_table_last_visit));
  395.             }
  396.            
  397.             // 0.2.5 save history
  398.             if($this->history_active)
  399.             {
  400.                 $this->_addHistory($row);
  401.             }
  402.            
  403.             $redirect_page = $this->access_page;
  404.             foreach($row[$this->group_model] as $grp)
  405.             {
  406.                 if($grp['level'] == $this->gid)
  407.                 {
  408.                     if(!empty($grp['redirect']))
  409.                     {
  410.                         $redirect_page = $grp['redirect'];
  411.                     }
  412.                 }
  413.             }
  414.    
  415.             $this->redirect($redirect_page);
  416.            
  417.             return 1;
  418.        }
  419.  
  420.     }
  421.    
  422.     // 0.2.5
  423.     function _addHistory(&$row)
  424.     {
  425.         $data[$this->history_model]['username']  = $row[$this->user_model][$this->user_table_login];
  426.         $data[$this->history_model]['fullname']  = $row[$this->user_model]['name'];
  427.         $data[$this->history_model]['groupname'] = $row[$this->group_model]['name'];
  428.         if(isset($row[$this->user_model][$this->user_table_last_visit]))
  429.         {
  430.             $data[$this->history_model]['visitdate'] = $row[$this->user_model][$this->user_table_last_visit];
  431.         }else
  432.         {
  433.             $data[$this->history_model]['visitdate'] = date('Y-m-d h:i:s');
  434.         }
  435.        
  436.         $HistoryModel =& new $this->history_model;
  437.         $HistoryModel->save($data);
  438.        
  439.     }
  440.     function _saveSession($row)
  441.     {   
  442.          $login = $row[$this->user_model][$this->user_table_login];
  443.          $passw = $row[$this->user_model][$this->user_table_passw];
  444.          $gid   = $row[$this->user_model][$this->user_table_gid];
  445.          //$hk = md5($this->hashkey.$login.$passw.$this->gid);
  446.          $hk    = $this->_getHashOf($this->hashkey.$login.$passw/*.$gid*/);
  447.          $row["{$this->user_model}"]['login_hash'] = $hk;
  448.           $row["{$this->user_model}"]['hashkey']    = $this->hashkey;
  449.           //$this->Session->write('othAuth.'.$this->gid,$row);
  450.          $this->Session->write('othAuth.'.$this->hashkey,$row);
  451.  
  452.     }
  453.    
  454.     // null, true to delete the cookie
  455.     function _saveCookie($row,$del = false)
  456.     {
  457.         if($this->cookie_active)
  458.         {
  459.             if(!$del)
  460.             {
  461.                 $login  = $row[$this->user_model][$this->user_table_login];
  462.                 $passw  = $row[$this->user_model][$this->user_table_passw];
  463.                
  464.                 $time   = strtotime($this->cookie_lifetime);
  465.                 $data   = $login.'|'.$passw;
  466.                 $data   = serialize($data);
  467.                 $data   = $this->encrypt($data);
  468.                 setcookie('othAuth',$data,$time,'/');
  469.             }else
  470.             {
  471.                 setcookie('othAuth','',strtotime('-999 day'),'/');
  472.             }
  473.         }
  474.     }
  475.    
  476.     function _readCookie()
  477.     {
  478.         // does session exists
  479.         if($this->Session->valid() && $this->Session->check('othAuth.'.$this->hashkey))
  480.         {
  481.             return;
  482.         }
  483.         if($this->cookie_active && isset($_COOKIE['othAuth']))
  484.         {
  485.            
  486.             $str = $_COOKIE['othAuth'];
  487.             if (get_magic_quotes_gpc())
  488.             {   
  489.                 $str=stripslashes($str);
  490.             }
  491.                        
  492.             $str = $this->decrypt($str);
  493.              
  494.             $str = @unserialize($str);         
  495.            
  496.             list($login,$passw) = explode('|',$str);
  497.             //die($passw);
  498.            
  499.             $data[$this->user_model][$this->user_login_var] = $login;
  500.             $data[$this->user_model][$this->user_passw_var] = $passw;
  501.             $redirect_old = $this->auto_redirect;
  502.             $this->auto_redirect = false;
  503.             $ret = $this->_login($data,true);
  504.             $this->auto_redirect = $redirect_old;
  505.            
  506.         }
  507.     }
  508.    
  509.     // delete attempts after a successful login
  510.     function _deleteLoginAttempts()
  511.     {
  512.         if($this->login_limit)
  513.         {
  514.             $ip = env('REMOTE_ADDR');
  515.             $Model = & new $this->login_attempts_model;
  516.             $Model->del($ip);
  517.            
  518.             if($this->cookie_active)
  519.                 setcookie('othAuth.login_attempts','',time() - 31536000,'/');
  520.  
  521.         }
  522.        
  523.     }
  524.     function _checkLoginAttempts()
  525.     {
  526.         if($this->login_limit)
  527.         {
  528.             $ip = env('REMOTE_ADDR');
  529.            
  530.             $Model = & new $this->login_attempts_model;
  531.            
  532.             // delete all expired and timedout records
  533.             $del_sql = "DELETE FROM {$Model->useTable} WHERE expire <= NOW()";
  534.             if($this->login_attempts_timeout > 0)
  535.             {
  536.                 $timeout = $this->login_attempts_timeout * 60;
  537.                 $del_sql .= " OR ( UNIX_TIMESTAMP(created) > UNIX_TIMESTAMP(NOW()) - $timeout )";
  538.             }
  539.             $Model->query($del_sql);
  540.            
  541.             $row = $Model->find(array($this->login_attempts_model.'.ip'=>$ip));
  542.            
  543.             //die("hi!");
  544.             if(!empty($row))
  545.             {
  546.                 $num = $row[$this->login_attempts_model]['num'];
  547.                
  548.                 $this->login_attempts_current_num = $num;
  549.                
  550.                 if($num >= $this->login_attempts_num)
  551.                 {
  552.                     return false;
  553.                 }
  554.             }else
  555.             {
  556.                 $this->login_attempts_current_num = 0;
  557.             }
  558.            
  559.             if($this->cookie_active && isset($_COOKIE['othAuth.login_attempts']))
  560.             {
  561.                 $cdata = $_COOKIE['othAuth.login_attempts'];
  562.                 if (get_magic_quotes_gpc())
  563.                 {   
  564.                     $cdata=stripslashes($cdata);
  565.                 }
  566.                            
  567.                 $cdata = $this->decrypt($cdata);
  568.                  
  569.                 $cdata = @unserialize($cdata);     
  570.                
  571.                 $time      = $cdata['t'];
  572.                 $num_tries = $cdata['n'];
  573.                
  574.                 if($num_tries >= $this->login_attempts_num)
  575.                 {
  576.                     return false;
  577.                 }
  578.                
  579.                 if($this->login_attempts_current_num == 0 && $num_tries > 0)
  580.                 {
  581.                     $this->login_attempts_current_num = $num_tries;
  582.                 }
  583.  
  584.             }
  585.         }
  586.         return true;
  587.     }
  588.    
  589.     function _saveLoginAttempts()
  590.     {
  591.         $num_tries = $this->login_attempts_current_num + 1;
  592.        
  593.         if($this->login_limit)
  594.         {
  595.             if (!is_numeric($this->login_locked_out))
  596.             {
  597.                 $keep_for = (int) strtotime($this->login_locked_out);
  598.                 $time   = ($keep_for > 0 ? $keep_for : 999999999);
  599.             }
  600.             else
  601.             {
  602.                 $keep_for = $this->login_locked_out;
  603.                 $time   = time() + ($keep_for > 0 ? $keep_for : 999999999);
  604.             }
  605.            
  606.             //die(date("Y-m-d H:i:s",$keep_for));
  607.            
  608.            
  609.            
  610.             $expire = date("Y-m-d H:i:s", $time);
  611.             $ip     = env('REMOTE_ADDR');
  612.            
  613.             //die(pr($expire));
  614.             $data[$this->login_attempts_model]['ip']     = $ip;
  615.             $data[$this->login_attempts_model]['expire'] = $expire;
  616.             $data[$this->login_attempts_model]['num']    = $num_tries;
  617.            
  618.             if($num_tries <= 1) // dunno why the model doesn't handle this
  619.             {
  620.                 $data[$this->login_attempts_model]['created'] = $expire;
  621.             }
  622.            
  623.             $Model = & new $this->login_attempts_model;
  624.             $Model->save($data);
  625.            
  626.             if($this->cookie_active)
  627.             {
  628.                 $cdata = $this->encrypt(serialize(array('t'=>time(),'n'=>$num_tries)));
  629.                 setcookie('othAuth.login_attempts',$cdata,$time,'/');
  630.             }
  631.         }
  632.     }
  633.    
  634.     function __notcurrent($page)
  635.     {
  636.         if($page == "") return false;
  637.        
  638.         uses('inflector');
  639.        
  640.         $c = strtolower(Inflector::underscore($this->controller->name));
  641.         $a = strtolower($this->controller->action);
  642.        
  643.         $page = strtolower($page.'/');
  644.        
  645.         $c_a = $this->_handleCakeAdmin($c,$a);
  646.         if($page[0] == '/')
  647.         {
  648.             $c_a = '/'.$c_a;
  649.         }
  650.         //die($c_a.' '.$page);
  651.         $not_current = strpos($page,$c_a);
  652.         // !== is required, $not_current might be boolean(false)
  653.         return ((!is_int($not_current)) || ($not_current !== 0));
  654.     }
  655.    
  656.     function redirect($page = "",$back = false)
  657.     {
  658.         if($page == "") $page = $this->logout_page;
  659.            
  660.         if(isset($this->auth_url_redirect_var))
  661.         {
  662.             if(!isset($this->controller->params['url'][$this->auth_url_redirect_var]))
  663.             {   
  664.                 if($back == true)
  665.                 {
  666.                     $this->Session->write('othAuth.frompage',$this->controller->params['url']['url']);
  667.                     $page .= "?".$this->auth_url_redirect_var."=".$this->controller->params['url']['url'];
  668.                 }
  669.                 else
  670.                 {   
  671.                     if($this->Session->check('othAuth.frompage'))
  672.                     {
  673.                         $page = $this->Session->read('othAuth.frompage');
  674.                         $this->Session->del('othAuth.frompage');
  675.                     }
  676.                 }
  677.             }   
  678.            
  679.         }
  680.  
  681.         if($this->__notcurrent($page))
  682.         {
  683.            if($this->__notcurrent($page))
  684.            {
  685.  
  686.                if ($this->RequestHandler->isAjax())
  687.                {
  688.                        $this->RequestHandler->setAjax($this->controller);
  689.                        // Brute force !
  690.                        echo '<script type="text/javascript">window.location = "'.
  691.                        $this->url($page).
  692.                        '"</script>';
  693.                        exit;
  694.                }
  695.                else
  696.                {
  697.                        $this->controller->redirect($page);
  698.                        exit;
  699.                }
  700.            }
  701.         }
  702.     }
  703.    
  704.     // users/login users/logout
  705.     // Logout the user
  706.     function logout ($kill_cookie = false)
  707.     {   
  708.         $us = 'othAuth.'.$this->hashkey;
  709.        
  710.         if($this->Session->valid() && $this->Session->check($us))
  711.         {
  712.             $ses = $this->Session->read($us);
  713.            
  714.             if(!empty($ses) && is_array($ses))
  715.             {
  716.                 // two logins of different hashkeys can exist
  717.                 if($this->hashkey == $ses[$this->user_model]['hashkey'])
  718.                 {
  719.                     $this->Session->del($us);
  720.                     $this->Session->del('othAuth.frompage');
  721.                     /*
  722.                     $o = $this->Session->check('othAuth');
  723.                     if( is_array( $o ) && empty( $o  ))
  724.                     {
  725.                         $this->Session->del('othAuth');
  726.                     }
  727.                     */
  728.                     if($kill_cookie)
  729.                     {
  730.                         $this->_saveCookie(null,true);
  731.                     }                   
  732.                     if($this->auto_redirect == true)
  733.                     {   
  734.                         // check if logout_page is the action where logout is called!
  735.                         if(!empty($this->logout_page))
  736.                         {
  737.                             $this->redirect($this->logout_page);
  738.                         }
  739.                         return true;
  740.                     }
  741.                    
  742.                 }
  743.             }
  744.         }
  745.         return false;
  746.     }
  747.    
  748.  
  749.     // Confirms that an existing login is still valid
  750.     function check()
  751.     {
  752.        
  753.         // is there a restriction list && action is in
  754.         if($this->_validRestrictions())
  755.         {
  756.             // try to read cookie
  757.             $this->_readCookie();
  758.             $us        = 'othAuth.'.$this->hashkey;
  759.            
  760.             // does session exists
  761.             if($this->Session->valid() &&
  762.                $this->Session->check($us))
  763.             {
  764.                 $ses        = $this->Session->read($us);
  765.                 $login     = $ses["{$this->user_model}"][$this->user_table_login];
  766.                 $password  = $ses["{$this->user_model}"][$this->user_table_passw];
  767.                 $gid       = $ses["{$this->user_model}"][$this->user_table_gid];
  768.                 $hk        = $ses["{$this->user_model}"]['login_hash'];
  769.                
  770.                
  771.                 // is user invalid
  772.                 if ($this->_getHashOf($this->hashkey.$login.$password/*.$gid*/) != $hk)
  773.                 {   
  774.                     $this->logout();
  775.                     return false;
  776.                 }
  777.                  
  778.                switch ($this->mode)
  779.                {
  780.                    case 'oth':
  781.                            $permi = $this->_othCheckPermission($ses);
  782.                          
  783.                            break;
  784.                    case 'nao':
  785.                            $permi = $this->_othCheckPermission($ses,true);
  786.                            break;
  787.                    case 'acl':
  788.                            $permi = $this->_aclCheckPermission($ses);
  789.                            break;
  790.                    default:
  791.                            $permi = $this->_othCheckPermission($ses);
  792.                }
  793.                 // check permissions on the current controller/action/p/a/r/a/m/s
  794.                 if(!$permi)
  795.                 {
  796.                     if($this->auto_redirect == true)
  797.                     {
  798.                         // should probably add $this->noaccess_page too or just flash
  799.                         //print_r($this->controller->params);
  800.                         $this->redirect($this->noaccess_page,true);
  801.                     }
  802.                     return false;
  803.                 }
  804.                
  805.                 return true;
  806.                
  807.             }
  808.            
  809.             if($this->auto_redirect == true)
  810.             {
  811.                 $this->redirect($this->login_page,true);
  812.             }
  813.             return false;   
  814.         }
  815.        
  816.         return true;
  817.     }
  818.    
  819.     function _validRestrictions()
  820.     {
  821.        
  822.         $isset   = isset($this->controller->othAuthRestrictions);
  823.         if($isset)
  824.         {
  825.             $oth_res = $this->controller->othAuthRestrictions;
  826.            
  827.             if(is_string($oth_res))
  828.             {
  829.                
  830.                
  831.                 if(($oth_res === "*") ||(
  832.                 defined('CAKE_ADMIN') && (($oth_res === CAKE_ADMIN) || $this->isCakeAdminAction())))
  833.                 {
  834.                     if(
  835.                        $this->__notcurrent($this->login_page) &&
  836.                        $this->__notcurrent($this->logout_page))
  837.                     {
  838.                         //die('here');
  839.                         return true;
  840.                     }   
  841.                 }
  842.                
  843.             }
  844.             elseif(is_array($oth_res))
  845.             {
  846.                 if(defined('CAKE_ADMIN'))
  847.                 {
  848.                     if(in_array(CAKE_ADMIN,$oth_res))
  849.                     {
  850.                         if($this->isCakeAdminAction())
  851.                         {
  852.                             if($this->__notcurrent($this->login_page) &&
  853.                                $this->__notcurrent($this->logout_page))
  854.                             {
  855.                                 return true;
  856.                             }
  857.                         }
  858.                     }
  859.                 }
  860.                 foreach($oth_res as $r)
  861.                 {
  862.                     $pos = strpos($r."/",$this->controller->action."/");
  863.                     if($pos === 0)
  864.                     {
  865.                         return true;
  866.                     }
  867.                 }
  868.             }
  869.         }
  870.        
  871.         return false;
  872.     }
  873.    
  874.     function _othCheckPermission(&$ses,$multi = false)
  875.     {
  876.         //die('c');
  877.         uses('inflector');
  878.        
  879.         $c   = strtolower(Inflector::underscore($this->controller->name));
  880.         $a   = strtolower($this->controller->action);
  881.         $h   = strtolower($this->controller->here);
  882.         $c_a = $this->_handleCakeAdmin($c,$a);// controller/admin_action -> admin/controller/action
  883.        
  884.         // extract params
  885.         $aa  =  substr( $c_a, strpos($c_a,'/'));
  886.        
  887.         $params = isset($this->controller->params['pass'])?implode('/',$this->controller->params['pass']): '';
  888.        
  889.         $c_a_p = $c_a.$params;
  890.        
  891.         $return = false;
  892.        
  893.         if(!isset($ses[$this->group_model][$this->permission_model]))
  894.         {
  895.             return false;
  896.         }
  897.         if(!$multi)
  898.         {
  899.             $ses_perms = $ses[$this->group_model][$this->permission_model];
  900.         }else
  901.         {
  902.            foreach ($ses[$this->group_model] as $groups)
  903.            {
  904.                if(isset($groups[$this->permission_model])){
  905.                        $ses_perms = am($ses_perms, $groups[$this->permission_model]);
  906.                }
  907.            }
  908.         }
  909.        
  910.         // quickly check if the group has full access (*) or
  911.         // current_controller/* or CAKE_ADMIN/current_controller/*
  912.         // full params check isn't supported atm
  913.         foreach($ses_perms as $sp)
  914.         {
  915.             if($sp['name'] == '*')
  916.             {
  917.                 return true;
  918.             }else
  919.             {
  920.                 $sp_name = strtolower($sp['name']);
  921.                 $perm_parts = explode('/',$sp_name);
  922.                 // users/edit/1 users/edit/*
  923.                 //  users/* users/*
  924.                
  925.                 if(defined('CAKE_ADMIN'))
  926.                 {
  927.                    
  928.                     if((count($perm_parts) > 1)  &&
  929.                        ($perm_parts[0] == CAKE_ADMIN) &&
  930.                        ($perm_parts[1] == $c) &&
  931.                        ($perm_parts[2] == "*"))
  932.                     {
  933.                         return true;
  934.                     }
  935.                 }
  936.                 //else
  937.                 //{
  938.                     if((count($perm_parts) > 1)  &&
  939.                        ($perm_parts[0] == $c) &&
  940.                        ($perm_parts[1] == "*"))
  941.                     {
  942.                         return true;
  943.                     }
  944.                 //}
  945.  
  946.             }
  947.         }
  948.        
  949.        
  950.         if(is_string($this->controller->othAuthRestrictions))
  951.         {
  952.             $is_checkall   = $this->controller->othAuthRestrictions === "*";
  953.             $is_cake_admin = defined('CAKE_ADMIN') && ($this->controller->othAuthRestrictions === CAKE_ADMIN);
  954.             if($is_checkall || $is_cake_admin)
  955.             {
  956.                 foreach($ses_perms as $p)
  957.                 {   
  958.                     if(strpos($c_a_p,strtolower($p['name'])) === 0)
  959.                     {
  960.                         $return = true;
  961.                         break;
  962.                     }
  963.                 }
  964.             }
  965.         }
  966.         else
  967.         {
  968.             $a_p_in_array = in_array($a.'/'.$params, $this->controller->othAuthRestrictions);
  969.            
  970.             // if current url is restricted, do a strict compare
  971.             // ex if current url action/p and current/p is in the list
  972.             // then the user need to have it in perms
  973.             // current/p/s current/p
  974.             if($a_p_in_array)
  975.             {
  976.                
  977.                 foreach($ses_perms as $p)
  978.                 {
  979.                     if($c_a_p == strtolower($p['name']))
  980.                     {
  981.                         $return = true;
  982.                         break;
  983.                     }
  984.                 }
  985.             }
  986.             // allow a user with permssion on the current action to access deeper levels
  987.             // ex: user access = 'action', allow 'action/p'
  988.             else
  989.             {
  990.                 foreach($ses_perms as $p)
  991.                 {
  992.                     if(strpos($c_a_p,strtolower($p['name'])) === 0)
  993.                     {
  994.                         $return = true;
  995.                         break;
  996.                     }
  997.                 }
  998.             }
  999.         }
  1000.         return $return;
  1001.     }
  1002.    
  1003.    function _aclCheckPermission(&$ses)
  1004.    {
  1005.            //die('c');
  1006.            $c   = Inflector::underscore($this->controller->name);
  1007.            $a   = $this->controller->action;
  1008.  
  1009.            $aco = "$c:$a";
  1010.  
  1011.            $login = $ses["{$this->user_model}"][$this->user_table_login];
  1012.  
  1013.            return $this->_aclCheckAccess($login, $aco);
  1014.    }
  1015.  
  1016.    function _aclCheckAccess($aro_alias, $aco)
  1017.    {
  1018.            // Check access using the component:
  1019.            $access = $this->Acl->check($aro_alias, $aco, $action = "*");
  1020.            if ($access === false)
  1021.            {
  1022.                    return false;
  1023.            }
  1024.            else
  1025.            {
  1026.                    return true;
  1027.            }
  1028.    }
  1029.    
  1030.     function _handleCakeAdmin($c,$a)
  1031.     {
  1032.         if(defined('CAKE_ADMIN'))
  1033.         {
  1034.             $strpos = strpos($a,CAKE_ADMIN.'_');
  1035.             if($strpos === 0)
  1036.             {
  1037.                 $function = substr($a,strlen(CAKE_ADMIN.'_'));
  1038.                 if($c == null) return $function.'/';
  1039.                 $c_a = CAKE_ADMIN.'/'.$c.'/'.$function.'/';
  1040.                 return $c_a;
  1041.             }else
  1042.             {
  1043.                 if($c == null) return $a.'/';
  1044.             }   
  1045.         }
  1046.         return $c.'/'.$a.'/';
  1047.     }
  1048.    
  1049.     function getSafeCakeAdminAction()
  1050.     {
  1051.         if(defined('CAKE_ADMIN'))
  1052.         {
  1053.             $a = $this->controller->action;
  1054.             $strpos = strpos($a,CAKE_ADMIN.'_');
  1055.             if($strpos === 0)
  1056.             {
  1057.                 $function = substr($a,strlen(CAKE_ADMIN.'_'));
  1058.                
  1059.                 return $function;
  1060.             }
  1061.         }
  1062.         return $this->controller->action;
  1063.     }
  1064.    
  1065.     function isCakeAdminAction()
  1066.     {
  1067.         if(defined('CAKE_ADMIN'))
  1068.         {
  1069.             $a = $this->controller->action;
  1070.             $strpos = strpos($a,CAKE_ADMIN.'_');
  1071.             if($strpos === 0)
  1072.             {
  1073.                 return true;
  1074.             }
  1075.         }
  1076.         return false;
  1077.     }
  1078.    
  1079.     // helper methods
  1080.     function user($arg)
  1081.     {
  1082.         $us = 'othAuth.'.$this->hashkey;
  1083.         // does session exists
  1084.         if($this->Session->valid() && $this->Session->check($us))
  1085.         {
  1086.             $ses = $this->Session->read($us);
  1087.             if(isset($ses["{$this->user_model}"][$arg]))
  1088.             {
  1089.                 return $ses["{$this->user_model}"][$arg];
  1090.             }
  1091.             else
  1092.             {
  1093.                 return false;
  1094.             }
  1095.         }
  1096.         return false;   
  1097.     }
  1098.    
  1099.     // helper methods
  1100.     function group($arg)
  1101.     {
  1102.         $us = 'othAuth.'.$this->hashkey;
  1103.         // does session exists
  1104.         if($this->Session->valid() && $this->Session->check($us))
  1105.         {
  1106.             $ses = $this->Session->read($us);
  1107.             if(isset($ses["{$this->group_model}"][$arg]))
  1108.             {
  1109.                 return $ses["{$this->group_model}"][$arg];
  1110.             }
  1111.             else
  1112.             {
  1113.                 return false;
  1114.             }
  1115.         }
  1116.         return false;   
  1117.     }
  1118.  
  1119.     /**
  1120.      * Get user's company session value.
  1121.      *
  1122.      * @return mixed
  1123.      * @author Nio Xiao
  1124.      **/
  1125.     function company($arg)
  1126.     {
  1127.         $us = 'othAuth_'.$this->hashkey;
  1128.         // does session exists
  1129.         if($this->Session->valid() && $this->Session->check($us))
  1130.         {
  1131.             $ses = $this->Session->read($us);
  1132.             if(isset($ses['Company'][$arg]))
  1133.             {
  1134.                 return $ses['Company'][$arg];
  1135.             }
  1136.             else
  1137.             {
  1138.                 return false;
  1139.             }
  1140.         }
  1141.         return false;
  1142.     }
  1143.    
  1144.    
  1145.     // helper methods
  1146.     function permission($arg)
  1147.     {
  1148.         $us = 'othAuth.'.$this->hashkey;
  1149.         // does session exists
  1150.         if($this->Session->valid() && $this->Session->check($us))
  1151.         {
  1152.             $ses = $this->Session->read($us);
  1153.             if(isset($ses[$this->group_model][$this->permission_model]))
  1154.             {
  1155.                 $ret = array();
  1156.                 if(is_array($ses[$this->group_model][$this->permission_model]))
  1157.                 {
  1158.                     for($i = 0; $i < count($ses[$this->group_model][$this->permission_model]); $i++ )
  1159.                     {
  1160.                         $ret[] = $ses[$this->group_model][$this->permission_model][$i][$arg];   
  1161.                     }
  1162.                 }
  1163.                 return $ret;
  1164.             }
  1165.             else
  1166.             {
  1167.                 return false;
  1168.             }
  1169.         }
  1170.         return false;   
  1171.     }
  1172.    
  1173.     function getData($arg = '')
  1174.     {
  1175.         $us = 'othAuth.'.$this->hashkey;
  1176.         // does session exists
  1177.         if($this->Session->valid() && $this->Session->check($us))
  1178.         {
  1179.             $data = $this->Session->read($us);
  1180.             if(in_array(strtolower($arg),array('user','group','permission')))
  1181.             {
  1182.                 return $data;
  1183.             }
  1184.             return $data;
  1185.         }
  1186.         return false;
  1187.     }
  1188.    
  1189.     // passes data to the view to be used by the helper
  1190.     function _passAuthData()
  1191.     {
  1192.        
  1193.         $data = get_object_vars($this);
  1194.        
  1195.         unset($data['controller']);
  1196.         unset($data['components']);
  1197.         unset($data['Session']);
  1198.         unset($data['RequestHandler']);
  1199.        
  1200.         $this->controller->set('othAuth_data',$data);
  1201.     }
  1202.    
  1203.    
  1204.     function encrypt($string)
  1205.     {
  1206.         $key = $this->hashkey;
  1207.         $result = '';
  1208.         for($i=0; $i<strlen($string); $i++) {
  1209.               $char = substr($string, $i, 1);
  1210.              $keychar = substr($key, ($i % strlen($key))-1, 1);
  1211.              $char = chr(ord($char)+ord($keychar));
  1212.              $result.=$char;
  1213.            }
  1214.  
  1215.            return base64_encode($result);
  1216.       }
  1217.  
  1218.       function decrypt($string)
  1219.       {
  1220.            $key = $this->hashkey;
  1221.            $result = '';
  1222.            $string = base64_decode($string);
  1223.  
  1224.            for($i=0; $i<strlen($string); $i++) {
  1225.              $char = substr($string, $i, 1);
  1226.              $keychar = substr($key, ($i % strlen($key))-1, 1);
  1227.              $char = chr(ord($char)-ord($keychar));
  1228.              $result.=$char;
  1229.            }
  1230.  
  1231.            return $result;
  1232.   }
  1233.     function getMsg($id)
  1234.     {
  1235.         switch($id) {
  1236.         case 1:
  1237.             {
  1238.                 return "You are already logged in.";
  1239.             }break;
  1240.         case 0:
  1241.             {
  1242.                 return "Please login!";
  1243.             }break;
  1244.         case -1:
  1245.             {
  1246.                  return $this->user_login_var."/".$this->user_passw_var." empty";
  1247.             }break;
  1248.         case -2:
  1249.             {
  1250.                  return "Wrong ".$this->user_login_var."/".$this->user_passw_var;
  1251.             }break;
  1252.         case -3:
  1253.             {
  1254.                  return "Too many login attempts.";
  1255.             }break;
  1256.         default:
  1257.             {
  1258.                  return "Invalid error ID";
  1259.             }break;
  1260.        
  1261.         }
  1262.     }
  1263.    
  1264.     /*
  1265.      * Create the User model to be used in login methods.
  1266.      */
  1267.     function _createModel()
  1268.     {
  1269.         // since we don't know if the models have extra associations we need to
  1270.         // unbind all the models, and bind only the ones we're interested in
  1271.         // mainly for performance ( and security )
  1272.        
  1273.         $UserModel =& new $this->user_model;
  1274.        
  1275.         $forUser  = array('belongsTo'=>array($this->group_model));
  1276.         $forGroup = array('hasAndBelongsToMany'=>array($this->permission_model));
  1277.         $forPerm  = array();
  1278.        
  1279.         $forUser  = $this->_mergeModelsToKeep($forUser,$this->allowedAssocUserModels);
  1280.         $forGroup = $this->_mergeModelsToKeep($forGroup,$this->allowedAssocGroupModels);
  1281.         $forPerm  = $this->_mergeModelsToKeep($forPerm,$this->allowedAssocPermissionModels);
  1282.        
  1283.  
  1284.        
  1285.         $UserModel->recursive = 2;
  1286.         $UserModel->unbindAll($forUser);
  1287.         $UserModel->{$this->group_model}->unbindAll($forGroup);
  1288.        
  1289.         $UserModel->{$this->group_model}->{$this->permission_model}->unbindAll($forPerm);
  1290.                                                                        
  1291.         return $UserModel;
  1292.     }
  1293.    
  1294.     function _mergeModelsToKeep($initial,$toAdd)
  1295.     {
  1296.         if(!empty($toAdd))
  1297.         {
  1298.             if(isset($toAdd['belongsTo']))
  1299.             {
  1300.                 $initial['belongsTo'] =
  1301.                 am($initial['belongsTo'],$toAdd['belongsTo']);
  1302.             }
  1303.             if(isset($toAdd['belongsTo']))
  1304.             {
  1305.                 $initial['hasMany'] =
  1306.                 am($initial['hasMany'],$toAdd['hasMany']);
  1307.             }
  1308.             if(isset($toAdd['hasAndBelongsToMany']))
  1309.             {
  1310.                 $initial['hasAndBelongsToMany'] = am($initial['hasAndBelongsToMany'],
  1311.                                                      $toAdd['hasAndBelongsToMany']);
  1312.             }
  1313.         }
  1314.        
  1315.         return $initial;
  1316.     }
  1317.    function url($url = null)
  1318.    {
  1319.            $base = strip_plugin($this->controller->base, $this->controller->plugin);
  1320.            
  1321.            if (empty($url))
  1322.            {
  1323.                    return $this->controller->here;
  1324.            }
  1325.            elseif ($url{0} == '/')
  1326.            {
  1327.                    $output = $base . $url;
  1328.            }
  1329.            else
  1330.            {
  1331.                    $output = $base.'/'.strtolower($this->controller->params['controller']).'/'.$url;
  1332.            }
  1333.            return preg_replace('/&([^a])/', '&\1', $output);
  1334.    }
  1335.    
  1336. }
  1337.  
Parsed in 1.997 seconds, using GeSHi 1.0.7.14

Modify this Paste