Dotclear


Ignore:
Timestamp:
03/08/18 17:58:39 (8 years ago)
Author:
franck <carnet.franck.paul@…>
Branch:
default
Message:

Code formatting (PSR-2)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • inc/core/class.dc.auth.php

    r3627 r3730  
    1010# 
    1111# -- END LICENSE BLOCK ----------------------------------------- 
    12 if (!defined('DC_RC_PATH')) { return; } 
     12if (!defined('DC_RC_PATH')) {return;} 
    1313 
    1414/** 
    15 * @ingroup DC_CORE 
    16 * @nosubgrouping 
    17 * @brief Authentication and user credentials management 
    18 * 
    19 * dcAuth is a class used to handle everything related to user authentication 
    20 * and credentials. Object is provided by dcCore $auth property. 
    21 */ 
     15 * @ingroup DC_CORE 
     16 * @nosubgrouping 
     17 * @brief Authentication and user credentials management 
     18 * 
     19 * dcAuth is a class used to handle everything related to user authentication 
     20 * and credentials. Object is provided by dcCore $auth property. 
     21 */ 
    2222class dcAuth 
    2323{ 
    24      /** @var dcCore dcCore instance */ 
    25      protected $core; 
    26      /** @var connection Database connection object */ 
    27      protected $con; 
    28  
    29      /** @var string User table name */ 
    30      protected $user_table; 
    31      /** @var string Perm table name */ 
    32      protected $perm_table; 
    33  
    34      /** @var string Current user ID */ 
    35      protected $user_id; 
    36      /** @var array Array with user information */ 
    37      protected $user_info = array(); 
    38      /** @var array Array with user options */ 
    39      protected $user_options = array(); 
    40      /** @var boolean User must change his password after login */ 
    41      protected $user_change_pwd; 
    42      /** @var boolean User is super admin */ 
    43      protected $user_admin; 
    44      /** @var array Permissions for each blog */ 
    45      protected $permissions = array(); 
    46      /** @var boolean User can change its password */ 
    47      protected $allow_pass_change = true; 
    48      /** @var array List of blogs on which the user has permissions */ 
    49      protected $blogs = array(); 
    50      /** @var integer Count of user blogs */ 
    51      public $blog_count = null; 
    52  
    53      /** @var array Permission types */ 
    54      protected $perm_types; 
    55  
    56      /** @var dcPrefs dcPrefs object */ 
    57      public $user_prefs; 
    58  
    59      /** 
    60      * Class constructor. Takes dcCore object as single argument. 
    61      * 
    62      * @param dcCore     $core          dcCore object 
    63      */ 
    64      public function __construct($core) 
    65      { 
    66           $this->core =& $core; 
    67           $this->con =& $core->con; 
    68           $this->blog_table = $core->prefix.'blog'; 
    69           $this->user_table = $core->prefix.'user'; 
    70           $this->perm_table = $core->prefix.'permissions'; 
    71  
    72           $this->perm_types = array( 
    73                'admin' => __('administrator'), 
    74                'usage' => __('manage their own entries and comments'), 
    75                'publish' => __('publish entries and comments'), 
    76                'delete' => __('delete entries and comments'), 
    77                'contentadmin' => __('manage all entries and comments'), 
    78                'categories' => __('manage categories'), 
    79                'media' => __('manage their own media items'), 
    80                'media_admin' => __('manage all media items') 
    81           ); 
    82      } 
    83  
    84      /// @name Credentials and user permissions 
    85      //@{ 
    86      /** 
    87      * Checks if user exists and can log in. <var>$pwd</var> argument is optionnal 
    88      * while you may need to check user without password. This method will create 
    89      * credentials and populate all needed object properties. 
    90      * 
    91      * @param string     $user_id       User ID 
    92      * @param string     $pwd           User password 
    93      * @param string     $user_key      User key check 
    94      * @param boolean    $check_blog    checks if user is associated to a blog or not. 
    95      * @return boolean 
    96      */ 
    97      public function checkUser($user_id, $pwd=null, $user_key=null, $check_blog=true) 
    98      { 
    99           # Check user and password 
    100           $strReq = 'SELECT user_id, user_super, user_pwd, user_change_pwd, '. 
    101                     'user_name, user_firstname, user_displayname, user_email, '. 
    102                     'user_url, user_default_blog, user_options, '. 
    103                     'user_lang, user_tz, user_post_status, user_creadt, user_upddt '. 
    104                     'FROM '.$this->con->escapeSystem($this->user_table).' '. 
    105                     "WHERE user_id = '".$this->con->escape($user_id)."' "; 
    106  
    107           try { 
    108                $rs = $this->con->select($strReq); 
    109           } catch (Exception $e) { 
    110                $err = $e->getMessage(); 
    111                return false; 
    112           } 
    113  
    114           if ($rs->isEmpty()) { 
    115                sleep(rand(2,5)); 
    116                return false; 
    117           } 
    118  
    119           $rs->extend('rsExtUser'); 
    120  
    121           if ($pwd != '') 
    122           { 
    123                $rehash = false; 
    124                if (password_verify($pwd,$rs->user_pwd)) { 
    125                     // User password ok 
    126                     if (password_needs_rehash($rs->user_pwd,PASSWORD_DEFAULT)) { 
    127                          $rs->user_pwd = $this->crypt($pwd); 
    128                          $rehash = true; 
    129                     } 
    130                } else { 
    131                     // Check if pwd still stored in old fashion way 
    132                     $ret = password_get_info($rs->user_pwd); 
    133                     if (is_array($ret) && isset($ret['algo']) && $ret['algo'] == 0) { 
    134                          // hash not done with password_hash() function, check by old fashion way 
    135                          if (crypt::hmac(DC_MASTER_KEY,$pwd,DC_CRYPT_ALGO) == $rs->user_pwd) { 
    136                               // Password Ok, need to store it in new fashion way 
    137                               $rs->user_pwd = $this->crypt($pwd); 
    138                               $rehash = true; 
    139                          } else { 
    140                               // Password KO 
    141                               sleep(rand(2,5)); 
    142                               return false; 
    143                          } 
    144                     } else { 
    145                          // Password KO 
    146                          sleep(rand(2,5)); 
    147                          return false; 
    148                     } 
    149                } 
    150                if ($rehash) { 
    151                     // Store new hash in DB 
    152                     $cur = $this->con->openCursor($this->user_table); 
    153                     $cur->user_pwd = (string) $rs->user_pwd; 
    154                     $cur->update("WHERE user_id = '".$rs->user_id."'"); 
    155                } 
    156           } 
    157           elseif ($user_key != '') 
    158           { 
    159                if (http::browserUID(DC_MASTER_KEY.$rs->user_id.$this->cryptLegacy($rs->user_id)) != $user_key) { 
    160                     return false; 
    161                } 
    162           } 
    163  
    164           $this->user_id = $rs->user_id; 
    165           $this->user_change_pwd = (boolean) $rs->user_change_pwd; 
    166           $this->user_admin = (boolean) $rs->user_super; 
    167  
    168           $this->user_info['user_pwd'] = $rs->user_pwd; 
    169           $this->user_info['user_name'] = $rs->user_name; 
    170           $this->user_info['user_firstname'] = $rs->user_firstname; 
    171           $this->user_info['user_displayname'] = $rs->user_displayname; 
    172           $this->user_info['user_email'] = $rs->user_email; 
    173           $this->user_info['user_url'] = $rs->user_url; 
    174           $this->user_info['user_default_blog'] = $rs->user_default_blog; 
    175           $this->user_info['user_lang'] = $rs->user_lang; 
    176           $this->user_info['user_tz'] = $rs->user_tz; 
    177           $this->user_info['user_post_status'] = $rs->user_post_status; 
    178           $this->user_info['user_creadt'] = $rs->user_creadt; 
    179           $this->user_info['user_upddt'] = $rs->user_upddt; 
    180  
    181           $this->user_info['user_cn'] = dcUtils::getUserCN($rs->user_id, $rs->user_name, 
    182           $rs->user_firstname, $rs->user_displayname); 
    183  
    184           $this->user_options = array_merge($this->core->userDefaults(),$rs->options()); 
    185  
    186           $this->user_prefs = new dcPrefs($this->core,$this->user_id); 
    187  
    188           # Get permissions on blogs 
    189           if ($check_blog && ($this->findUserBlog() === false)) { 
    190                return false; 
    191           } 
    192           return true; 
    193      } 
    194  
    195      /** 
    196       * This method crypt given string (password, session_id, …). 
    197       * 
    198       * @param string $pwd string to be crypted 
    199       * @return string crypted value 
    200       */ 
    201      public function crypt($pwd) 
    202      { 
    203           return password_hash($pwd,PASSWORD_DEFAULT); 
    204      } 
    205  
    206      /** 
    207       * This method crypt given string (password, session_id, …). 
    208       * 
    209       * @param string $pwd string to be crypted 
    210       * @return string crypted value 
    211       */ 
    212      public function cryptLegacy($pwd) 
    213      { 
    214           return crypt::hmac(DC_MASTER_KEY,$pwd,DC_CRYPT_ALGO); 
    215      } 
    216  
    217      /** 
    218      * This method only check current user password. 
    219      * 
    220      * @param string     $pwd           User password 
    221      * @return boolean 
    222      */ 
    223      public function checkPassword($pwd) 
    224      { 
    225           if (!empty($this->user_info['user_pwd'])) { 
    226                return password_verify($pwd,$this->user_info['user_pwd']); 
    227           } 
    228  
    229           return false; 
    230      } 
    231  
    232      /** 
    233      * This method checks if user session cookie exists 
    234      * 
    235      * @return boolean 
    236      */ 
    237      public function sessionExists() 
    238      { 
    239           return isset($_COOKIE[DC_SESSION_NAME]); 
    240      } 
    241  
    242      /** 
    243      * This method checks user session validity. 
    244      * 
    245      * @return boolean 
    246      */ 
    247      public function checkSession($uid=null) 
    248      { 
    249           $this->core->session->start(); 
    250  
    251           # If session does not exist, logout. 
    252           if (!isset($_SESSION['sess_user_id'])) { 
    253                $this->core->session->destroy(); 
    254                return false; 
    255           } 
    256  
    257           # Check here for user and IP address 
    258           $this->checkUser($_SESSION['sess_user_id']); 
    259           $uid = $uid ?: http::browserUID(DC_MASTER_KEY); 
    260  
    261           $user_can_log = $this->userID() !== null && $uid == $_SESSION['sess_browser_uid']; 
    262  
    263           if (!$user_can_log) { 
    264                $this->core->session->destroy(); 
    265                return false; 
    266           } 
    267  
    268           return true; 
    269      } 
    270  
    271      /** 
    272      * Checks if user must change his password in order to login. 
    273      * 
    274      * @return boolean 
    275      */ 
    276      public function mustChangePassword() 
    277      { 
    278           return $this->user_change_pwd; 
    279      } 
    280  
    281      /** 
    282      * Checks if user is super admin 
    283      * 
    284      * @return boolean 
    285      */ 
    286      public function isSuperAdmin() 
    287      { 
    288           return $this->user_admin; 
    289      } 
    290  
    291      /** 
    292      * Checks if user has permissions given in <var>$permissions</var> for blog 
    293      * <var>$blog_id</var>. <var>$permissions</var> is a coma separated list of 
    294      * permissions. 
    295      * 
    296      * @param string     $permissions   Permissions list 
    297      * @param string     $blog_id       Blog ID 
    298      * @return boolean 
    299      */ 
    300      public function check($permissions,$blog_id) 
    301      { 
    302           if ($this->user_admin) { 
    303                return true; 
    304           } 
    305  
    306           $p = array_map('trim',explode(',',$permissions)); 
    307           $b = $this->getPermissions($blog_id); 
    308  
    309           if ($b != false) 
    310           { 
    311                if (isset($b['admin'])) { 
    312                     return true; 
    313                } 
    314  
    315                foreach ($p as $v) 
    316                { 
    317                     if (isset($b[$v])) { 
    318                          return true; 
    319                     } 
    320                } 
    321           } 
    322  
    323           return false; 
    324      } 
    325  
    326      /** 
    327      * Returns true if user is allowed to change its password. 
    328      * 
    329      * @return boolean 
    330      */ 
    331      public function allowPassChange() 
    332      { 
    333           return $this->allow_pass_change; 
    334      } 
    335      //@} 
    336  
    337      /// @name User code handlers 
    338      //@{ 
    339      public function getUserCode() 
    340      { 
    341           $code = 
    342           pack('a32',$this->userID()). 
    343           pack('H*',$this->crypt($this->getInfo('user_pwd'))); 
    344           return bin2hex($code); 
    345      } 
    346  
    347      public function checkUserCode($code) 
    348      { 
    349           $code = @pack('H*',$code); 
    350  
    351           $user_id = trim(@pack('a32',substr($code,0,32))); 
    352           $pwd = @unpack('H*hex',substr($code,32)); 
    353  
    354           if ($user_id === false || $pwd === false) { 
    355                return false; 
    356           } 
    357  
    358           $pwd = $pwd['hex']; 
    359  
    360           $strReq = 'SELECT user_id, user_pwd '. 
    361                     'FROM '.$this->user_table.' '. 
    362                     "WHERE user_id = '".$this->con->escape($user_id)."' "; 
    363  
    364           $rs = $this->con->select($strReq); 
    365  
    366           if ($rs->isEmpty()) { 
    367                return false; 
    368           } 
    369  
    370           if ($this->crypt($rs->user_pwd) != $pwd) { 
    371                return false; 
    372           } 
    373  
    374           return $rs->user_id; 
    375      } 
    376      //@} 
    377  
    378  
    379      /// @name Sudo 
    380      //@{ 
    381      /** 
    382      * Calls $f function with super admin rights. 
    383      * Returns the function result. 
    384      * 
    385      * @param callback   $f             Callback function 
    386      * @return mixed 
    387      */ 
    388      public function sudo($f) 
    389      { 
    390           if (!is_callable($f)) { 
    391                throw new Exception($f.' function doest not exist'); 
    392           } 
    393  
    394           $args = func_get_args(); 
    395           array_shift($args); 
    396  
    397           if ($this->user_admin) { 
    398                $res = call_user_func_array($f,$args); 
    399           } else { 
    400                $this->user_admin = true; 
    401                try { 
    402                     $res = call_user_func_array($f,$args); 
    403                     $this->user_admin = false; 
    404                } catch (Exception $e) { 
    405                     $this->user_admin = false; 
    406                     throw $e; 
    407                } 
    408           } 
    409  
    410           return $res; 
    411      } 
    412      //@} 
    413  
    414      /// @name User information and options 
    415      //@{ 
    416      /** 
    417      * Returns user permissions for a blog as an array which looks like: 
    418      * 
    419      *  - [blog_id] 
    420      *    - [permission] => true 
    421      *    - ... 
    422      * 
    423      * @param string     $blog_id       Blog ID 
    424      * @return array 
    425      */ 
    426      public function getPermissions($blog_id) 
    427      { 
    428           if (isset($this->blogs[$blog_id])) { 
    429                return $this->blogs[$blog_id]; 
    430           } 
    431  
    432           if ($this->user_admin) { 
    433                $strReq = 'SELECT blog_id '. 
    434                     'from '.$this->blog_table.' '. 
    435                     "WHERE blog_id = '".$this->con->escape($blog_id)."' "; 
    436                $rs = $this->con->select($strReq); 
    437  
    438                $this->blogs[$blog_id] = $rs->isEmpty() ? false : array('admin' => true); 
    439  
    440                return $this->blogs[$blog_id]; 
    441           } 
    442  
    443           $strReq = 'SELECT permissions '. 
    444                     'FROM '.$this->perm_table.' '. 
    445                     "WHERE user_id = '".$this->con->escape($this->user_id)."' ". 
    446                     "AND blog_id = '".$this->con->escape($blog_id)."' ". 
    447                     "AND (permissions LIKE '%|usage|%' OR permissions LIKE '%|admin|%' OR permissions LIKE '%|contentadmin|%') "; 
    448           $rs = $this->con->select($strReq); 
    449  
    450           $this->blogs[$blog_id] = $rs->isEmpty() ? false : $this->parsePermissions($rs->permissions); 
    451  
    452           return $this->blogs[$blog_id]; 
    453      } 
    454  
    455     public function getBlogCount() { 
    456           if ($this->blog_count === null) { 
    457                $this->blog_count = $this->core->getBlogs(array(),true)->f(0); 
    458           } 
     24    /** @var dcCore dcCore instance */ 
     25    protected $core; 
     26    /** @var connection Database connection object */ 
     27    protected $con; 
     28 
     29    /** @var string User table name */ 
     30    protected $user_table; 
     31    /** @var string Perm table name */ 
     32    protected $perm_table; 
     33 
     34    /** @var string Current user ID */ 
     35    protected $user_id; 
     36    /** @var array Array with user information */ 
     37    protected $user_info = array(); 
     38    /** @var array Array with user options */ 
     39    protected $user_options = array(); 
     40    /** @var boolean User must change his password after login */ 
     41    protected $user_change_pwd; 
     42    /** @var boolean User is super admin */ 
     43    protected $user_admin; 
     44    /** @var array Permissions for each blog */ 
     45    protected $permissions = array(); 
     46    /** @var boolean User can change its password */ 
     47    protected $allow_pass_change = true; 
     48    /** @var array List of blogs on which the user has permissions */ 
     49    protected $blogs = array(); 
     50    /** @var integer Count of user blogs */ 
     51    public $blog_count = null; 
     52 
     53    /** @var array Permission types */ 
     54    protected $perm_types; 
     55 
     56    /** @var dcPrefs dcPrefs object */ 
     57    public $user_prefs; 
     58 
     59    /** 
     60     * Class constructor. Takes dcCore object as single argument. 
     61     * 
     62     * @param dcCore    $core        dcCore object 
     63     */ 
     64    public function __construct($core) 
     65    { 
     66        $this->core       = &$core; 
     67        $this->con        = &$core->con; 
     68        $this->blog_table = $core->prefix . 'blog'; 
     69        $this->user_table = $core->prefix . 'user'; 
     70        $this->perm_table = $core->prefix . 'permissions'; 
     71 
     72        $this->perm_types = array( 
     73            'admin'        => __('administrator'), 
     74            'usage'        => __('manage their own entries and comments'), 
     75            'publish'      => __('publish entries and comments'), 
     76            'delete'       => __('delete entries and comments'), 
     77            'contentadmin' => __('manage all entries and comments'), 
     78            'categories'   => __('manage categories'), 
     79            'media'        => __('manage their own media items'), 
     80            'media_admin'  => __('manage all media items') 
     81        ); 
     82    } 
     83 
     84    /// @name Credentials and user permissions 
     85    //@{ 
     86    /** 
     87     * Checks if user exists and can log in. <var>$pwd</var> argument is optionnal 
     88     * while you may need to check user without password. This method will create 
     89     * credentials and populate all needed object properties. 
     90     * 
     91     * @param string    $user_id        User ID 
     92     * @param string    $pwd            User password 
     93     * @param string    $user_key        User key check 
     94     * @param boolean    $check_blog    checks if user is associated to a blog or not. 
     95     * @return boolean 
     96     */ 
     97    public function checkUser($user_id, $pwd = null, $user_key = null, $check_blog = true) 
     98    { 
     99        # Check user and password 
     100        $strReq = 'SELECT user_id, user_super, user_pwd, user_change_pwd, ' . 
     101        'user_name, user_firstname, user_displayname, user_email, ' . 
     102        'user_url, user_default_blog, user_options, ' . 
     103        'user_lang, user_tz, user_post_status, user_creadt, user_upddt ' . 
     104        'FROM ' . $this->con->escapeSystem($this->user_table) . ' ' . 
     105        "WHERE user_id = '" . $this->con->escape($user_id) . "' "; 
     106 
     107        try { 
     108            $rs = $this->con->select($strReq); 
     109        } catch (Exception $e) { 
     110            $err = $e->getMessage(); 
     111            return false; 
     112        } 
     113 
     114        if ($rs->isEmpty()) { 
     115            sleep(rand(2, 5)); 
     116            return false; 
     117        } 
     118 
     119        $rs->extend('rsExtUser'); 
     120 
     121        if ($pwd != '') { 
     122            $rehash = false; 
     123            if (password_verify($pwd, $rs->user_pwd)) { 
     124                // User password ok 
     125                if (password_needs_rehash($rs->user_pwd, PASSWORD_DEFAULT)) { 
     126                    $rs->user_pwd = $this->crypt($pwd); 
     127                    $rehash       = true; 
     128                } 
     129            } else { 
     130                // Check if pwd still stored in old fashion way 
     131                $ret = password_get_info($rs->user_pwd); 
     132                if (is_array($ret) && isset($ret['algo']) && $ret['algo'] == 0) { 
     133                    // hash not done with password_hash() function, check by old fashion way 
     134                    if (crypt::hmac(DC_MASTER_KEY, $pwd, DC_CRYPT_ALGO) == $rs->user_pwd) { 
     135                        // Password Ok, need to store it in new fashion way 
     136                        $rs->user_pwd = $this->crypt($pwd); 
     137                        $rehash       = true; 
     138                    } else { 
     139                        // Password KO 
     140                        sleep(rand(2, 5)); 
     141                        return false; 
     142                    } 
     143                } else { 
     144                    // Password KO 
     145                    sleep(rand(2, 5)); 
     146                    return false; 
     147                } 
     148            } 
     149            if ($rehash) { 
     150                // Store new hash in DB 
     151                $cur           = $this->con->openCursor($this->user_table); 
     152                $cur->user_pwd = (string) $rs->user_pwd; 
     153                $cur->update("WHERE user_id = '" . $rs->user_id . "'"); 
     154            } 
     155        } elseif ($user_key != '') { 
     156            if (http::browserUID(DC_MASTER_KEY . $rs->user_id . $this->cryptLegacy($rs->user_id)) != $user_key) { 
     157                return false; 
     158            } 
     159        } 
     160 
     161        $this->user_id         = $rs->user_id; 
     162        $this->user_change_pwd = (boolean) $rs->user_change_pwd; 
     163        $this->user_admin      = (boolean) $rs->user_super; 
     164 
     165        $this->user_info['user_pwd']          = $rs->user_pwd; 
     166        $this->user_info['user_name']         = $rs->user_name; 
     167        $this->user_info['user_firstname']    = $rs->user_firstname; 
     168        $this->user_info['user_displayname']  = $rs->user_displayname; 
     169        $this->user_info['user_email']        = $rs->user_email; 
     170        $this->user_info['user_url']          = $rs->user_url; 
     171        $this->user_info['user_default_blog'] = $rs->user_default_blog; 
     172        $this->user_info['user_lang']         = $rs->user_lang; 
     173        $this->user_info['user_tz']           = $rs->user_tz; 
     174        $this->user_info['user_post_status']  = $rs->user_post_status; 
     175        $this->user_info['user_creadt']       = $rs->user_creadt; 
     176        $this->user_info['user_upddt']        = $rs->user_upddt; 
     177 
     178        $this->user_info['user_cn'] = dcUtils::getUserCN($rs->user_id, $rs->user_name, 
     179            $rs->user_firstname, $rs->user_displayname); 
     180 
     181        $this->user_options = array_merge($this->core->userDefaults(), $rs->options()); 
     182 
     183        $this->user_prefs = new dcPrefs($this->core, $this->user_id); 
     184 
     185        # Get permissions on blogs 
     186        if ($check_blog && ($this->findUserBlog() === false)) { 
     187            return false; 
     188        } 
     189        return true; 
     190    } 
     191 
     192    /** 
     193     * This method crypt given string (password, session_id, …). 
     194     * 
     195     * @param string $pwd string to be crypted 
     196     * @return string crypted value 
     197     */ 
     198    public function crypt($pwd) 
     199    { 
     200        return password_hash($pwd, PASSWORD_DEFAULT); 
     201    } 
     202 
     203    /** 
     204     * This method crypt given string (password, session_id, …). 
     205     * 
     206     * @param string $pwd string to be crypted 
     207     * @return string crypted value 
     208     */ 
     209    public function cryptLegacy($pwd) 
     210    { 
     211        return crypt::hmac(DC_MASTER_KEY, $pwd, DC_CRYPT_ALGO); 
     212    } 
     213 
     214    /** 
     215     * This method only check current user password. 
     216     * 
     217     * @param string    $pwd            User password 
     218     * @return boolean 
     219     */ 
     220    public function checkPassword($pwd) 
     221    { 
     222        if (!empty($this->user_info['user_pwd'])) { 
     223            return password_verify($pwd, $this->user_info['user_pwd']); 
     224        } 
     225 
     226        return false; 
     227    } 
     228 
     229    /** 
     230     * This method checks if user session cookie exists 
     231     * 
     232     * @return boolean 
     233     */ 
     234    public function sessionExists() 
     235    { 
     236        return isset($_COOKIE[DC_SESSION_NAME]); 
     237    } 
     238 
     239    /** 
     240     * This method checks user session validity. 
     241     * 
     242     * @return boolean 
     243     */ 
     244    public function checkSession($uid = null) 
     245    { 
     246        $this->core->session->start(); 
     247 
     248        # If session does not exist, logout. 
     249        if (!isset($_SESSION['sess_user_id'])) { 
     250            $this->core->session->destroy(); 
     251            return false; 
     252        } 
     253 
     254        # Check here for user and IP address 
     255        $this->checkUser($_SESSION['sess_user_id']); 
     256        $uid = $uid ?: http::browserUID(DC_MASTER_KEY); 
     257 
     258        $user_can_log = $this->userID() !== null && $uid == $_SESSION['sess_browser_uid']; 
     259 
     260        if (!$user_can_log) { 
     261            $this->core->session->destroy(); 
     262            return false; 
     263        } 
     264 
     265        return true; 
     266    } 
     267 
     268    /** 
     269     * Checks if user must change his password in order to login. 
     270     * 
     271     * @return boolean 
     272     */ 
     273    public function mustChangePassword() 
     274    { 
     275        return $this->user_change_pwd; 
     276    } 
     277 
     278    /** 
     279     * Checks if user is super admin 
     280     * 
     281     * @return boolean 
     282     */ 
     283    public function isSuperAdmin() 
     284    { 
     285        return $this->user_admin; 
     286    } 
     287 
     288    /** 
     289     * Checks if user has permissions given in <var>$permissions</var> for blog 
     290     * <var>$blog_id</var>. <var>$permissions</var> is a coma separated list of 
     291     * permissions. 
     292     * 
     293     * @param string    $permissions    Permissions list 
     294     * @param string    $blog_id        Blog ID 
     295     * @return boolean 
     296     */ 
     297    public function check($permissions, $blog_id) 
     298    { 
     299        if ($this->user_admin) { 
     300            return true; 
     301        } 
     302 
     303        $p = array_map('trim', explode(',', $permissions)); 
     304        $b = $this->getPermissions($blog_id); 
     305 
     306        if ($b != false) { 
     307            if (isset($b['admin'])) { 
     308                return true; 
     309            } 
     310 
     311            foreach ($p as $v) { 
     312                if (isset($b[$v])) { 
     313                    return true; 
     314                } 
     315            } 
     316        } 
     317 
     318        return false; 
     319    } 
     320 
     321    /** 
     322     * Returns true if user is allowed to change its password. 
     323     * 
     324     * @return    boolean 
     325     */ 
     326    public function allowPassChange() 
     327    { 
     328        return $this->allow_pass_change; 
     329    } 
     330    //@} 
     331 
     332    /// @name User code handlers 
     333    //@{ 
     334    public function getUserCode() 
     335    { 
     336        $code = 
     337        pack('a32', $this->userID()) . 
     338        pack('H*', $this->crypt($this->getInfo('user_pwd'))); 
     339        return bin2hex($code); 
     340    } 
     341 
     342    public function checkUserCode($code) 
     343    { 
     344        $code = @pack('H*', $code); 
     345 
     346        $user_id = trim(@pack('a32', substr($code, 0, 32))); 
     347        $pwd     = @unpack('H*hex', substr($code, 32)); 
     348 
     349        if ($user_id === false || $pwd === false) { 
     350            return false; 
     351        } 
     352 
     353        $pwd = $pwd['hex']; 
     354 
     355        $strReq = 'SELECT user_id, user_pwd ' . 
     356        'FROM ' . $this->user_table . ' ' . 
     357        "WHERE user_id = '" . $this->con->escape($user_id) . "' "; 
     358 
     359        $rs = $this->con->select($strReq); 
     360 
     361        if ($rs->isEmpty()) { 
     362            return false; 
     363        } 
     364 
     365        if ($this->crypt($rs->user_pwd) != $pwd) { 
     366            return false; 
     367        } 
     368 
     369        return $rs->user_id; 
     370    } 
     371    //@} 
     372 
     373    /// @name Sudo 
     374    //@{ 
     375    /** 
     376     * Calls $f function with super admin rights. 
     377     * Returns the function result. 
     378     * 
     379     * @param callback    $f            Callback function 
     380     * @return mixed 
     381     */ 
     382    public function sudo($f) 
     383    { 
     384        if (!is_callable($f)) { 
     385            throw new Exception($f . ' function doest not exist'); 
     386        } 
     387 
     388        $args = func_get_args(); 
     389        array_shift($args); 
     390 
     391        if ($this->user_admin) { 
     392            $res = call_user_func_array($f, $args); 
     393        } else { 
     394            $this->user_admin = true; 
     395            try { 
     396                $res              = call_user_func_array($f, $args); 
     397                $this->user_admin = false; 
     398            } catch (Exception $e) { 
     399                $this->user_admin = false; 
     400                throw $e; 
     401            } 
     402        } 
     403 
     404        return $res; 
     405    } 
     406    //@} 
     407 
     408    /// @name User information and options 
     409    //@{ 
     410    /** 
     411     * Returns user permissions for a blog as an array which looks like: 
     412     * 
     413     *  - [blog_id] 
     414     *    - [permission] => true 
     415     *    - ... 
     416     * 
     417     * @param string    $blog_id        Blog ID 
     418     * @return array 
     419     */ 
     420    public function getPermissions($blog_id) 
     421    { 
     422        if (isset($this->blogs[$blog_id])) { 
     423            return $this->blogs[$blog_id]; 
     424        } 
     425 
     426        if ($this->user_admin) { 
     427            $strReq = 'SELECT blog_id ' . 
     428            'from ' . $this->blog_table . ' ' . 
     429            "WHERE blog_id = '" . $this->con->escape($blog_id) . "' "; 
     430            $rs = $this->con->select($strReq); 
     431 
     432            $this->blogs[$blog_id] = $rs->isEmpty() ? false : array('admin' => true); 
     433 
     434            return $this->blogs[$blog_id]; 
     435        } 
     436 
     437        $strReq = 'SELECT permissions ' . 
     438        'FROM ' . $this->perm_table . ' ' . 
     439        "WHERE user_id = '" . $this->con->escape($this->user_id) . "' " . 
     440        "AND blog_id = '" . $this->con->escape($blog_id) . "' " . 
     441            "AND (permissions LIKE '%|usage|%' OR permissions LIKE '%|admin|%' OR permissions LIKE '%|contentadmin|%') "; 
     442        $rs = $this->con->select($strReq); 
     443 
     444        $this->blogs[$blog_id] = $rs->isEmpty() ? false : $this->parsePermissions($rs->permissions); 
     445 
     446        return $this->blogs[$blog_id]; 
     447    } 
     448 
     449    public function getBlogCount() 
     450    { 
     451        if ($this->blog_count === null) { 
     452            $this->blog_count = $this->core->getBlogs(array(), true)->f(0); 
     453        } 
    459454 
    460455        return $this->blog_count; 
    461456    } 
    462457 
    463      public function findUserBlog($blog_id=null) 
    464      { 
    465           if ($blog_id && $this->getPermissions($blog_id) !== false) 
    466           { 
    467                return $blog_id; 
    468           } 
    469           else 
    470           { 
    471                if ($this->user_admin) 
    472                { 
    473                     $strReq = 'SELECT blog_id '. 
    474                               'FROM '.$this->blog_table.' '. 
    475                               'ORDER BY blog_id ASC '. 
    476                               $this->con->limit(1); 
    477                } 
    478                else 
    479                { 
    480                     $strReq = 'SELECT P.blog_id '. 
    481                               'FROM '.$this->perm_table.' P, '.$this->blog_table.' B '. 
    482                               "WHERE user_id = '".$this->con->escape($this->user_id)."' ". 
    483                               "AND P.blog_id = B.blog_id ". 
    484                               "AND (permissions LIKE '%|usage|%' OR permissions LIKE '%|admin|%' OR permissions LIKE '%|contentadmin|%') ". 
    485                               "AND blog_status >= 0 ". 
    486                               'ORDER BY P.blog_id ASC '. 
    487                               $this->con->limit(1); 
    488                } 
    489  
    490                $rs = $this->con->select($strReq); 
    491                if (!$rs->isEmpty()) { 
    492                     return $rs->blog_id; 
    493                } 
    494           } 
    495  
    496           return false; 
    497      } 
    498  
    499      /** 
    500      * Returns current user ID 
    501      * 
    502      * @return string 
    503      */ 
    504      public function userID() 
    505      { 
    506           return $this->user_id; 
    507      } 
    508  
    509      /** 
    510      * Returns information about a user . 
    511      * 
    512      * @param string     $n             Information name 
    513      * @return string 
    514      */ 
    515      public function getInfo($n) 
    516      { 
    517           if (isset($this->user_info[$n])) { 
    518                return $this->user_info[$n]; 
    519           } 
    520  
    521           return null; 
    522      } 
    523  
    524      /** 
    525      * Returns a specific user option 
    526      * 
    527      * @param string     $n             Option name 
    528      * @return string 
    529      */ 
    530      public function getOption($n) 
    531      { 
    532           if (isset($this->user_options[$n])) { 
    533                return $this->user_options[$n]; 
    534           } 
    535           return null; 
    536      } 
    537  
    538      /** 
    539      * Returns all user options in an associative array. 
    540      * 
    541      * @return array 
    542      */ 
    543      public function getOptions() 
    544      { 
    545           return $this->user_options; 
    546      } 
    547      //@} 
    548  
    549      /// @name Permissions 
    550      //@{ 
    551      /** 
    552      * Returns an array with permissions parsed from the string <var>$level</var> 
    553      * 
    554      * @param string     $level         Permissions string 
    555      * @return array 
    556      */ 
    557      public function parsePermissions($level) 
    558      { 
    559           $level = preg_replace('/^\|/','',$level); 
    560           $level = preg_replace('/\|$/','',$level); 
    561  
    562           $res = array(); 
    563           foreach (explode('|',$level) as $v) { 
    564                $res[$v] = true; 
    565           } 
    566           return $res; 
    567      } 
    568  
    569      /** 
    570      * Returns <var>perm_types</var> property content. 
    571      * 
    572      * @return array 
    573      */ 
    574      public function getPermissionsTypes() 
    575      { 
    576           return $this->perm_types; 
    577      } 
    578  
    579      /** 
    580      * Adds a new permission type. 
    581      * 
    582      * @param string     $name          Permission name 
    583      * @param string     $title         Permission title 
    584      */ 
    585      public function setPermissionType($name,$title) 
    586      { 
    587           $this->perm_types[$name] = $title; 
    588      } 
    589      //@} 
    590  
    591      /// @name Password recovery 
    592      //@{ 
    593      /** 
    594      * Add a recover key to a specific user identified by its email and 
    595      * password. 
    596      * 
    597      * @param string     $user_id       User ID 
    598      * @param string     $user_email    User Email 
    599      * @return string 
    600      */ 
    601      public function setRecoverKey($user_id,$user_email) 
    602      { 
    603           $strReq = 'SELECT user_id '. 
    604                     'FROM '.$this->user_table.' '. 
    605                     "WHERE user_id = '".$this->con->escape($user_id)."' ". 
    606                     "AND user_email = '".$this->con->escape($user_email)."' "; 
    607  
    608           $rs = $this->con->select($strReq); 
    609  
    610           if ($rs->isEmpty()) { 
    611                throw new Exception(__('That user does not exist in the database.')); 
    612           } 
    613  
    614           $key = md5(uniqid('',true)); 
    615  
    616           $cur = $this->con->openCursor($this->user_table); 
    617           $cur->user_recover_key = $key; 
    618  
    619           $cur->update("WHERE user_id = '".$this->con->escape($user_id)."'"); 
    620  
    621           return $key; 
    622      } 
    623  
    624      /** 
    625      * Creates a new user password using recovery key. Returns an array: 
    626      * 
    627      * - user_email 
    628      * - user_id 
    629      * - new_pass 
    630      * 
    631      * @param string     $recover_key   Recovery key 
    632      * @return array 
    633      */ 
    634      public function recoverUserPassword($recover_key) 
    635      { 
    636           $strReq = 'SELECT user_id, user_email '. 
    637                     'FROM '.$this->user_table.' '. 
    638                     "WHERE user_recover_key = '".$this->con->escape($recover_key)."' "; 
    639  
    640           $rs = $this->con->select($strReq); 
    641  
    642           if ($rs->isEmpty()) { 
    643                throw new Exception(__('That key does not exist in the database.')); 
    644           } 
    645  
    646           $new_pass = crypt::createPassword(); 
    647  
    648           $cur = $this->con->openCursor($this->user_table); 
    649           $cur->user_pwd = $this->crypt($new_pass); 
    650           $cur->user_recover_key = null; 
    651           $cur->user_change_pwd = 1;         // User will have to change this temporary password at next login 
    652  
    653           $cur->update("WHERE user_recover_key = '".$this->con->escape($recover_key)."'"); 
    654  
    655           return array('user_email' => $rs->user_email, 'user_id' => $rs->user_id, 'new_pass' => $new_pass); 
    656      } 
    657      //@} 
    658  
    659      /** @name User management callbacks 
    660      This 3 functions only matter if you extend this class and use 
    661      DC_AUTH_CLASS constant. 
    662      These are called after core user management functions. 
    663      Could be useful if you need to add/update/remove stuff in your 
    664      LDAP directory or other third party authentication database. 
    665      */ 
    666      //@{ 
    667  
    668      /** 
    669      * Called after core->addUser 
    670      * @see dcCore::addUser 
    671      * @param cursor     $cur           User cursor 
    672      */ 
    673      public function afterAddUser($cur) {} 
    674  
    675      /** 
    676      * Called after core->updUser 
    677      * @see dcCore::updUser 
    678      * @param string     $id            User ID 
    679      * @param cursor     $cur           User cursor 
    680      */ 
    681      public function afterUpdUser($id,$cur) {} 
    682  
    683      /** 
    684      * Called after core->delUser 
    685      * @see dcCore::delUser 
    686      * @param string     $id            User ID 
    687      */ 
    688      public function afterDelUser($id) {} 
    689      //@} 
     458    public function findUserBlog($blog_id = null) 
     459    { 
     460        if ($blog_id && $this->getPermissions($blog_id) !== false) { 
     461            return $blog_id; 
     462        } else { 
     463            if ($this->user_admin) { 
     464                $strReq = 'SELECT blog_id ' . 
     465                'FROM ' . $this->blog_table . ' ' . 
     466                'ORDER BY blog_id ASC ' . 
     467                $this->con->limit(1); 
     468            } else { 
     469                $strReq = 'SELECT P.blog_id ' . 
     470                'FROM ' . $this->perm_table . ' P, ' . $this->blog_table . ' B ' . 
     471                "WHERE user_id = '" . $this->con->escape($this->user_id) . "' " . 
     472                "AND P.blog_id = B.blog_id " . 
     473                "AND (permissions LIKE '%|usage|%' OR permissions LIKE '%|admin|%' OR permissions LIKE '%|contentadmin|%') " . 
     474                "AND blog_status >= 0 " . 
     475                'ORDER BY P.blog_id ASC ' . 
     476                $this->con->limit(1); 
     477            } 
     478 
     479            $rs = $this->con->select($strReq); 
     480            if (!$rs->isEmpty()) { 
     481                return $rs->blog_id; 
     482            } 
     483        } 
     484 
     485        return false; 
     486    } 
     487 
     488    /** 
     489     * Returns current user ID 
     490     * 
     491     * @return string 
     492     */ 
     493    public function userID() 
     494    { 
     495        return $this->user_id; 
     496    } 
     497 
     498    /** 
     499     * Returns information about a user . 
     500     * 
     501     * @param string    $n            Information name 
     502     * @return string 
     503     */ 
     504    public function getInfo($n) 
     505    { 
     506        if (isset($this->user_info[$n])) { 
     507            return $this->user_info[$n]; 
     508        } 
     509 
     510        return; 
     511    } 
     512 
     513    /** 
     514     * Returns a specific user option 
     515     * 
     516     * @param string    $n            Option name 
     517     * @return string 
     518     */ 
     519    public function getOption($n) 
     520    { 
     521        if (isset($this->user_options[$n])) { 
     522            return $this->user_options[$n]; 
     523        } 
     524        return; 
     525    } 
     526 
     527    /** 
     528     * Returns all user options in an associative array. 
     529     * 
     530     * @return array 
     531     */ 
     532    public function getOptions() 
     533    { 
     534        return $this->user_options; 
     535    } 
     536    //@} 
     537 
     538    /// @name Permissions 
     539    //@{ 
     540    /** 
     541     * Returns an array with permissions parsed from the string <var>$level</var> 
     542     * 
     543     * @param string    $level        Permissions string 
     544     * @return array 
     545     */ 
     546    public function parsePermissions($level) 
     547    { 
     548        $level = preg_replace('/^\|/', '', $level); 
     549        $level = preg_replace('/\|$/', '', $level); 
     550 
     551        $res = array(); 
     552        foreach (explode('|', $level) as $v) { 
     553            $res[$v] = true; 
     554        } 
     555        return $res; 
     556    } 
     557 
     558    /** 
     559     * Returns <var>perm_types</var> property content. 
     560     * 
     561     * @return array 
     562     */ 
     563    public function getPermissionsTypes() 
     564    { 
     565        return $this->perm_types; 
     566    } 
     567 
     568    /** 
     569     * Adds a new permission type. 
     570     * 
     571     * @param string    $name        Permission name 
     572     * @param string    $title        Permission title 
     573     */ 
     574    public function setPermissionType($name, $title) 
     575    { 
     576        $this->perm_types[$name] = $title; 
     577    } 
     578    //@} 
     579 
     580    /// @name Password recovery 
     581    //@{ 
     582    /** 
     583     * Add a recover key to a specific user identified by its email and 
     584     * password. 
     585     * 
     586     * @param string    $user_id        User ID 
     587     * @param string    $user_email    User Email 
     588     * @return string 
     589     */ 
     590    public function setRecoverKey($user_id, $user_email) 
     591    { 
     592        $strReq = 'SELECT user_id ' . 
     593        'FROM ' . $this->user_table . ' ' . 
     594        "WHERE user_id = '" . $this->con->escape($user_id) . "' " . 
     595        "AND user_email = '" . $this->con->escape($user_email) . "' "; 
     596 
     597        $rs = $this->con->select($strReq); 
     598 
     599        if ($rs->isEmpty()) { 
     600            throw new Exception(__('That user does not exist in the database.')); 
     601        } 
     602 
     603        $key = md5(uniqid('', true)); 
     604 
     605        $cur                   = $this->con->openCursor($this->user_table); 
     606        $cur->user_recover_key = $key; 
     607 
     608        $cur->update("WHERE user_id = '" . $this->con->escape($user_id) . "'"); 
     609 
     610        return $key; 
     611    } 
     612 
     613    /** 
     614     * Creates a new user password using recovery key. Returns an array: 
     615     * 
     616     * - user_email 
     617     * - user_id 
     618     * - new_pass 
     619     * 
     620     * @param string    $recover_key    Recovery key 
     621     * @return array 
     622     */ 
     623    public function recoverUserPassword($recover_key) 
     624    { 
     625        $strReq = 'SELECT user_id, user_email ' . 
     626        'FROM ' . $this->user_table . ' ' . 
     627        "WHERE user_recover_key = '" . $this->con->escape($recover_key) . "' "; 
     628 
     629        $rs = $this->con->select($strReq); 
     630 
     631        if ($rs->isEmpty()) { 
     632            throw new Exception(__('That key does not exist in the database.')); 
     633        } 
     634 
     635        $new_pass = crypt::createPassword(); 
     636 
     637        $cur                   = $this->con->openCursor($this->user_table); 
     638        $cur->user_pwd         = $this->crypt($new_pass); 
     639        $cur->user_recover_key = null; 
     640        $cur->user_change_pwd  = 1; // User will have to change this temporary password at next login 
     641 
     642        $cur->update("WHERE user_recover_key = '" . $this->con->escape($recover_key) . "'"); 
     643 
     644        return array('user_email' => $rs->user_email, 'user_id' => $rs->user_id, 'new_pass' => $new_pass); 
     645    } 
     646    //@} 
     647 
     648    /** @name User management callbacks 
     649    This 3 functions only matter if you extend this class and use 
     650    DC_AUTH_CLASS constant. 
     651    These are called after core user management functions. 
     652    Could be useful if you need to add/update/remove stuff in your 
     653    LDAP directory    or other third party authentication database. 
     654     */ 
     655    //@{ 
     656 
     657    /** 
     658     * Called after core->addUser 
     659     * @see dcCore::addUser 
     660     * @param cursor    $cur            User cursor 
     661     */ 
     662    public function afterAddUser($cur) 
     663    {} 
     664 
     665    /** 
     666     * Called after core->updUser 
     667     * @see dcCore::updUser 
     668     * @param string    $id            User ID 
     669     * @param cursor    $cur            User cursor 
     670     */ 
     671    public function afterUpdUser($id, $cur) 
     672    {} 
     673 
     674    /** 
     675     * Called after core->delUser 
     676     * @see dcCore::delUser 
     677     * @param string    $id            User ID 
     678     */ 
     679    public function afterDelUser($id) 
     680    {} 
     681    //@} 
    690682} 
Note: See TracChangeset for help on using the changeset viewer.

Sites map