[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/auth/ -> plain.class.php (source)

   1  <?php
   2  /**
   3   * Plaintext authentication backend
   4   *
   5   * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   6   * @author     Andreas Gohr <andi@splitbrain.org>
   7   * @author     Chris Smith <chris@jalakai.co.uk>
   8   */
   9  
  10  define('DOKU_AUTH', dirname(__FILE__));
  11  require_once (DOKU_AUTH.'/basic.class.php');
  12  
  13  define('AUTH_USERFILE',DOKU_CONF.'users.auth.php');
  14  
  15  // we only accept page ids for auth_plain
  16  if(isset($_REQUEST['u']))
  17    $_REQUEST['u'] = cleanID($_REQUEST['u']);
  18  if(isset($_REQUEST['acl_user']))
  19    $_REQUEST['acl_user'] = cleanID($_REQUEST['acl_user']);
  20  // the same goes for password reset requests
  21  if(isset($_POST['login'])){
  22    $_POST['login'] = cleanID($_POST['login']);
  23  }
  24  
  25  class auth_plain extends auth_basic {
  26  
  27      var $users = null;
  28      var $_pattern = array();
  29  
  30      /**
  31       * Constructor
  32       *
  33       * Carry out sanity checks to ensure the object is
  34       * able to operate. Set capabilities.
  35       *
  36       * @author  Christopher Smith <chris@jalakai.co.uk>
  37       */
  38      function auth_plain() {
  39        if (!@is_readable(AUTH_USERFILE)){
  40          $this->success = false;
  41        }else{
  42          if(@is_writable(AUTH_USERFILE)){
  43            $this->cando['addUser']      = true;
  44            $this->cando['delUser']      = true;
  45            $this->cando['modLogin']     = true;
  46            $this->cando['modPass']      = true;
  47            $this->cando['modName']      = true;
  48            $this->cando['modMail']      = true;
  49            $this->cando['modGroups']    = true;
  50          }
  51          $this->cando['getUsers']     = true;
  52          $this->cando['getUserCount'] = true;
  53        }
  54      }
  55  
  56      /**
  57       * Check user+password [required auth function]
  58       *
  59       * Checks if the given user exists and the given
  60       * plaintext password is correct
  61       *
  62       * @author  Andreas Gohr <andi@splitbrain.org>
  63       * @return  bool
  64       */
  65      function checkPass($user,$pass){
  66  
  67        $userinfo = $this->getUserData($user);
  68        if ($userinfo === false) return false;
  69  
  70        return auth_verifyPassword($pass,$this->users[$user]['pass']);
  71      }
  72  
  73      /**
  74       * Return user info
  75       *
  76       * Returns info about the given user needs to contain
  77       * at least these fields:
  78       *
  79       * name string  full name of the user
  80       * mail string  email addres of the user
  81       * grps array   list of groups the user is in
  82       *
  83       * @author  Andreas Gohr <andi@splitbrain.org>
  84       */
  85      function getUserData($user){
  86  
  87        if($this->users === null) $this->_loadUserData();
  88        return isset($this->users[$user]) ? $this->users[$user] : false;
  89      }
  90  
  91      /**
  92       * Create a new User
  93       *
  94       * Returns false if the user already exists, null when an error
  95       * occurred and true if everything went well.
  96       *
  97       * The new user will be added to the default group by this
  98       * function if grps are not specified (default behaviour).
  99       *
 100       * @author  Andreas Gohr <andi@splitbrain.org>
 101       * @author  Chris Smith <chris@jalakai.co.uk>
 102       */
 103      function createUser($user,$pwd,$name,$mail,$grps=null){
 104        global $conf;
 105  
 106        // user mustn't already exist
 107        if ($this->getUserData($user) !== false) return false;
 108  
 109        $pass = auth_cryptPassword($pwd);
 110  
 111        // set default group if no groups specified
 112        if (!is_array($grps)) $grps = array($conf['defaultgroup']);
 113  
 114        // prepare user line
 115        $groups = join(',',$grps);
 116        $userline = join(':',array($user,$pass,$name,$mail,$groups))."\n";
 117  
 118        if (io_saveFile(AUTH_USERFILE,$userline,true)) {
 119          $this->users[$user] = compact('pass','name','mail','grps');
 120          return $pwd;
 121        }
 122  
 123        msg('The '.AUTH_USERFILE.' file is not writable. Please inform the Wiki-Admin',-1);
 124        return null;
 125      }
 126  
 127      /**
 128       * Modify user data
 129       *
 130       * @author  Chris Smith <chris@jalakai.co.uk>
 131       * @param   $user      nick of the user to be changed
 132       * @param   $changes   array of field/value pairs to be changed (password will be clear text)
 133       * @return  bool
 134       */
 135      function modifyUser($user, $changes) {
 136        global $conf;
 137        global $ACT;
 138        global $INFO;
 139  
 140        // sanity checks, user must already exist and there must be something to change
 141        if (($userinfo = $this->getUserData($user)) === false) return false;
 142        if (!is_array($changes) || !count($changes)) return true;
 143  
 144        // update userinfo with new data, remembering to encrypt any password
 145        $newuser = $user;
 146        foreach ($changes as $field => $value) {
 147          if ($field == 'user') {
 148            $newuser = $value;
 149            continue;
 150          }
 151          if ($field == 'pass') $value = auth_cryptPassword($value);
 152          $userinfo[$field] = $value;
 153        }
 154  
 155        $groups = join(',',$userinfo['grps']);
 156        $userline = join(':',array($newuser, $userinfo['pass'], $userinfo['name'], $userinfo['mail'], $groups))."\n";
 157  
 158        if (!$this->deleteUsers(array($user))) {
 159          msg('Unable to modify user data. Please inform the Wiki-Admin',-1);
 160          return false;
 161        }
 162  
 163        if (!io_saveFile(AUTH_USERFILE,$userline,true)) {
 164          msg('There was an error modifying your user data. You should register again.',-1);
 165          // FIXME, user has been deleted but not recreated, should force a logout and redirect to login page
 166          $ACT == 'register';
 167          return false;
 168        }
 169  
 170        $this->users[$newuser] = $userinfo;
 171        return true;
 172      }
 173  
 174      /**
 175       *  Remove one or more users from the list of registered users
 176       *
 177       *  @author  Christopher Smith <chris@jalakai.co.uk>
 178       *  @param   array  $users   array of users to be deleted
 179       *  @return  int             the number of users deleted
 180       */
 181      function deleteUsers($users) {
 182  
 183        if (!is_array($users) || empty($users)) return 0;
 184  
 185        if ($this->users === null) $this->_loadUserData();
 186  
 187        $deleted = array();
 188        foreach ($users as $user) {
 189          if (isset($this->users[$user])) $deleted[] = preg_quote($user,'/');
 190        }
 191  
 192        if (empty($deleted)) return 0;
 193  
 194        $pattern = '/^('.join('|',$deleted).'):/';
 195  
 196        if (io_deleteFromFile(AUTH_USERFILE,$pattern,true)) {
 197          foreach ($deleted as $user) unset($this->users[$user]);
 198          return count($deleted);
 199        }
 200  
 201        // problem deleting, reload the user list and count the difference
 202        $count = count($this->users);
 203        $this->_loadUserData();
 204        $count -= count($this->users);
 205        return $count;
 206      }
 207  
 208      /**
 209       * Return a count of the number of user which meet $filter criteria
 210       *
 211       * @author  Chris Smith <chris@jalakai.co.uk>
 212       */
 213      function getUserCount($filter=array()) {
 214  
 215        if($this->users === null) $this->_loadUserData();
 216  
 217        if (!count($filter)) return count($this->users);
 218  
 219        $count = 0;
 220        $this->_constructPattern($filter);
 221  
 222        foreach ($this->users as $user => $info) {
 223            $count += $this->_filter($user, $info);
 224        }
 225  
 226        return $count;
 227      }
 228  
 229      /**
 230       * Bulk retrieval of user data
 231       *
 232       * @author  Chris Smith <chris@jalakai.co.uk>
 233       * @param   start     index of first user to be returned
 234       * @param   limit     max number of users to be returned
 235       * @param   filter    array of field/pattern pairs
 236       * @return  array of userinfo (refer getUserData for internal userinfo details)
 237       */
 238      function retrieveUsers($start=0,$limit=0,$filter=array()) {
 239  
 240        if ($this->users === null) $this->_loadUserData();
 241  
 242        ksort($this->users);
 243  
 244        $i = 0;
 245        $count = 0;
 246        $out = array();
 247        $this->_constructPattern($filter);
 248  
 249        foreach ($this->users as $user => $info) {
 250          if ($this->_filter($user, $info)) {
 251            if ($i >= $start) {
 252              $out[$user] = $info;
 253              $count++;
 254              if (($limit > 0) && ($count >= $limit)) break;
 255            }
 256            $i++;
 257          }
 258        }
 259  
 260        return $out;
 261      }
 262  
 263      /**
 264       * Load all user data
 265       *
 266       * loads the user file into a datastructure
 267       *
 268       * @author  Andreas Gohr <andi@splitbrain.org>
 269       */
 270      function _loadUserData(){
 271        $this->users = array();
 272  
 273        if(!@file_exists(AUTH_USERFILE)) return;
 274  
 275        $lines = file(AUTH_USERFILE);
 276        foreach($lines as $line){
 277          $line = preg_replace('/#.*$/','',$line); //ignore comments
 278          $line = trim($line);
 279          if(empty($line)) continue;
 280  
 281          $row    = split(":",$line,5);
 282          $groups = split(",",$row[4]);
 283  
 284          $this->users[$row[0]]['pass'] = $row[1];
 285          $this->users[$row[0]]['name'] = urldecode($row[2]);
 286          $this->users[$row[0]]['mail'] = $row[3];
 287          $this->users[$row[0]]['grps'] = $groups;
 288        }
 289      }
 290  
 291      /**
 292       * return 1 if $user + $info match $filter criteria, 0 otherwise
 293       *
 294       * @author   Chris Smith <chris@jalakai.co.uk>
 295       */
 296      function _filter($user, $info) {
 297          // FIXME
 298          foreach ($this->_pattern as $item => $pattern) {
 299              if ($item == 'user') {
 300                  if (!preg_match($pattern, $user)) return 0;
 301              } else if ($item == 'grps') {
 302                  if (!count(preg_grep($pattern, $info['grps']))) return 0;
 303              } else {
 304                  if (!preg_match($pattern, $info[$item])) return 0;
 305              }
 306          }
 307          return 1;
 308      }
 309  
 310      function _constructPattern($filter) {
 311        $this->_pattern = array();
 312        foreach ($filter as $item => $pattern) {
 313  //        $this->_pattern[$item] = '/'.preg_quote($pattern,"/").'/i';          // don't allow regex characters
 314          $this->_pattern[$item] = '/'.str_replace('/','\/',$pattern).'/i';    // allow regex characters
 315        }
 316      }
 317  }
 318  
 319  //Setup VIM: ex: et ts=2 enc=utf-8 :


Generated: Fri Nov 21 01:30:02 2008 Cross-referenced by PHPXref 0.7