]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiGroup.php
store current user->page and ->action in session for WhoIsOnline
[SourceForge/phpwiki.git] / lib / WikiGroup.php
1 <?php
2 rcs_id('$Id: WikiGroup.php,v 1.17 2004-03-10 15:38:48 rurban Exp $');
3 /*
4  Copyright 2003, 2004 $ThePhpWikiProgrammingTeam
5
6  This file is part of PhpWiki.
7
8  PhpWiki is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12
13  PhpWiki is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with PhpWiki; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 // For now we provide no default memberhsip method. This might change.
24 // (!defined('GROUP_METHOD')) define('GROUP_METHOD', "WIKIPAGE");
25
26 if (!defined('GROUP_METHOD') or 
27     !in_array(GROUP_METHOD,
28               array('NONE','WIKIPAGE','DB','FILE','LDAP')))
29     trigger_error(_("No or unsupported GROUP_METHOD defined"), E_USER_WARNING);
30     
31 /* Special group names for ACL */    
32 define('GROUP_EVERY',           _("Every"));
33 define('GROUP_ANONYMOUS',       _("Anonymous Users"));
34 define('GROUP_BOGOUSERS',       _("Bogo Users"));
35 define('GROUP_HASHOMEPAGE',     _("HasHomePage"));
36 define('GROUP_SIGNED',          _("Signed Users"));
37 define('GROUP_AUTHENTICATED',   _("Authenticated Users"));
38 define('GROUP_ADMIN',           _("Administrators"));
39 define('GROUP_OWNER',           _("Owner"));
40 define('GROUP_CREATOR',         _("Creator"));
41
42 /**
43  * WikiGroup is an abstract class to provide the base functions for determining
44  * group membership.
45  * 
46  * WikiGroup is an abstract class with three functions:
47  * <ol><li />Provide the static method getGroup with will return the proper
48  *         subclass.
49  *     <li />Provide an interface for subclasses to implement.
50  *     <li />Provide fallover methods (with error msgs) if not impemented in subclass.
51  * </ol>
52  * Do not ever instantiate this class use: $group = &WikiGroup::getGroup($request);
53  * This will instantiate the proper subclass.
54  * @author Joby Walker <zorloc@imperium.org>
55  */ 
56 class WikiGroup{
57     /** User name */
58     var $username;
59     /** The global WikiRequest object */
60     var $request;
61     /** Array of groups $username is confirmed to belong to */
62     var $membership;
63     
64     /**
65      * Initializes a WikiGroup object which should never happen.  Use:
66      * $group = &WikiGroup::getGroup($request);
67      * @param object $request The global WikiRequest object -- ignored.
68      */ 
69     function WikiGroup(&$request){    
70         return;
71     }
72
73     /**
74      * Gets the current username and erases $this->membership if is different than
75      * the stored $this->username
76      * @return string Current username.
77      */ 
78     function _getUserName(){
79         $request = &$this->request;
80         $user = $request->getUser();
81         $username = $user->getID();
82         if ($username != $this->username) {
83             $this->membership = array();
84             $this->username = $username;
85         }
86         return $username;
87     }
88     
89     /**
90      * Static method to return the WikiGroup subclass used in this wiki.  Controlled
91      * by the constant GROUP_METHOD.
92      * @param object $request The global WikiRequest object.
93      * @return object Subclass of WikiGroup selected via GROUP_METHOD.
94      */ 
95     function getGroup($request){
96         switch (GROUP_METHOD){
97             case "NONE": 
98                 return new GroupNone($request);
99                 break;
100             case "WIKIPAGE":
101                 return new GroupWikiPage($request);
102                 break;
103             case "DB":
104                 return new GroupDB($request);
105                 break;
106             case "FILE": 
107                 return new GroupFile($request);
108                 break;
109             case "LDAP": 
110                 return new GroupLDAP($request);
111                 break;
112             default:
113                 trigger_error(_("No or unsupported GROUP_METHOD defined"), E_USER_WARNING);
114                 return new WikiGroup($request);
115         }
116     }
117
118     /* ACL PagePermissions will need those special groups based on the User status only */
119     function specialGroup($group){
120         return in_array($group,$this->specialGroups());
121     }
122
123     function specialGroups(){
124         return array(
125                      GROUP_EVERY,
126                      GROUP_ANONYMOUS,
127                      GROUP_BOGOUSERS,
128                      GROUP_SIGNED,
129                      GROUP_AUTHENTICATED,
130                      GROUP_ADMIN);
131     }
132
133     /**
134      * Determines if the current user is a member of a group.
135      * 
136      * This method is an abstraction.  The group is ignored, an error is sent, and
137      * false (not a member of the group) is returned.
138      * @param string $group Name of the group to check for membership (ignored).
139      * @return boolean True if user is a member, else false (always false).
140      */ 
141     function isMember($group){
142         if ($this->specialGroup($group)) {
143             $request = &$this->request;
144             $user = $request->getUser();
145             switch ($group) {
146             case GROUP_EVERY:           return true;
147             case GROUP_ANONYMOUS:       return ! $user->isSignedIn();
148             case GROUP_BOGOUSERS:       return isa($user,'_BogoUser');
149             case GROUP_SIGNED:          return $user->isSignedIn();
150             case GROUP_AUTHENTICATED:   return $user->isAuthenticated();
151             case GROUP_ADMIN:           return $user->isAdmin();
152             default:
153                 trigger_error(__sprintf("Undefined method %s for special group %s",
154                                         'isMember',$group),
155                               E_USER_WARNING);
156             }
157         } else {
158             trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
159                                     'isMember',GROUP_METHOD),
160                           E_USER_WARNING);
161         }
162         return false;
163     }
164     
165     /**
166      * Determines all of the groups of which the current user is a member.
167      * 
168      * This method is an abstraction.  An error is sent and an empty 
169      * array is returned.
170      * @return array Array of groups to which the user belongs (always empty).
171      */ 
172     function getAllGroupsIn(){
173         trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
174                                 'getAllGroupsIn',GROUP_METHOD),
175                       E_USER_WARNING);
176         return array();
177     }
178
179     function _allUsers() {
180         static $users = array();
181         if (!empty($users))
182                 return $users;
183                 
184         /* WikiPage users: */
185         $dbh = $this->request->getDbh();
186         $page_iter = $dbh->getAllPages();
187         while ($page = $page_iter->next()) {
188             if ($page->isUserPage())
189                 $users[] = $page->_pagename;
190         }
191
192         /* WikiDB users from prefs (not from users): */
193         $dbi = _PassUser::getAuthDbh();
194         if ($dbi and !empty($GLOBALS['DBAuthParams']['pref_select'])) {
195             //get prefs table
196             $sql = preg_replace('/SELECT .+ FROM/i','SELECT userid FROM',$GLOBALS['DBAuthParams']['pref_select']);
197             //don't strip WHERE, only the userid stuff.
198             $sql = preg_replace('/(WHERE.*?)\s+\w+\s*=\s*"\$userid"/i','\\1 AND 1',$sql);
199             $sql = str_replace('WHERE AND 1','',$sql);
200             if ($GLOBALS['DBParams']['dbtype'] == 'ADODB') {
201                 $db_result = $dbi->Execute($sql);
202                 foreach ($db_result->GetArray() as $u) {
203                    $users = array_merge($users,array_values($u));
204                 }
205             } elseif ($GLOBALS['DBParams']['dbtype'] == 'SQL') {
206                 $users = array_merge($users,$dbi->getCol($sql));
207             }
208         }
209
210         /* WikiDB users from users: */
211         // Fixme: don't strip WHERE, only the userid stuff.
212         if ($dbi and !empty($GLOBALS['DBAuthParams']['auth_user_exists'])) {
213             //don't strip WHERE, only the userid stuff.
214             $sql = preg_replace('/(WHERE.*?)\s+\w+\s*=\s*"\$userid"/i','\\1 AND 1',$GLOBALS['DBAuthParams']['auth_user_exists']);
215             $sql = str_replace('WHERE AND 1','',$sql);
216             if ($GLOBALS['DBParams']['dbtype'] == 'ADODB') {
217                 $db_result = $dbi->Execute($sql);
218                 foreach ($db_result->GetArray() as $u) {
219                    $users = array_merge($users,array_values($u));
220                 }
221             } elseif ($GLOBALS['DBParams']['dbtype'] == 'SQL') {
222                 $users = array_merge($users,$dbi->getCol($sql));
223             }
224         }
225
226         return array_unique($users);
227     }
228
229     /**
230      * Determines all of the members of a particular group.
231      * 
232      * This method is an abstraction.  The group is ignored, an error is sent, 
233      * and an empty array is returned
234      * @param string $group Name of the group to get the full membership list of.
235      * @return array Array of usernames that have joined the group (always empty).
236      */ 
237     function getMembersOf($group){
238         if ($this->specialGroup($group)) {
239             $request = &$this->request;
240             $all = $this->_allUsers();
241             $users = array();
242             switch ($group) {
243             case GROUP_EVERY:           
244                 return $all;
245             case GROUP_ANONYMOUS:       
246                 return $users;
247             case GROUP_BOGOUSERS:       
248                 foreach ($all as $u) {
249                     if (isWikiWord($user)) $users[] = $u;
250                 }
251                 return $users;
252             case GROUP_SIGNED:          
253                 foreach ($all as $u) {
254                     $user = WikiUser($u);
255                     if ($user->isSignedIn()) $users[] = $u;
256                 }
257                 return $users;
258             case GROUP_AUTHENTICATED:
259                 foreach ($all as $u) {
260                     $user = WikiUser($u);
261                     if ($user->isAuthenticated()) $users[] = $u;
262                 }
263                 return $users;
264             case GROUP_ADMIN:           
265                 foreach ($all as $u) {
266                     $user = WikiUser($u);
267                     if ($user->isAdmin()) $users[] = $u;
268                 }
269                 return $users;
270             default:
271                 trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
272                                         'getMembersOf',GROUP_METHOD),
273                               E_USER_WARNING);
274             }
275         }
276         trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
277                                 'getMembersOf',GROUP_METHOD),
278                       E_USER_WARNING);
279         return array();
280     }
281
282     /**
283      * Add the current or specified user to a group.
284      * 
285      * This method is an abstraction.  The group and user are ignored, an error 
286      * is sent, and false (not added) is always returned.
287      * @param string $group User added to this group.
288      * @param string $user Username to add to the group (default = current user).
289      * @return bool On true user was added, false if not.
290      */ 
291     function setMemberOf($group, $user = false){
292         trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
293                                 'setMemberOf',GROUP_METHOD),
294                       E_USER_WARNING);
295         return false;
296     }
297     
298     /**
299      * Remove the current or specified user to a group.
300      * 
301      * This method is an abstraction.  The group and user are ignored, and error
302      * is sent, and false (not removed) is always returned.
303      * @param string $group User removed from this group.
304      * @param string $user Username to remove from the group (default = current user).
305      * @return bool On true user was removed, false if not.
306      */ 
307     function removeMemberOf($group, $user = false){
308         trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
309                                 'removeMemberOf',GROUP_METHOD),
310                       E_USER_WARNING);
311         return false;
312     }
313 }
314
315 /**
316  * GroupNone disables all Group funtionality
317  * 
318  * All of the GroupNone functions return false or empty values to indicate failure or 
319  * no results.  Use GroupNone if group controls are not desired.
320  * @author Joby Walker <zorloc@imperium.org>
321  */ 
322 class GroupNone extends WikiGroup{
323
324     /**
325      * Constructor
326      * 
327      * Ignores the parameter provided.
328      * @param object $request The global WikiRequest object - ignored.
329      */ 
330     function GroupNone(&$request){
331         return;
332     }    
333
334     /**
335      * Determines if the current user is a member of a group.
336      * 
337      * The group is ignored and false (not a member of the group) is returned.
338      * @param string $group Name of the group to check for membership (ignored).
339      * @return boolean True if user is a member, else false (always false).
340      */ 
341     function isMember($group){
342         if ($this->specialGroup($group)) {
343             return WikiGroup::isMember($group);
344         } else {
345             return false;
346         }
347     }
348     
349     /**
350      * Determines all of the groups of which the current user is a member.
351      * 
352      * The group is ignored and an empty array (a member of no groups) is returned.
353      * @param string $group Name of the group to check for membership (ignored).
354      * @return array Array of groups to which the user belongs (always empty).
355      */ 
356     function getAllGroupsIn(){
357         return array();
358     }
359
360     /**
361      * Determines all of the members of a particular group.
362      * 
363      * The group is ignored and an empty array (a member of no groups) is returned.
364      * @param string $group Name of the group to check for membership (ignored).
365      * @return array Array of groups user belongs to (always empty).
366      */ 
367     function getMembersOf($group){
368         return array();
369     }
370
371 }
372
373 /**
374  * GroupWikiPage provides group functionality via pages within the Wiki.
375  * 
376  * GroupWikiPage is the Wiki way of managing a group.  Every group will have 
377  * a page. To modify the membership of the group, one only needs to edit the 
378  * membership list on the page.
379  * @author Joby Walker <zorloc@imperium.org>
380  */ 
381 class GroupWikiPage extends WikiGroup{
382     
383     /**
384      * Constructor
385      * 
386      * Initializes the three superclass instance variables
387      * @param object $request The global WikiRequest object.
388      */ 
389     function GroupWikiPage(&$request){
390         $this->request = &$request;
391         $this->username = $this->_getUserName();
392         //$this->username = null;
393         $this->membership = array();
394     }
395
396     /**
397      * Determines if the current user is a member of a group.
398      * 
399      * To determine membership in a particular group, this method checks the 
400      * superclass instance variable $membership to see if membership has 
401      * already been determined.  If not, then the group page is parsed to 
402      * determine membership.
403      * @param string $group Name of the group to check for membership.
404      * @return boolean True if user is a member, else false.
405      */ 
406     function isMember($group){
407         if ($this->specialGroup($group))
408             return WikiGroup::isMember($group);
409
410         $request = $this->request;
411         //$username = $this->_getUserName();
412         if (isset($this->membership[$group])) {
413             return $this->membership[$group];
414         }
415         $group_page = $request->getPage($group);
416         if ($this->_inGroupPage($group_page)) {
417             $this->membership[$group] = true;
418             return true;
419         }
420         $this->membership[$group] = false;
421         return false;
422     }
423     
424     /**
425     * Private method to take a WikiDB_Page and parse to determine if the
426     * current_user is a member of the group.
427     * @param object $group_page WikiDB_Page object for the group's page
428     * @return boolean True if user is a member, else false.
429     * @access private
430     */
431     function _inGroupPage($group_page){
432         $group_revision = $group_page->getCurrentRevision();
433         if ($group_revision->hasDefaultContents()) {
434             $group = $group_page->getName();
435             trigger_error(sprintf(_("Group %s does not exist"),$group), E_USER_WARNING);
436             return false;
437         }
438         $contents = $group_revision->getContent();
439         $match = '/^\s*[\*\#]+\s*' . $this->username . '\s*$/';
440         foreach ($contents as $line){
441             if (preg_match($match, $line)) {
442                 return true;
443             }
444         }
445         return false;
446     }
447     
448     /**
449      * Determines all of the groups of which the current user is a member.
450      * 
451      * Checks the root Group page ('CategoryGroup') for the list of all groups, 
452      * then checks each group to see if the current user is a member.
453      * @param string $group Name of the group to check for membership.
454      * @return array Array of groups to which the user belongs.
455      */ 
456     function getAllGroupsIn(){
457         $request = &$this->request;
458         //$username = $this->_getUserName();
459         $membership = array();
460
461         $specialgroups = $this->specialGroups();
462         foreach ($specialgroups as $group) {
463             $this->membership[$group] = $this->isMember($group);
464         }
465
466         $dbh = &$request->getDbh();
467         $master_page = $request->getPage(_("CategoryGroup"));
468         $master_list = $master_page->getLinks(true);
469         while ($group_page = $master_list->next()){
470             $group = $group_page->getName();
471             $this->membership[$group] = $this->_inGroupPage($group_page);
472         }
473         foreach ($this->membership as $g => $bool) {
474             if ($bool) $membership[] = $g;
475         }
476         return $membership;
477     }
478
479     /**
480      * Determines all of the members of a particular group.
481      * 
482      * Checks a group's page to return all the current members.  Currently this
483      * method is disabled and triggers an error and returns an empty array.
484      * @param string $group Name of the group to get the full membership list of.
485      * @return array Array of usernames that have joined the group (always empty).
486      */ 
487     function getMembersOf($group){
488         if ($this->specialGroup($group))
489             return WikiGroup::getMembersOf($group);
490
491         trigger_error("GroupWikiPage::getMembersOf is not yet implimented",
492                       E_USER_WARNING);
493         return array();
494         /*
495         * Waiting for a reliable way to check if a string is a username.
496         $request = $this->request;
497         $user = $this->user;
498         $group_page = $request->getPage($group);
499         $group_revision = $group_page->getCurrentRevision();
500         if ($group_revision->hasDefaultContents()) {
501             trigger_error("Group $group does not exist", E_USER_WARNING);
502             return false;
503         }
504         $contents = $group_revision->getContent();
505         $match = '/^(\s*[\*\#]+\s*)(\w+)(\s*)$/';
506         $members = array();
507         foreach($contents as $line){
508             $matches = array();
509             if(preg_match($match, $line, $matches)){
510                 $members[] = $matches[2];
511             }
512         }
513         return $members;
514         */
515     }
516 }
517
518 /**
519  * GroupDb is configured by $DbAuthParams[] statements
520  * 
521  * @author ReiniUrban
522  */ 
523 class GroupDb extends WikiGroup {
524     
525     var $_is_member, $_group_members, $_user_groups;
526     /**
527      * Constructor
528      * 
529      * @param object $request The global WikiRequest object.
530      */ 
531     function GroupDb(&$request){
532         global $DBAuthParams;
533         $this->request = &$request;
534         $this->username = $this->_getUserName();
535         //$this->membership = array();
536
537         if (empty($DBAuthParams['group_members']) or 
538             empty($DBAuthParams['user_groups']) or
539             empty($DBAuthParams['is_member'])) {
540             trigger_error(_("No or not enough GROUP_DB SQL statements defined"), E_USER_WARNING);
541             return false;
542         }
543         _PassUser::getAuthDbh();
544         $this->_is_member = $this->_auth_dbi->prepare(str_replace(array('"$userid"','"$groupname"'),
545                                                                   array('?','?'),
546                                                                   $DBAuthParams['is_member']));
547         $this->_group_members = $this->_auth_dbi->prepare(str_replace('"$groupname"','?',
548                                                                       $DBAuthParams['group_members']));
549         $this->_user_groups = $this->_auth_dbi->prepare(str_replace('"$userid"','?',
550                                                                     $DBAuthParams['user_groups']));
551     }
552
553     /**
554      * Determines if the current user is a member of a database group.
555      * 
556      * @param string $group Name of the group to check for membership.
557      * @return boolean True if user is a member, else false.
558      */ 
559     function isMember($group) {
560         if ($this->specialGroup($group))
561             return WikiGroup::isMember($group);
562
563         $request = $this->request;
564         $username = $this->_getUserName();
565         if (isset($this->membership[$group])) {
566             return $this->membership[$group];
567         }
568         $dbh = _PassUser::getAuthDbh();
569         $db_result = $dbh->execute($this->_is_member,array($username,$group));
570         if ($db_result->numRows() > 0) {
571             $this->membership[$group] = true;
572             return true;
573         }
574         $this->membership[$group] = false;
575         return false;
576     }
577     
578     /**
579      * Determines all of the groups of which the current user is a member.
580      * 
581      * then checks each group to see if the current user is a member.
582      * @param string $group Name of the group to check for membership.
583      * @return array Array of groups to which the user belongs.
584      */ 
585     function getAllGroupsIn(){
586         $request = &$this->request;
587         $username = $this->_getUserName();
588         $membership = array();
589
590         $specialgroups = $this->specialGroups();
591         foreach ($specialgroups as $group) {
592             if ($this->isMember($group)) {
593                 $membership[] = $group;
594             }
595         }
596         $dbh = _PassUser::getAuthDbh();
597         $db_result = $dbh->execute($this->_user_groups,array($username));
598         if ($db_result->numRows() > 0) {
599             while (list($group) = $db_result->fetchRow()) {
600                 $membership[] = $group;
601             }
602         }
603         $this->membership = $membership;
604         return $membership;
605     }
606
607     /**
608      * Determines all of the members of a particular group.
609      * 
610      * Checks a group's page to return all the current members.  Currently this
611      * method is disabled and triggers an error and returns an empty array.
612      * @param string $group Name of the group to get the full membership list of.
613      * @return array Array of usernames that have joined the group.
614      */ 
615     function getMembersOf($group){
616         $request = &$this->request;
617         $username = $this->_getUserName();
618         $members = array();
619
620         $dbh = _PassUser::getAuthDbh();
621         $db_result = $dbh->execute($this->_group_members,array($group));
622         if ($db_result->numRows() > 0) {
623             while (list($userid) = $db_result->fetchRow()) {
624                 $members[] = $userid;
625             }
626         }
627         return $members;
628     }
629 }
630
631 /**
632  * GroupFile is configured by AUTH_GROUP_FILE
633  * groupname: user1 user2 ...
634  * 
635  * @author ReiniUrban
636  */ 
637 class GroupFile extends WikiGroup {
638     
639     /**
640      * Constructor
641      * 
642      * @param object $request The global WikiRequest object.
643      */ 
644     function GroupFile(&$request){
645         $this->request = &$request;
646         $this->username = null;
647         $this->membership = array();
648
649         if (!defined('AUTH_GROUP_FILE')) {
650             trigger_error(_("AUTH_GROUP_FILE not defined"), E_USER_WARNING);
651             return false;
652         }
653         if (!file_exists(AUTH_GROUP_FILE)) {
654             trigger_error(sprintf(_("Cannot open AUTH_GROUP_FILE %s"), AUTH_GROUP_FILE), E_USER_WARNING);
655             return false;
656         }
657         require 'lib/pear/File_Passwd.php';
658         $this->_file = File_Passwd($file);
659     }
660
661     /**
662      * Determines if the current user is a member of a group.
663      * 
664      * To determine membership in a particular group, this method checks the 
665      * superclass instance variable $membership to see if membership has 
666      * already been determined.  If not, then the group file is parsed to 
667      * determine membership.
668      * @param string $group Name of the group to check for membership.
669      * @return boolean True if user is a member, else false.
670      */ 
671     function isMember($group) {
672         if ($this->specialGroup($group))
673             return WikiGroup::isMember($group);
674
675         $request = $this->request;
676         $username = $this->_getUserName();
677         if (isset($this->membership[$group])) {
678             return $this->membership[$group];
679         }
680
681         foreach ($this->_file->users[] as $g => $u) {
682             $users = explode(' ',$u);
683             if (in_array($username,$users)) {
684                 $this->membership[$group] = true;
685                 return true;
686             }
687         }
688         $this->membership[$group] = false;
689         return false;
690     }
691     
692     /**
693      * Determines all of the groups of which the current user is a member.
694      * 
695      * then checks each group to see if the current user is a member.
696      * @param string $group Name of the group to check for membership.
697      * @return array Array of groups to which the user belongs.
698      */ 
699     function getAllGroupsIn(){
700         $username = $this->_getUserName();
701         $membership = array();
702
703         $specialgroups = $this->specialGroups();
704         foreach ($specialgroups as $group) {
705             if ($this->isMember($group)) {
706                 $this->membership[$group] = true;
707                 $membership[] = $group;
708             }
709         }
710         foreach ($this->_file->users[] as $group => $u) {
711             $users = explode(' ',$u);
712             if (in_array($username,$users)) {
713                 $this->membership[$group] = true;
714                 $membership[] = $group;
715             }
716         }
717         $this->membership = $membership;
718         return $membership;
719     }
720
721     /**
722      * Determines all of the members of a particular group.
723      * 
724      * Return all the current members.
725      * @param string $group Name of the group to get the full membership list of.
726      * @return array Array of usernames that have joined the group.
727      */ 
728     function getMembersOf($group){
729         if ($this->specialGroup($group)) {
730             trigger_error(__sprintf("Undefined method %s for special group %s",
731                                     'getMembersOf',$group),
732                           E_USER_WARNING);
733         } else {
734             if (!empty($this->_file->users[$group])) {
735                 return explode(' ',$this->_file->users[$group]);
736             }
737             return array();
738         }
739     }
740 }
741
742 /**
743  * Ldap is configured in index.php
744  * 
745  * @author ReiniUrban
746  */ 
747 class GroupLdap extends WikiGroup {
748     
749     /**
750      * Constructor
751      * 
752      * @param object $request The global WikiRequest object.
753      */ 
754     function GroupLdap(&$request){
755         $this->request = &$request;
756         $this->username = null;
757         $this->membership = array();
758
759         if (!defined("LDAP_AUTH_HOST")) {
760             trigger_error(_("LDAP_AUTH_HOST not defined"), E_USER_WARNING);
761             return false;
762         }
763         if (! function_exists('ldap_connect')) {
764             dl("ldap".DLL_EXT);
765             if (! function_exists('ldap_connect')) {
766                 trigger_error(_("No LDAP in this PHP version"), E_USER_WARNING);
767                 return false;
768             }
769         }
770         if (!defined("LDAP_BASE_DN"))
771             define("LDAP_BASE_DN",'');
772         $this->base_dn = LDAP_BASE_DN;
773         if (strstr("ou=",LDAP_BASE_DN))
774             $this->base_dn =  preg_replace("/(ou=\w+,)?()/","\$2",LDAP_BASE_DN);
775     }
776
777     /**
778      * Determines if the current user is a member of a group.
779      * Not ready yet!
780      * 
781      * @param string $group Name of the group to check for membership.
782      * @return boolean True if user is a member, else false.
783      */ 
784     function isMember($group) {
785         if ($this->specialGroup($group))
786             return WikiGroup::isMember($group);
787
788         if (isset($this->membership[$group])) {
789             return $this->membership[$group];
790         }
791         $request = $this->request;
792         $username = $this->_getUserName();
793
794         $this->membership[$group] = in_array($username,$this->getMembersOf($group));
795         return $this->membership[$group];
796     }
797     
798     /**
799      * Determines all of the groups of which the current user is a member.
800      *
801      * @param string $group Name of the group to check for membership.
802      * @return array Array of groups to which the user belongs.
803      */ 
804     function getAllGroupsIn(){
805         $request = &$this->request;
806         $username = $this->_getUserName();
807         $membership = array();
808
809         $specialgroups = $this->specialGroups();
810         foreach ($specialgroups as $group) {
811             if ($this->isMember($group)) {
812                 $this->membership[$group] = true;
813                 $membership[] = $group;
814             }
815         }
816         if ($ldap = ldap_connect(LDAP_AUTH_HOST)) { // must be a valid LDAP server!
817             $r = @ldap_bind($ldap);                 // this is an anonymous bind
818             $sr = ldap_search($ldap, "ou=Users,".$this->base_dn,"uid=$username");
819             $info = ldap_get_entries($ldap, $sr);
820             for ($i = 0; $i < $info["count"]; $i++) {
821                 if ($info[$i]["gidnumber"]["count"]) {
822                   $gid = $info[$i]["gidnumber"][0];
823                   $sr2 = ldap_search($ldap, "ou=Groups,".$this->base_dn,"gidNumber=$gid");
824                   $info2 = ldap_get_entries($ldap, $sr2);
825                   if ($info2["count"])
826                     $membership[] =  $info2[0]["cn"][0];
827                 }
828             }
829         }
830         ldap_close($ldap);
831         $this->membership = $membership;
832         return $membership;
833     }
834
835     /**
836      * Determines all of the members of a particular group.
837      * 
838      * Return all the members of the given group. LDAP just returns the gid of each user
839      * @param string $group Name of the group to get the full membership list of.
840      * @return array Array of usernames that have joined the group.
841      */ 
842     function getMembersOf($group){
843         $members = array();
844         if ($ldap = ldap_connect(LDAP_AUTH_HOST)) { // must be a valid LDAP server!
845             $r = @ldap_bind($ldap);                 // this is an anonymous bind
846             $sr = ldap_search($ldap, "ou=Groups,".$this->base_dn,"cn=$group");
847             $info = ldap_get_entries($ldap, $sr);
848             for ($i = 0; $i < $info["count"]; $i++) {
849                 $gid = $info[$i]["gidnumber"][0];
850                 $sr2 = ldap_search($ldap, "ou=Users,".$this->base_dn,"gidNumber=$gid");
851                 $info2 = ldap_get_entries($ldap, $sr2);
852                 for ($j = 0; $j < $info2["count"]; $j++) {
853                     $members[] = $info2[$j]["cn"][0];
854                 }
855             }
856         }
857         ldap_close($ldap);
858         return $members;
859     }
860 }
861
862 // $Log: not supported by cvs2svn $
863 // Revision 1.15  2004/03/09 12:11:57  rurban
864 // prevent from undefined DBAuthParams warning
865 //
866 // Revision 1.14  2004/03/08 19:30:01  rurban
867 // fixed Theme->getButtonURL
868 // AllUsers uses now WikiGroup (also DB User and DB Pref users)
869 // PageList fix for empty pagenames
870 //
871 // Revision 1.13  2004/03/08 18:17:09  rurban
872 // added more WikiGroup::getMembersOf methods, esp. for special groups
873 // fixed $LDAP_SET_OPTIONS
874 // fixed _AuthInfo group methods
875 //
876 // Revision 1.12  2004/02/23 21:30:25  rurban
877 // more PagePerm stuff: (working against 1.4.0)
878 //   ACL editing and simplification of ACL's to simple rwx------ string
879 //   not yet working.
880 //
881 // Revision 1.11  2004/02/07 10:41:25  rurban
882 // fixed auth from session (still double code but works)
883 // fixed GroupDB
884 // fixed DbPassUser upgrade and policy=old
885 // added GroupLdap
886 //
887 // Revision 1.10  2004/02/03 09:45:39  rurban
888 // LDAP cleanup, start of new Pref classes
889 //
890 // Revision 1.9  2004/02/01 09:14:11  rurban
891 // Started with Group_Ldap (not yet ready)
892 // added new _AuthInfo plugin to help in auth problems (warning: may display passwords)
893 // fixed some configurator vars
894 // renamed LDAP_AUTH_SEARCH to LDAP_BASE_DN
895 // changed PHPWIKI_VERSION from 1.3.8a to 1.3.8pre
896 // USE_DB_SESSION defaults to true on SQL
897 // changed GROUP_METHOD definition to string, not constants
898 // changed sample user DBAuthParams from UPDATE to REPLACE to be able to
899 //   create users. (Not to be used with external databases generally, but
900 //   with the default internal user table)
901 //
902 // fixed the IndexAsConfigProblem logic. this was flawed:
903 //   scripts which are the same virtual path defined their own lib/main call
904 //   (hmm, have to test this better, phpwiki.sf.net/demo works again)
905 //
906 // Revision 1.8  2004/01/27 23:23:39  rurban
907 // renamed ->Username => _userid for consistency
908 // renamed mayCheckPassword => mayCheckPass
909 // fixed recursion problem in WikiUserNew
910 // fixed bogo login (but not quite 100% ready yet, password storage)
911 //
912 // Revision 1.7  2004/01/26 16:52:40  rurban
913 // added GroupDB and GroupFile classes
914 //
915 // Revision 1.6  2003/12/07 19:29:11  carstenklapp
916 // Code Housecleaning: fixed syntax errors. (php -l *.php)
917 //
918 // Revision 1.5  2003/02/22 20:49:55  dairiki
919 // Fixes for "Call-time pass by reference has been deprecated" errors.
920 //
921 // Revision 1.4  2003/01/21 04:02:39  zorloc
922 // Added Log entry and page footer.
923 //
924
925 // Local Variables:
926 // mode: php
927 // tab-width: 8
928 // c-basic-offset: 4
929 // c-hanging-comment-ender-p: nil
930 // indent-tabs-mode: nil
931 // End:
932 ?>