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