1<?php 2// must be run within Dokuwiki 3if(!defined('DOKU_INC')) die(); 4 5/** 6 * Chained authentication backend 7 * 8 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 9 * @author Philipp Nesuer <pneuser@physik.fu-berlin.de> 10 */ 11class auth_plugin_authchained extends DokuWiki_Auth_Plugin { 12 public $success = true; 13 //arry with authentication plugins 14 protected $chained_plugins = array(); 15 protected $chained_auth = NULL; 16 17 /** 18 * Constructor. 19 * 20 * Loads all configured plugins or the authentication plugin of the 21 * logged in user. 22 * 23 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 24 */ 25 public function __construct() { 26 global $conf; 27 // call parent 28# parent::__constructor(); 29 30 //check if there is allready an authentication plugin selected 31 if(isset($_SESSION[DOKU_COOKIE]['auth']['chained']['module']) && 32 !empty($_SESSION[DOKU_COOKIE]['auth']['chained']['module']) ) 33 { 34 //get previously selected authentication plugin 35 $tmp_plugin = $_SESSION[DOKU_COOKIE]['auth']['chained']['module']; 36 require_once(DOKU_INC."lib/plugins/".$tmp_plugin."/auth.php"); 37 $tmp_classname = "auth_plugin_".$tmp_plugin; 38 $this->chained_auth = new $tmp_classname; 39 } 40 else { 41 //get authentication plugins 42 if(isset($conf['auth']['chained']['authtypes'])){ 43 foreach(explode(":",$conf['auth']['chained']['authtypes']) as 44 $tmp_plugin){ 45 require_once(DOKU_INC."lib/plugins/".$tmp_plugin."/auth.php"); 46 $tmp_classname = "auth_plugin_".$tmp_plugin; 47 $tmp_class = new $tmp_classname; 48 $tmp_module = array($tmp_plugin,$tmp_class); 49 array_push($this->chained_plugins, $tmp_module); 50 } 51 }else{ 52 $success = false; 53 } 54 } 55 //debug 56// print_r($chained_plugins); 57 } 58 59 /** 60 * Forwards the authentication to configured authplugins. 61 * Returns true, if the usermanager authtype has the capability and no user 62 * is logged in. 63 * 64 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 65 * @param string $cap the capability to check 66 * @return bool 67 */ 68 public function canDo($cap) { 69 global $conf; 70 if(is_null($this->chained_auth)) 71 { 72 foreach($this->chained_plugins as $module) 73 { 74 #echo "TEST AUTHMANAGER!!!"; 75 if($module[0] == 76 $conf['auth']['chained']['usermanager_authtype']){ 77 $module[1]->canDo($cap); 78 } 79 } 80 return false; 81 } 82 else{ 83 #echo "canDo $cap ".$this->chained_auth->canDo($cap)."\n"; 84 return $this->chained_auth->canDo($cap); 85 } 86 } 87 88 /** 89 * Forwards the result of the auth plugin of the logged in user or 90 * returns false 91 * 92 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 93 * @param string $type Modification type ('create', 'modify', 'delete') 94 * @param array $params Parameters for the createUser, modifyUser or deleteUsers method. The content of this array depends on the modification type 95 * @return mixed Result from the modification function or false if an event handler has canceled the action 96 */ 97 public function triggerUserMod($type, $params) { 98 if(is_null($this->chained_auth)) 99 return false; 100 else 101 return $this->chained_auth->canDo($cap); 102 } 103 104 /** 105 * Forwards the result of the auth plugin of the logged in user and 106 * unsets our session variable. 107 * @see auth_logoff() 108 * @author Philipp Neuser <pneuser@physik.fu-berlin.de 109 */ 110 public function logOff() { 111 if(!is_null($this->chained_auth)) 112 $this->chained_auth->logOff(); 113 unset($_SESSION[DOKU_COOKIE]['auth']['chained']['module']); 114 } 115 116 /** 117 * Do all authentication [ OPTIONAL ] 118 * If the current plugin is external, be external. 119 * 120 * @see auth_login() 121 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 122 * 123 * @param string $user Username 124 * @param string $pass Cleartext Password 125 * @param bool $sticky Cookie should not expire 126 * @return bool true on successful auth 127 */ 128 public function trustExternal($user, $pass, $sticky = false) { 129 if(!is_null($this->chained_auth) && $this->chained_auth->canDo('external')) 130 $this->chained_auth->trustExternal($user, $pass, $sticky); 131 } 132 133 /** 134 * Check user+password [ MUST BE OVERRIDDEN ] 135 * 136 * Checks if the given user exists in one of the plugins and checks 137 * against the given password. The first plugin returning true becomes 138 * auth plugin of the user session. 139 * 140 * @author Philipp Neuser <pneuser@physik.fu-berlin.de 141 * @param string $user the user name 142 * @param string $pass the clear text password 143 * @return bool 144 */ 145 public function checkPass($user, $pass) { 146 //debug 147 //print_r($this->chained_plugins); 148 foreach($this->chained_plugins as $module) 149 { 150 if($module[1]->canDo('external')) 151 { 152 if($module[1]->trustExternal($user, $pass)) 153 { 154 $_SESSION[DOKU_COOKIE]['auth']['chained']['module'] = 155 $module[0]; 156 $this->chained_auth = $module[1]; 157 return true; 158 }else{ 159 if($module[1]->checkPass($user, $pass)) 160 { 161 $_SESSION[DOKU_COOKIE]['auth']['chained']['module'] = 162 $module[0]; 163 $this->chained_auth = $module[1]; 164 return true; 165 } 166 } 167 }else{ 168 if($module[1]->checkPass($user, $pass)) 169 { 170 $_SESSION[DOKU_COOKIE]['auth']['chained']['module'] = 171 $module[0]; 172 $this->this->chained_auth = $module[1]; 173 return true; 174 } 175 } 176 } 177 return false; 178 } 179 180 /** 181 * Forwards the result of the auth plugin of the logged in user or 182 * checks all plugins if the users exists. The first plugin returning 183 * data is used. 184 * 185 * name string full name of the user 186 * mail string email addres of the user 187 * grps array list of groups the user is in 188 * 189 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 190 * @param string $user the user name 191 * @return array containing user data or false 192 */ 193 public function getUserData($user) { 194 //if(!$this->cando['external']) msg("no valid authorisation system in use", -1); 195// echo "TESTSETEST"; 196 if(is_null($this->chained_auth)) 197 { 198 foreach($this->chained_plugins as $module) 199 { 200 $tmp_array = $module[1]->getUserData($user); 201 if(!is_bool($tmp_array)) 202 $tmp_chk_arr =array_filter($tmp_array); 203 if(!empty($tmp_chk_arr) && $tmp_array) 204 return $tmp_array; 205 } 206 return false; 207 } 208 else 209 { 210 return $this->chained_auth->getUserData($user); 211 } 212 } 213 214 /** 215 * Forwards the result of the auth plugin of the logged in user or 216 * returns null. 217 * 218 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 219 * @param string $user 220 * @param string $pass 221 * @param string $name 222 * @param string $mail 223 * @param null|array $grps 224 * @return bool|null 225 */ 226 public function createUser($user, $pass, $name, $mail, $grps = null) { 227 if(is_null($this->chained_auth)){ 228 msg("authorisation method does not allow creation of new users", 229 -1); 230 return null; 231 } 232 else{ 233 //please note: users will be added to the module, to which the 234 //current user is logged into 235 if($this->canDo('addUser')){ 236 return $this->chained_auth->createUser($user, $pass, $name, $mail, 237 $grps); 238 }else{ 239 msg("authorisation method does not allow creation of new 240 users", -1); 241 return null; 242 } 243 } 244 } 245 246 /** 247 * Forwards the result of the auth plugin of the logged in user or 248 * returns false 249 * 250 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 251 * @param string $user nick of the user to be changed 252 * @param array $changes array of field/value pairs to be changed (password will be clear text) 253 * @return bool 254 */ 255 public function modifyUser($user, $changes) { 256 if(is_null($this->chained_auth)){ 257 msg("authorisation method does not allow modifying of user data", 258 -1); 259 return false; 260 } 261 else{ 262 //please note: users will be modified in the module, to which the 263 //current user is logged into 264 if($this->canDo('modLogin') && $this->canDo('modPass') && 265 $this->canDo('modName') && $this->canDo('modMail') && 266 $this->canDo('modGroups')){ 267 return $this->chained_auth->createUser($user, $changes); 268 }else{ 269 msg("authorisation method does not allow modifying of user 270 data", -1); 271 return false; 272 } 273 } 274 275 } 276 277 /** 278 * Forwards the result of the auth plugin of the logged in user or 279 * returns false 280 * 281 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 282 * @param array $users 283 * @return int number of users deleted 284 */ 285 public function deleteUsers($users) { 286 if(is_null($this->chained_auth)){ 287 msg("authorisation method does not allow deleting of users", 288 -1); 289 return false; 290 } 291 else{ 292 //please note: users will be added to the module, to which the 293 //current user is logged into 294 if($this->canDo('delUser')){ 295 return $this->chained_auth->createUser($users); 296 }else{ 297 msg("authorisation method does not allow deleting of users", -1); 298 return false; 299 } 300 } 301 } 302 303 /** 304 * Forwards the result of the auth plugin of the logged in user or 305 * returns 0 306 * 307 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 308 * @param array $filter array of field/pattern pairs, empty array for no filter 309 * @return int 310 */ 311 public function getUserCount($filter = array()) { 312 if(is_null($this->chained_auth)){ 313 msg("authorisation method does not provide user counts", 314 -1); 315 return 0; 316 } 317 else{ 318 //please note: users will be counted in the module, to which the 319 //current user is logged into 320 if($this->canDo('getUserCount')){ 321 return $this->chained_auth->getUserCount($filter); 322 }else{ 323 msg("authorisation method does not provide user counts", -1); 324 return 0; 325 } 326 } 327 328 } 329 330 /** 331 * Forwards the result of the auth plugin of the logged in user or 332 * returns empty array 333 * 334 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 335 * @param int $start index of first user to be returned 336 * @param int $limit max number of users to be returned 337 * @param array $filter array of field/pattern pairs, null for no filter 338 * @return array list of userinfo (refer getUserData for internal userinfo details) 339 */ 340 public function retrieveUsers($start = 0, $limit = -1, $filter = null) { 341 if(is_null($this->chained_auth)){ 342 msg("authorisation method does not support mass retrievals", 343 -1); 344 return array(); 345 } 346 else{ 347 //please note: users will be retrieved from the module, to which the 348 //current user is logged into 349 if($this->canDo('getUsers')){ 350 return $this->chained_auth->retrieveUsers($start, $limit, $filter); 351 }else{ 352 msg("authorisation method does not support mass retrievals", -1); 353 return array(); 354 } 355 } 356 } 357 358 /** 359 * Forwards the result of the auth plugin of the logged in user or 360 * returns false 361 * 362 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 363 * @param string $group 364 * @return bool 365 */ 366 public function addGroup($group) { 367 if(is_null($this->chained_auth)){ 368 msg("authorisation method does not support independent group 369 creation", 370 -1); 371 return false; 372 } 373 else{ 374 //please note: users will be added to the module, to which the 375 //current user is logged into 376 if($this->canDo('addGroup')){ 377 return $this->chained_auth->addGroup($group); 378 }else{ 379 msg("authorisation method does not support independent group 380 creation", -1); 381 return false; 382 } 383 } 384 } 385 386 /** 387 * Forwards the result of the auth plugin of the logged in user or 388 * returns empty array 389 * 390 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 391 * @param int $start 392 * @param int $limit 393 * @return array 394 */ 395 public function retrieveGroups($start = 0, $limit = 0) { 396 if(is_null($this->chained_auth)){ 397 msg("authorisation method does not support group list retrieval", 398 -1); 399 return array(); 400 } 401 else{ 402 //please note: users will be retrieved from the module, to which the 403 //current user is logged into 404 if($this->canDo('getGroups')){ 405 return $this->chained_auth->retrieveGroups($start,$limit); 406 }else{ 407 msg("authorisation method does not support group list 408 retrieval", -1); 409 return array(); 410 } 411 } 412 } 413 414 /** 415 * Forwards the result of the auth plugin of the logged in user or 416 * returns true 417 * 418 * @return bool 419 */ 420 public function isCaseSensitive() { 421 if(is_null($this->chained_auth)) 422 return true; 423 else 424 return $this->chained_auth->isCaseSensitive(); 425 } 426 427 /** 428 * Sanitize a given username [OPTIONAL] 429 * Forwards the result of the auth plugin of the logged in user or 430 * returns false 431 * 432 * 433 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 434 * @param string $user username 435 * @return string the cleaned username 436 */ 437 public function cleanUser($user) { 438 //print_r($this->chained_auth); 439 if(is_null($this->chained_auth)) 440 return $user; 441 else 442 return $this->chained_auth->cleanUser($user); 443 } 444 445 /** 446 * Sanitize a given groupname [OPTIONAL] 447 * Forwards the result of the auth plugin of the logged in user or 448 * returns false 449 * 450 * @author Philipp Neuser <pneuser@physik.fu-berlin.de> 451 * @param string $group groupname 452 * @return string the cleaned groupname 453 */ 454 public function cleanGroup($group) { 455 if(is_null($this->chained_auth)) 456 { 457 return $group; 458 } 459 else 460 return $this->chained_auth->cleanGroup($group); 461 } 462 463 464 public function useSessionCache($user) { 465 global $conf; 466 if(is_null($this->chained_auth)) 467 return ($_SESSION[DOKU_COOKIE]['auth']['time'] >= 468 @filemtime($conf['cachedir'].'/sessionpurge')); 469 else 470 return $this->chained_auth->useSessionCache($user); 471 } 472} 473