Completed
Push — sidebaracl ( 7a112d...7c3e4a )
by Andreas
04:38
created

lib/plugins/auth.php (2 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
455
        $this->configloaded = true;
0 ignored issues
show
The property configloaded cannot be accessed from this context as it is declared private in class DokuWiki_Plugin.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
456
    }
457
}
458