[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 3 namespace dokuwiki\Extension; 4 5 /** 6 * Auth Plugin Prototype 7 * 8 * allows to authenticate users in a plugin 9 * 10 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 11 * @author Chris Smith <chris@jalakai.co.uk> 12 * @author Jan Schumann <js@jschumann-it.com> 13 */ 14 abstract class AuthPlugin extends Plugin 15 { 16 public $success = true; 17 18 /** 19 * Possible things an auth backend module may be able to 20 * do. The things a backend can do need to be set to true 21 * in the constructor. 22 */ 23 protected $cando = array( 24 'addUser' => false, // can Users be created? 25 'delUser' => false, // can Users be deleted? 26 'modLogin' => false, // can login names be changed? 27 'modPass' => false, // can passwords be changed? 28 'modName' => false, // can real names be changed? 29 'modMail' => false, // can emails be changed? 30 'modGroups' => false, // can groups be changed? 31 'getUsers' => false, // can a (filtered) list of users be retrieved? 32 'getUserCount' => false, // can the number of users be retrieved? 33 'getGroups' => false, // can a list of available groups be retrieved? 34 'external' => false, // does the module do external auth checking? 35 'logout' => true, // can the user logout again? (eg. not possible with HTTP auth) 36 ); 37 38 /** 39 * Constructor. 40 * 41 * Carry out sanity checks to ensure the object is 42 * able to operate. Set capabilities in $this->cando 43 * array here 44 * 45 * For future compatibility, sub classes should always include a call 46 * to parent::__constructor() in their constructors! 47 * 48 * Set $this->success to false if checks fail 49 * 50 * @author Christopher Smith <chris@jalakai.co.uk> 51 */ 52 public function __construct() 53 { 54 // the base class constructor does nothing, derived class 55 // constructors do the real work 56 } 57 58 /** 59 * Available Capabilities. [ DO NOT OVERRIDE ] 60 * 61 * For introspection/debugging 62 * 63 * @author Christopher Smith <chris@jalakai.co.uk> 64 * @return array 65 */ 66 public function getCapabilities() 67 { 68 return array_keys($this->cando); 69 } 70 71 /** 72 * Capability check. [ DO NOT OVERRIDE ] 73 * 74 * Checks the capabilities set in the $this->cando array and 75 * some pseudo capabilities (shortcutting access to multiple 76 * ones) 77 * 78 * ususal capabilities start with lowercase letter 79 * shortcut capabilities start with uppercase letter 80 * 81 * @author Andreas Gohr <andi@splitbrain.org> 82 * @param string $cap the capability to check 83 * @return bool 84 */ 85 public function canDo($cap) 86 { 87 switch ($cap) { 88 case 'Profile': 89 // can at least one of the user's properties be changed? 90 return ($this->cando['modPass'] || 91 $this->cando['modName'] || 92 $this->cando['modMail']); 93 break; 94 case 'UserMod': 95 // can at least anything be changed? 96 return ($this->cando['modPass'] || 97 $this->cando['modName'] || 98 $this->cando['modMail'] || 99 $this->cando['modLogin'] || 100 $this->cando['modGroups'] || 101 $this->cando['modMail']); 102 break; 103 default: 104 // print a helping message for developers 105 if (!isset($this->cando[$cap])) { 106 msg("Check for unknown capability '$cap' - Do you use an outdated Plugin?", -1); 107 } 108 return $this->cando[$cap]; 109 } 110 } 111 112 /** 113 * Trigger the AUTH_USERDATA_CHANGE event and call the modification function. [ DO NOT OVERRIDE ] 114 * 115 * You should use this function instead of calling createUser, modifyUser or 116 * deleteUsers directly. The event handlers can prevent the modification, for 117 * example for enforcing a user name schema. 118 * 119 * @author Gabriel Birke <birke@d-scribe.de> 120 * @param string $type Modification type ('create', 'modify', 'delete') 121 * @param array $params Parameters for the createUser, modifyUser or deleteUsers method. 122 * The content of this array depends on the modification type 123 * @return bool|null|int Result from the modification function or false if an event handler has canceled the action 124 */ 125 public function triggerUserMod($type, $params) 126 { 127 $validTypes = array( 128 'create' => 'createUser', 129 'modify' => 'modifyUser', 130 'delete' => 'deleteUsers', 131 ); 132 if (empty($validTypes[$type])) { 133 return false; 134 } 135 136 $result = false; 137 $eventdata = array('type' => $type, 'params' => $params, 'modification_result' => null); 138 $evt = new Event('AUTH_USER_CHANGE', $eventdata); 139 if ($evt->advise_before(true)) { 140 $result = call_user_func_array(array($this, $validTypes[$type]), $evt->data['params']); 141 $evt->data['modification_result'] = $result; 142 } 143 $evt->advise_after(); 144 unset($evt); 145 return $result; 146 } 147 148 /** 149 * Log off the current user [ OPTIONAL ] 150 * 151 * Is run in addition to the ususal logoff method. Should 152 * only be needed when trustExternal is implemented. 153 * 154 * @see auth_logoff() 155 * @author Andreas Gohr <andi@splitbrain.org> 156 */ 157 public function logOff() 158 { 159 } 160 161 /** 162 * Do all authentication [ OPTIONAL ] 163 * 164 * Set $this->cando['external'] = true when implemented 165 * 166 * If this function is implemented it will be used to 167 * authenticate a user - all other DokuWiki internals 168 * will not be used for authenticating (except this 169 * function returns null, in which case, DokuWiki will 170 * still run auth_login as a fallback, which may call 171 * checkPass()). If this function is not returning null, 172 * implementing checkPass() is not needed here anymore. 173 * 174 * The function can be used to authenticate against third 175 * party cookies or Apache auth mechanisms and replaces 176 * the auth_login() function 177 * 178 * The function will be called with or without a set 179 * username. If the Username is given it was called 180 * from the login form and the given credentials might 181 * need to be checked. If no username was given it 182 * the function needs to check if the user is logged in 183 * by other means (cookie, environment). 184 * 185 * The function needs to set some globals needed by 186 * DokuWiki like auth_login() does. 187 * 188 * @see auth_login() 189 * @author Andreas Gohr <andi@splitbrain.org> 190 * 191 * @param string $user Username 192 * @param string $pass Cleartext Password 193 * @param bool $sticky Cookie should not expire 194 * @return bool true on successful auth, 195 * null on unknown result (fallback to checkPass) 196 */ 197 public function trustExternal($user, $pass, $sticky = false) 198 { 199 /* some example: 200 201 global $USERINFO; 202 global $conf; 203 $sticky ? $sticky = true : $sticky = false; //sanity check 204 205 // do the checking here 206 207 // set the globals if authed 208 $USERINFO['name'] = 'FIXME'; 209 $USERINFO['mail'] = 'FIXME'; 210 $USERINFO['grps'] = array('FIXME'); 211 $_SERVER['REMOTE_USER'] = $user; 212 $_SESSION[DOKU_COOKIE]['auth']['user'] = $user; 213 $_SESSION[DOKU_COOKIE]['auth']['pass'] = $pass; 214 $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO; 215 return true; 216 217 */ 218 } 219 220 /** 221 * Check user+password [ MUST BE OVERRIDDEN ] 222 * 223 * Checks if the given user exists and the given 224 * plaintext password is correct 225 * 226 * May be ommited if trustExternal is used. 227 * 228 * @author Andreas Gohr <andi@splitbrain.org> 229 * @param string $user the user name 230 * @param string $pass the clear text password 231 * @return bool 232 */ 233 public function checkPass($user, $pass) 234 { 235 msg("no valid authorisation system in use", -1); 236 return false; 237 } 238 239 /** 240 * Return user info [ MUST BE OVERRIDDEN ] 241 * 242 * Returns info about the given user needs to contain 243 * at least these fields: 244 * 245 * name string full name of the user 246 * mail string email address of the user 247 * grps array list of groups the user is in 248 * 249 * @author Andreas Gohr <andi@splitbrain.org> 250 * @param string $user the user name 251 * @param bool $requireGroups whether or not the returned data must include groups 252 * @return false|array containing user data or false 253 */ 254 public function getUserData($user, $requireGroups = true) 255 { 256 if (!$this->cando['external']) msg("no valid authorisation system in use", -1); 257 return false; 258 } 259 260 /** 261 * Create a new User [implement only where required/possible] 262 * 263 * Returns false if the user already exists, null when an error 264 * occurred and true if everything went well. 265 * 266 * The new user HAS TO be added to the default group by this 267 * function! 268 * 269 * Set addUser capability when implemented 270 * 271 * @author Andreas Gohr <andi@splitbrain.org> 272 * @param string $user 273 * @param string $pass 274 * @param string $name 275 * @param string $mail 276 * @param null|array $grps 277 * @return bool|null 278 */ 279 public function createUser($user, $pass, $name, $mail, $grps = null) 280 { 281 msg("authorisation method does not allow creation of new users", -1); 282 return null; 283 } 284 285 /** 286 * Modify user data [implement only where required/possible] 287 * 288 * Set the mod* capabilities according to the implemented features 289 * 290 * @author Chris Smith <chris@jalakai.co.uk> 291 * @param string $user nick of the user to be changed 292 * @param array $changes array of field/value pairs to be changed (password will be clear text) 293 * @return bool 294 */ 295 public function modifyUser($user, $changes) 296 { 297 msg("authorisation method does not allow modifying of user data", -1); 298 return false; 299 } 300 301 /** 302 * Delete one or more users [implement only where required/possible] 303 * 304 * Set delUser capability when implemented 305 * 306 * @author Chris Smith <chris@jalakai.co.uk> 307 * @param array $users 308 * @return int number of users deleted 309 */ 310 public function deleteUsers($users) 311 { 312 msg("authorisation method does not allow deleting of users", -1); 313 return 0; 314 } 315 316 /** 317 * Return a count of the number of user which meet $filter criteria 318 * [should be implemented whenever retrieveUsers is implemented] 319 * 320 * Set getUserCount capability when implemented 321 * 322 * @author Chris Smith <chris@jalakai.co.uk> 323 * @param array $filter array of field/pattern pairs, empty array for no filter 324 * @return int 325 */ 326 public function getUserCount($filter = array()) 327 { 328 msg("authorisation method does not provide user counts", -1); 329 return 0; 330 } 331 332 /** 333 * Bulk retrieval of user data [implement only where required/possible] 334 * 335 * Set getUsers capability when implemented 336 * 337 * @author Chris Smith <chris@jalakai.co.uk> 338 * @param int $start index of first user to be returned 339 * @param int $limit max number of users to be returned, 0 for unlimited 340 * @param array $filter array of field/pattern pairs, null for no filter 341 * @return array list of userinfo (refer getUserData for internal userinfo details) 342 */ 343 public function retrieveUsers($start = 0, $limit = 0, $filter = null) 344 { 345 msg("authorisation method does not support mass retrieval of user data", -1); 346 return array(); 347 } 348 349 /** 350 * Define a group [implement only where required/possible] 351 * 352 * Set addGroup capability when implemented 353 * 354 * @author Chris Smith <chris@jalakai.co.uk> 355 * @param string $group 356 * @return bool 357 */ 358 public function addGroup($group) 359 { 360 msg("authorisation method does not support independent group creation", -1); 361 return false; 362 } 363 364 /** 365 * Retrieve groups [implement only where required/possible] 366 * 367 * Set getGroups capability when implemented 368 * 369 * @author Chris Smith <chris@jalakai.co.uk> 370 * @param int $start 371 * @param int $limit 372 * @return array 373 */ 374 public function retrieveGroups($start = 0, $limit = 0) 375 { 376 msg("authorisation method does not support group list retrieval", -1); 377 return array(); 378 } 379 380 /** 381 * Return case sensitivity of the backend [OPTIONAL] 382 * 383 * When your backend is caseinsensitive (eg. you can login with USER and 384 * user) then you need to overwrite this method and return false 385 * 386 * @return bool 387 */ 388 public function isCaseSensitive() 389 { 390 return true; 391 } 392 393 /** 394 * Sanitize a given username [OPTIONAL] 395 * 396 * This function is applied to any user name that is given to 397 * the backend and should also be applied to any user name within 398 * the backend before returning it somewhere. 399 * 400 * This should be used to enforce username restrictions. 401 * 402 * @author Andreas Gohr <andi@splitbrain.org> 403 * @param string $user username 404 * @return string the cleaned username 405 */ 406 public function cleanUser($user) 407 { 408 return $user; 409 } 410 411 /** 412 * Sanitize a given groupname [OPTIONAL] 413 * 414 * This function is applied to any groupname that is given to 415 * the backend and should also be applied to any groupname within 416 * the backend before returning it somewhere. 417 * 418 * This should be used to enforce groupname restrictions. 419 * 420 * Groupnames are to be passed without a leading '@' here. 421 * 422 * @author Andreas Gohr <andi@splitbrain.org> 423 * @param string $group groupname 424 * @return string the cleaned groupname 425 */ 426 public function cleanGroup($group) 427 { 428 return $group; 429 } 430 431 /** 432 * Check Session Cache validity [implement only where required/possible] 433 * 434 * DokuWiki caches user info in the user's session for the timespan defined 435 * in $conf['auth_security_timeout']. 436 * 437 * This makes sure slow authentication backends do not slow down DokuWiki. 438 * This also means that changes to the user database will not be reflected 439 * on currently logged in users. 440 * 441 * To accommodate for this, the user manager plugin will touch a reference 442 * file whenever a change is submitted. This function compares the filetime 443 * of this reference file with the time stored in the session. 444 * 445 * This reference file mechanism does not reflect changes done directly in 446 * the backend's database through other means than the user manager plugin. 447 * 448 * Fast backends might want to return always false, to force rechecks on 449 * each page load. Others might want to use their own checking here. If 450 * unsure, do not override. 451 * 452 * @param string $user - The username 453 * @author Andreas Gohr <andi@splitbrain.org> 454 * @return bool 455 */ 456 public function useSessionCache($user) 457 { 458 global $conf; 459 return ($_SESSION[DOKU_COOKIE]['auth']['time'] >= @filemtime($conf['cachedir'] . '/sessionpurge')); 460 } 461 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body