Apply rector fixes to inc/Extension and inc/Debug
[dokuwiki.git] / inc / Extension / AuthPlugin.php
blob2d61dfd8e1e3e1e21917a90d25de8f7bb3213f69
1 <?php
3 namespace dokuwiki\Extension;
5 /**
6 * Auth Plugin Prototype
8 * allows to authenticate users in a plugin
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>
14 abstract class AuthPlugin extends Plugin
16 public $success = true;
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.
23 protected $cando = [
24 'addUser' => false,
25 // can Users be created?
26 'delUser' => false,
27 // can Users be deleted?
28 'modLogin' => false,
29 // can login names be changed?
30 'modPass' => false,
31 // can passwords be changed?
32 'modName' => false,
33 // can real names be changed?
34 'modMail' => false,
35 // can emails be changed?
36 'modGroups' => false,
37 // can groups be changed?
38 'getUsers' => false,
39 // can a (filtered) list of users be retrieved?
40 'getUserCount' => false,
41 // can the number of users be retrieved?
42 'getGroups' => false,
43 // can a list of available groups be retrieved?
44 'external' => false,
45 // does the module do external auth checking?
46 'logout' => true,
49 /**
50 * Constructor.
52 * Carry out sanity checks to ensure the object is
53 * able to operate. Set capabilities in $this->cando
54 * array here
56 * For future compatibility, sub classes should always include a call
57 * to parent::__constructor() in their constructors!
59 * Set $this->success to false if checks fail
61 * @author Christopher Smith <chris@jalakai.co.uk>
63 public function __construct()
65 // the base class constructor does nothing, derived class
66 // constructors do the real work
69 /**
70 * Available Capabilities. [ DO NOT OVERRIDE ]
72 * For introspection/debugging
74 * @author Christopher Smith <chris@jalakai.co.uk>
75 * @return array
77 public function getCapabilities()
79 return array_keys($this->cando);
82 /**
83 * Capability check. [ DO NOT OVERRIDE ]
85 * Checks the capabilities set in the $this->cando array and
86 * some pseudo capabilities (shortcutting access to multiple
87 * ones)
89 * ususal capabilities start with lowercase letter
90 * shortcut capabilities start with uppercase letter
92 * @author Andreas Gohr <andi@splitbrain.org>
93 * @param string $cap the capability to check
94 * @return bool
96 public function canDo($cap)
98 switch ($cap) {
99 case 'Profile':
100 // can at least one of the user's properties be changed?
101 return ($this->cando['modPass'] ||
102 $this->cando['modName'] ||
103 $this->cando['modMail']);
104 case 'UserMod':
105 // can at least anything be changed?
106 return ($this->cando['modPass'] ||
107 $this->cando['modName'] ||
108 $this->cando['modMail'] ||
109 $this->cando['modLogin'] ||
110 $this->cando['modGroups'] ||
111 $this->cando['modMail']);
112 default:
113 // print a helping message for developers
114 if (!isset($this->cando[$cap])) {
115 msg("Check for unknown capability '$cap' - Do you use an outdated Plugin?", -1);
117 return $this->cando[$cap];
122 * Trigger the AUTH_USERDATA_CHANGE event and call the modification function. [ DO NOT OVERRIDE ]
124 * You should use this function instead of calling createUser, modifyUser or
125 * deleteUsers directly. The event handlers can prevent the modification, for
126 * example for enforcing a user name schema.
128 * @author Gabriel Birke <birke@d-scribe.de>
129 * @param string $type Modification type ('create', 'modify', 'delete')
130 * @param array $params Parameters for the createUser, modifyUser or deleteUsers method.
131 * The content of this array depends on the modification type
132 * @return bool|null|int Result from the modification function or false if an event handler has canceled the action
134 public function triggerUserMod($type, $params)
136 $validTypes = ['create' => 'createUser', 'modify' => 'modifyUser', 'delete' => 'deleteUsers'];
137 if (empty($validTypes[$type])) {
138 return false;
141 $result = false;
142 $eventdata = ['type' => $type, 'params' => $params, 'modification_result' => null];
143 $evt = new Event('AUTH_USER_CHANGE', $eventdata);
144 if ($evt->advise_before(true)) {
145 $result = call_user_func_array([$this, $validTypes[$type]], $evt->data['params']);
146 $evt->data['modification_result'] = $result;
148 $evt->advise_after();
149 unset($evt);
150 return $result;
154 * Log off the current user [ OPTIONAL ]
156 * Is run in addition to the ususal logoff method. Should
157 * only be needed when trustExternal is implemented.
159 * @see auth_logoff()
160 * @author Andreas Gohr <andi@splitbrain.org>
162 public function logOff()
167 * Do all authentication [ OPTIONAL ]
169 * Set $this->cando['external'] = true when implemented
171 * If this function is implemented it will be used to
172 * authenticate a user - all other DokuWiki internals
173 * will not be used for authenticating (except this
174 * function returns null, in which case, DokuWiki will
175 * still run auth_login as a fallback, which may call
176 * checkPass()). If this function is not returning null,
177 * implementing checkPass() is not needed here anymore.
179 * The function can be used to authenticate against third
180 * party cookies or Apache auth mechanisms and replaces
181 * the auth_login() function
183 * The function will be called with or without a set
184 * username. If the Username is given it was called
185 * from the login form and the given credentials might
186 * need to be checked. If no username was given it
187 * the function needs to check if the user is logged in
188 * by other means (cookie, environment).
190 * The function needs to set some globals needed by
191 * DokuWiki like auth_login() does.
193 * @see auth_login()
194 * @author Andreas Gohr <andi@splitbrain.org>
196 * @param string $user Username
197 * @param string $pass Cleartext Password
198 * @param bool $sticky Cookie should not expire
199 * @return bool true on successful auth,
200 * null on unknown result (fallback to checkPass)
202 public function trustExternal($user, $pass, $sticky = false)
204 /* some example:
206 global $USERINFO;
207 global $conf;
208 $sticky ? $sticky = true : $sticky = false; //sanity check
210 // do the checking here
212 // set the globals if authed
213 $USERINFO['name'] = 'FIXME';
214 $USERINFO['mail'] = 'FIXME';
215 $USERINFO['grps'] = array('FIXME');
216 $_SERVER['REMOTE_USER'] = $user;
217 $_SESSION[DOKU_COOKIE]['auth']['user'] = $user;
218 $_SESSION[DOKU_COOKIE]['auth']['pass'] = $pass;
219 $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
220 return true;
226 * Check user+password [ MUST BE OVERRIDDEN ]
228 * Checks if the given user exists and the given
229 * plaintext password is correct
231 * May be ommited if trustExternal is used.
233 * @author Andreas Gohr <andi@splitbrain.org>
234 * @param string $user the user name
235 * @param string $pass the clear text password
236 * @return bool
238 public function checkPass($user, $pass)
240 msg("no valid authorisation system in use", -1);
241 return false;
245 * Return user info [ MUST BE OVERRIDDEN ]
247 * Returns info about the given user needs to contain
248 * at least these fields:
250 * name string full name of the user
251 * mail string email address of the user
252 * grps array list of groups the user is in
254 * @author Andreas Gohr <andi@splitbrain.org>
255 * @param string $user the user name
256 * @param bool $requireGroups whether or not the returned data must include groups
257 * @return false|array containing user data or false
259 public function getUserData($user, $requireGroups = true)
261 if (!$this->cando['external']) msg("no valid authorisation system in use", -1);
262 return false;
266 * Create a new User [implement only where required/possible]
268 * Returns false if the user already exists, null when an error
269 * occurred and true if everything went well.
271 * The new user HAS TO be added to the default group by this
272 * function!
274 * Set addUser capability when implemented
276 * @author Andreas Gohr <andi@splitbrain.org>
277 * @param string $user
278 * @param string $pass
279 * @param string $name
280 * @param string $mail
281 * @param null|array $grps
282 * @return bool|null
284 public function createUser($user, $pass, $name, $mail, $grps = null)
286 msg("authorisation method does not allow creation of new users", -1);
287 return null;
291 * Modify user data [implement only where required/possible]
293 * Set the mod* capabilities according to the implemented features
295 * @author Chris Smith <chris@jalakai.co.uk>
296 * @param string $user nick of the user to be changed
297 * @param array $changes array of field/value pairs to be changed (password will be clear text)
298 * @return bool
300 public function modifyUser($user, $changes)
302 msg("authorisation method does not allow modifying of user data", -1);
303 return false;
307 * Delete one or more users [implement only where required/possible]
309 * Set delUser capability when implemented
311 * @author Chris Smith <chris@jalakai.co.uk>
312 * @param array $users
313 * @return int number of users deleted
315 public function deleteUsers($users)
317 msg("authorisation method does not allow deleting of users", -1);
318 return 0;
322 * Return a count of the number of user which meet $filter criteria
323 * [should be implemented whenever retrieveUsers is implemented]
325 * Set getUserCount capability when implemented
327 * @author Chris Smith <chris@jalakai.co.uk>
328 * @param array $filter array of field/pattern pairs, empty array for no filter
329 * @return int
331 public function getUserCount($filter = [])
333 msg("authorisation method does not provide user counts", -1);
334 return 0;
338 * Bulk retrieval of user data [implement only where required/possible]
340 * Set getUsers capability when implemented
342 * @author Chris Smith <chris@jalakai.co.uk>
343 * @param int $start index of first user to be returned
344 * @param int $limit max number of users to be returned, 0 for unlimited
345 * @param array $filter array of field/pattern pairs, null for no filter
346 * @return array list of userinfo (refer getUserData for internal userinfo details)
348 public function retrieveUsers($start = 0, $limit = 0, $filter = null)
350 msg("authorisation method does not support mass retrieval of user data", -1);
351 return [];
355 * Define a group [implement only where required/possible]
357 * Set addGroup capability when implemented
359 * @author Chris Smith <chris@jalakai.co.uk>
360 * @param string $group
361 * @return bool
363 public function addGroup($group)
365 msg("authorisation method does not support independent group creation", -1);
366 return false;
370 * Retrieve groups [implement only where required/possible]
372 * Set getGroups capability when implemented
374 * @author Chris Smith <chris@jalakai.co.uk>
375 * @param int $start
376 * @param int $limit
377 * @return array
379 public function retrieveGroups($start = 0, $limit = 0)
381 msg("authorisation method does not support group list retrieval", -1);
382 return [];
386 * Return case sensitivity of the backend [OPTIONAL]
388 * When your backend is caseinsensitive (eg. you can login with USER and
389 * user) then you need to overwrite this method and return false
391 * @return bool
393 public function isCaseSensitive()
395 return true;
399 * Sanitize a given username [OPTIONAL]
401 * This function is applied to any user name that is given to
402 * the backend and should also be applied to any user name within
403 * the backend before returning it somewhere.
405 * This should be used to enforce username restrictions.
407 * @author Andreas Gohr <andi@splitbrain.org>
408 * @param string $user username
409 * @return string the cleaned username
411 public function cleanUser($user)
413 return $user;
417 * Sanitize a given groupname [OPTIONAL]
419 * This function is applied to any groupname that is given to
420 * the backend and should also be applied to any groupname within
421 * the backend before returning it somewhere.
423 * This should be used to enforce groupname restrictions.
425 * Groupnames are to be passed without a leading '@' here.
427 * @author Andreas Gohr <andi@splitbrain.org>
428 * @param string $group groupname
429 * @return string the cleaned groupname
431 public function cleanGroup($group)
433 return $group;
437 * Check Session Cache validity [implement only where required/possible]
439 * DokuWiki caches user info in the user's session for the timespan defined
440 * in $conf['auth_security_timeout'].
442 * This makes sure slow authentication backends do not slow down DokuWiki.
443 * This also means that changes to the user database will not be reflected
444 * on currently logged in users.
446 * To accommodate for this, the user manager plugin will touch a reference
447 * file whenever a change is submitted. This function compares the filetime
448 * of this reference file with the time stored in the session.
450 * This reference file mechanism does not reflect changes done directly in
451 * the backend's database through other means than the user manager plugin.
453 * Fast backends might want to return always false, to force rechecks on
454 * each page load. Others might want to use their own checking here. If
455 * unsure, do not override.
457 * @param string $user - The username
458 * @author Andreas Gohr <andi@splitbrain.org>
459 * @return bool
461 public function useSessionCache($user)
463 global $conf;
464 return ($_SESSION[DOKU_COOKIE]['auth']['time'] >= @filemtime($conf['cachedir'] . '/sessionpurge'));