| [ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
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 :
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Fri Nov 21 01:30:02 2008 | Cross-referenced by PHPXref 0.7 |