]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiGroup.php
added more WikiGroup::getMembersOf methods, esp. for special groups
[SourceForge/phpwiki.git] / lib / WikiGroup.php
1 <?php
2 rcs_id('$Id: WikiGroup.php,v 1.13 2004-03-08 18:17:09 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 ($GLOBALS['DBAuthParams']['pref_select']) {
195             //get prefs table
196             $sql = str_replace(' prefs ',' userid ',$GLOBALS['DBAuthParams']['pref_select']);
197             $sql = preg_replace('/WHERE.*/i','',$sql);
198             if ($GLOBALS['DBParams']['dbtype'] == 'ADODB') {
199                 $db_result = $dbi->Execute($sql);
200                 $users = array_merge($users,$db_result->GetArray());
201             } elseif ($GLOBALS['DBParams']['dbtype'] == 'SQL') {
202                 $users = array_merge($users,$dbi->getCol($sql));
203             }
204         }
205         return $users;
206     }
207
208     /**
209      * Determines all of the members of a particular group.
210      * 
211      * This method is an abstraction.  The group is ignored, an error is sent, 
212      * and an empty array is returned
213      * @param string $group Name of the group to get the full membership list of.
214      * @return array Array of usernames that have joined the group (always empty).
215      */ 
216     function getMembersOf($group){
217         if ($this->specialGroup($group)) {
218             $request = &$this->request;
219             $all = $this->_allUsers();
220             $users = array();
221             switch ($group) {
222             case GROUP_EVERY:           
223                 return $all;
224             case GROUP_ANONYMOUS:       
225                 return $users;
226             case GROUP_BOGOUSERS:       
227                 foreach ($all as $u) {
228                     if (isWikiWord($user)) $users[] = $u;
229                 }
230                 return $users;
231             case GROUP_SIGNED:          
232                 foreach ($all as $u) {
233                     $user = WikiUser($u);
234                     if ($user->isSignedIn()) $users[] = $u;
235                 }
236                 return $users;
237             case GROUP_AUTHENTICATED:
238                 foreach ($all as $u) {
239                     $user = WikiUser($u);
240                     if ($user->isAuthenticated()) $users[] = $u;
241                 }
242                 return $users;
243             case GROUP_ADMIN:           
244                 foreach ($all as $u) {
245                     $user = WikiUser($u);
246                     if ($user->isAdmin()) $users[] = $u;
247                 }
248                 return $users;
249             default:
250                 trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
251                                         'getMembersOf',GROUP_METHOD),
252                               E_USER_WARNING);
253             }
254         }
255         trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
256                                 'getMembersOf',GROUP_METHOD),
257                       E_USER_WARNING);
258         return array();
259     }
260
261     /**
262      * Add the current or specified user to a group.
263      * 
264      * This method is an abstraction.  The group and user are ignored, an error 
265      * is sent, and false (not added) is always returned.
266      * @param string $group User added to this group.
267      * @param string $user Username to add to the group (default = current user).
268      * @return bool On true user was added, false if not.
269      */ 
270     function setMemberOf($group, $user = false){
271         trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
272                                 'setMemberOf',GROUP_METHOD),
273                       E_USER_WARNING);
274         return false;
275     }
276     
277     /**
278      * Remove the current or specified user to a group.
279      * 
280      * This method is an abstraction.  The group and user are ignored, and error
281      * is sent, and false (not removed) is always returned.
282      * @param string $group User removed from this group.
283      * @param string $user Username to remove from the group (default = current user).
284      * @return bool On true user was removed, false if not.
285      */ 
286     function removeMemberOf($group, $user = false){
287         trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
288                                 'removeMemberOf',GROUP_METHOD),
289                       E_USER_WARNING);
290         return false;
291     }
292 }
293
294 /**
295  * GroupNone disables all Group funtionality
296  * 
297  * All of the GroupNone functions return false or empty values to indicate failure or 
298  * no results.  Use GroupNone if group controls are not desired.
299  * @author Joby Walker <zorloc@imperium.org>
300  */ 
301 class GroupNone extends WikiGroup{
302
303     /**
304      * Constructor
305      * 
306      * Ignores the parameter provided.
307      * @param object $request The global WikiRequest object - ignored.
308      */ 
309     function GroupNone(&$request){
310         return;
311     }    
312
313     /**
314      * Determines if the current user is a member of a group.
315      * 
316      * The group is ignored and false (not a member of the group) is returned.
317      * @param string $group Name of the group to check for membership (ignored).
318      * @return boolean True if user is a member, else false (always false).
319      */ 
320     function isMember($group){
321         if ($this->specialGroup($group)) {
322             return WikiGroup::isMember($group);
323         } else {
324             return false;
325         }
326     }
327     
328     /**
329      * Determines all of the groups of which the current user is a member.
330      * 
331      * The group is ignored and an empty array (a member of no groups) is returned.
332      * @param string $group Name of the group to check for membership (ignored).
333      * @return array Array of groups to which the user belongs (always empty).
334      */ 
335     function getAllGroupsIn(){
336         return array();
337     }
338
339     /**
340      * Determines all of the members of a particular group.
341      * 
342      * The group is ignored and an empty array (a member of no groups) is returned.
343      * @param string $group Name of the group to check for membership (ignored).
344      * @return array Array of groups user belongs to (always empty).
345      */ 
346     function getMembersOf($group){
347         return array();
348     }
349
350 }
351
352 /**
353  * GroupWikiPage provides group functionality via pages within the Wiki.
354  * 
355  * GroupWikiPage is the Wiki way of managing a group.  Every group will have 
356  * a page. To modify the membership of the group, one only needs to edit the 
357  * membership list on the page.
358  * @author Joby Walker <zorloc@imperium.org>
359  */ 
360 class GroupWikiPage extends WikiGroup{
361     
362     /**
363      * Constructor
364      * 
365      * Initializes the three superclass instance variables
366      * @param object $request The global WikiRequest object.
367      */ 
368     function GroupWikiPage(&$request){
369         $this->request = &$request;
370         $this->username = $this->_getUserName();
371         //$this->username = null;
372         $this->membership = array();
373     }
374
375     /**
376      * Determines if the current user is a member of a group.
377      * 
378      * To determine membership in a particular group, this method checks the 
379      * superclass instance variable $membership to see if membership has 
380      * already been determined.  If not, then the group page is parsed to 
381      * determine membership.
382      * @param string $group Name of the group to check for membership.
383      * @return boolean True if user is a member, else false.
384      */ 
385     function isMember($group){
386         if ($this->specialGroup($group))
387             return WikiGroup::isMember($group);
388
389         $request = $this->request;
390         //$username = $this->_getUserName();
391         if (isset($this->membership[$group])) {
392             return $this->membership[$group];
393         }
394         $group_page = $request->getPage($group);
395         if ($this->_inGroupPage($group_page)) {
396             $this->membership[$group] = true;
397             return true;
398         }
399         $this->membership[$group] = false;
400         return false;
401     }
402     
403     /**
404     * Private method to take a WikiDB_Page and parse to determine if the
405     * current_user is a member of the group.
406     * @param object $group_page WikiDB_Page object for the group's page
407     * @return boolean True if user is a member, else false.
408     * @access private
409     */
410     function _inGroupPage($group_page){
411         $group_revision = $group_page->getCurrentRevision();
412         if ($group_revision->hasDefaultContents()) {
413             $group = $group_page->getName();
414             trigger_error(sprintf(_("Group %s does not exist"),$group), E_USER_WARNING);
415             return false;
416         }
417         $contents = $group_revision->getContent();
418         $match = '/^\s*[\*\#]+\s*' . $this->username . '\s*$/';
419         foreach ($contents as $line){
420             if (preg_match($match, $line)) {
421                 return true;
422             }
423         }
424         return false;
425     }
426     
427     /**
428      * Determines all of the groups of which the current user is a member.
429      * 
430      * Checks the root Group page ('CategoryGroup') for the list of all groups, 
431      * then checks each group to see if the current user is a member.
432      * @param string $group Name of the group to check for membership.
433      * @return array Array of groups to which the user belongs.
434      */ 
435     function getAllGroupsIn(){
436         $request = &$this->request;
437         //$username = $this->_getUserName();
438         $membership = array();
439
440         $specialgroups = $this->specialGroups();
441         foreach ($specialgroups as $group) {
442             $this->membership[$group] = $this->isMember($group);
443         }
444
445         $dbh = &$request->getDbh();
446         $master_page = $request->getPage(_("CategoryGroup"));
447         $master_list = $master_page->getLinks(true);
448         while ($group_page = $master_list->next()){
449             $group = $group_page->getName();
450             $this->membership[$group] = $this->_inGroupPage($group_page);
451         }
452         foreach ($this->membership as $g => $bool) {
453             if ($bool) $membership[] = $g;
454         }
455         return $membership;
456     }
457
458     /**
459      * Determines all of the members of a particular group.
460      * 
461      * Checks a group's page to return all the current members.  Currently this
462      * method is disabled and triggers an error and returns an empty array.
463      * @param string $group Name of the group to get the full membership list of.
464      * @return array Array of usernames that have joined the group (always empty).
465      */ 
466     function getMembersOf($group){
467         if ($this->specialGroup($group))
468             return WikiGroup::getMembersOf($group);
469
470         trigger_error("GroupWikiPage::getMembersOf is not yet implimented",
471                       E_USER_WARNING);
472         return array();
473         /*
474         * Waiting for a reliable way to check if a string is a username.
475         $request = $this->request;
476         $user = $this->user;
477         $group_page = $request->getPage($group);
478         $group_revision = $group_page->getCurrentRevision();
479         if ($group_revision->hasDefaultContents()) {
480             trigger_error("Group $group does not exist", E_USER_WARNING);
481             return false;
482         }
483         $contents = $group_revision->getContent();
484         $match = '/^(\s*[\*\#]+\s*)(\w+)(\s*)$/';
485         $members = array();
486         foreach($contents as $line){
487             $matches = array();
488             if(preg_match($match, $line, $matches)){
489                 $members[] = $matches[2];
490             }
491         }
492         return $members;
493         */
494     }
495 }
496
497 /**
498  * GroupDb is configured by $DbAuthParams[] statements
499  * 
500  * @author ReiniUrban
501  */ 
502 class GroupDb extends WikiGroup {
503     
504     var $_is_member, $_group_members, $_user_groups;
505     /**
506      * Constructor
507      * 
508      * @param object $request The global WikiRequest object.
509      */ 
510     function GroupDb(&$request){
511         global $DBAuthParams;
512         $this->request = &$request;
513         $this->username = $this->_getUserName();
514         //$this->membership = array();
515
516         if (empty($DBAuthParams['group_members']) or 
517             empty($DBAuthParams['user_groups']) or
518             empty($DBAuthParams['is_member'])) {
519             trigger_error(_("No or not enough GROUP_DB SQL statements defined"), E_USER_WARNING);
520             return false;
521         }
522         _PassUser::getAuthDbh();
523         $this->_is_member = $this->_auth_dbi->prepare(str_replace(array('"$userid"','"$groupname"'),array('?','?'),$DBAuthParams['is_member']));
524         $this->_group_members = $this->_auth_dbi->prepare(str_replace('"$groupname"','?',$DBAuthParams['group_members']));
525         $this->_user_groups = $this->_auth_dbi->prepare(str_replace('"$userid"','?',$DBAuthParams['user_groups']));
526     }
527
528     /**
529      * Determines if the current user is a member of a database group.
530      * 
531      * @param string $group Name of the group to check for membership.
532      * @return boolean True if user is a member, else false.
533      */ 
534     function isMember($group) {
535         if ($this->specialGroup($group))
536             return WikiGroup::isMember($group);
537
538         $request = $this->request;
539         $username = $this->_getUserName();
540         if (isset($this->membership[$group])) {
541             return $this->membership[$group];
542         }
543         $dbh = _PassUser::getAuthDbh();
544         $db_result = $dbh->execute($this->_is_member,array($username,$group));
545         if ($db_result->numRows() > 0) {
546             $this->membership[$group] = true;
547             return true;
548         }
549         $this->membership[$group] = false;
550         return false;
551     }
552     
553     /**
554      * Determines all of the groups of which the current user is a member.
555      * 
556      * then checks each group to see if the current user is a member.
557      * @param string $group Name of the group to check for membership.
558      * @return array Array of groups to which the user belongs.
559      */ 
560     function getAllGroupsIn(){
561         $request = &$this->request;
562         $username = $this->_getUserName();
563         $membership = array();
564
565         $specialgroups = $this->specialGroups();
566         foreach ($specialgroups as $group) {
567             if ($this->isMember($group)) {
568                 $membership[] = $group;
569             }
570         }
571         $dbh = _PassUser::getAuthDbh();
572         $db_result = $dbh->execute($this->_user_groups,$username);
573         if ($db_result->numRows() > 0) {
574             while (list($group) = $db_result->fetchRow()) {
575                 $membership[] = $group;
576             }
577         }
578         $this->membership = $membership;
579         return $membership;
580     }
581
582     /**
583      * Determines all of the members of a particular group.
584      * 
585      * Checks a group's page to return all the current members.  Currently this
586      * method is disabled and triggers an error and returns an empty array.
587      * @param string $group Name of the group to get the full membership list of.
588      * @return array Array of usernames that have joined the group.
589      */ 
590     function getMembersOf($group){
591         $request = &$this->request;
592         $username = $this->_getUserName();
593         $members = array();
594
595         $dbh = _PassUser::getAuthDbh();
596         $db_result = $dbh->execute($this->_group_members,$group);
597         if ($db_result->numRows() > 0) {
598             while (list($userid) = $db_result->fetchRow()) {
599                 $members[] = $userid;
600             }
601         }
602         return $members;
603     }
604 }
605
606 /**
607  * GroupFile is configured by AUTH_GROUP_FILE
608  * groupname: user1 user2 ...
609  * 
610  * @author ReiniUrban
611  */ 
612 class GroupFile extends WikiGroup {
613     
614     /**
615      * Constructor
616      * 
617      * @param object $request The global WikiRequest object.
618      */ 
619     function GroupFile(&$request){
620         $this->request = &$request;
621         $this->username = null;
622         $this->membership = array();
623
624         if (!defined('AUTH_GROUP_FILE')) {
625             trigger_error(_("AUTH_GROUP_FILE not defined"), E_USER_WARNING);
626             return false;
627         }
628         if (!file_exists(AUTH_GROUP_FILE)) {
629             trigger_error(sprintf(_("Cannot open AUTH_GROUP_FILE %s"), AUTH_GROUP_FILE), E_USER_WARNING);
630             return false;
631         }
632         require 'lib/pear/File_Passwd.php';
633         $this->_file = File_Passwd($file);
634     }
635
636     /**
637      * Determines if the current user is a member of a group.
638      * 
639      * To determine membership in a particular group, this method checks the 
640      * superclass instance variable $membership to see if membership has 
641      * already been determined.  If not, then the group file is parsed to 
642      * determine membership.
643      * @param string $group Name of the group to check for membership.
644      * @return boolean True if user is a member, else false.
645      */ 
646     function isMember($group) {
647         if ($this->specialGroup($group))
648             return WikiGroup::isMember($group);
649
650         $request = $this->request;
651         $username = $this->_getUserName();
652         if (isset($this->membership[$group])) {
653             return $this->membership[$group];
654         }
655
656         foreach ($this->_file->users[] as $g => $u) {
657             $users = explode(' ',$u);
658             if (in_array($username,$users)) {
659                 $this->membership[$group] = true;
660                 return true;
661             }
662         }
663         $this->membership[$group] = false;
664         return false;
665     }
666     
667     /**
668      * Determines all of the groups of which the current user is a member.
669      * 
670      * then checks each group to see if the current user is a member.
671      * @param string $group Name of the group to check for membership.
672      * @return array Array of groups to which the user belongs.
673      */ 
674     function getAllGroupsIn(){
675         $username = $this->_getUserName();
676         $membership = array();
677
678         $specialgroups = $this->specialGroups();
679         foreach ($specialgroups as $group) {
680             if ($this->isMember($group)) {
681                 $this->membership[$group] = true;
682                 $membership[] = $group;
683             }
684         }
685         foreach ($this->_file->users[] as $group => $u) {
686             $users = explode(' ',$u);
687             if (in_array($username,$users)) {
688                 $this->membership[$group] = true;
689                 $membership[] = $group;
690             }
691         }
692         $this->membership = $membership;
693         return $membership;
694     }
695
696     /**
697      * Determines all of the members of a particular group.
698      * 
699      * Return all the current members.
700      * @param string $group Name of the group to get the full membership list of.
701      * @return array Array of usernames that have joined the group.
702      */ 
703     function getMembersOf($group){
704         if ($this->specialGroup($group)) {
705             trigger_error(__sprintf("Undefined method %s for special group %s",
706                                     'getMembersOf',$group),
707                           E_USER_WARNING);
708         } else {
709             if (!empty($this->_file->users[$group])) {
710                 return explode(' ',$this->_file->users[$group]);
711             }
712             return array();
713         }
714     }
715 }
716
717 /**
718  * Ldap is configured in index.php
719  * 
720  * @author ReiniUrban
721  */ 
722 class GroupLdap extends WikiGroup {
723     
724     /**
725      * Constructor
726      * 
727      * @param object $request The global WikiRequest object.
728      */ 
729     function GroupLdap(&$request){
730         $this->request = &$request;
731         $this->username = null;
732         $this->membership = array();
733
734         if (!defined("LDAP_AUTH_HOST")) {
735             trigger_error(_("LDAP_AUTH_HOST not defined"), E_USER_WARNING);
736             return false;
737         }
738         if (! function_exists('ldap_connect')) {
739             dl("ldap".DLL_EXT);
740             if (! function_exists('ldap_connect')) {
741                 trigger_error(_("No LDAP in this PHP version"), E_USER_WARNING);
742                 return false;
743             }
744         }
745         if (!defined("LDAP_BASE_DN"))
746             define("LDAP_BASE_DN",'');
747         $this->base_dn = LDAP_BASE_DN;
748         if (strstr("ou=",LDAP_BASE_DN))
749             $this->base_dn =  preg_replace("/(ou=\w+,)?()/","\$2",LDAP_BASE_DN);
750     }
751
752     /**
753      * Determines if the current user is a member of a group.
754      * Not ready yet!
755      * 
756      * @param string $group Name of the group to check for membership.
757      * @return boolean True if user is a member, else false.
758      */ 
759     function isMember($group) {
760         if ($this->specialGroup($group))
761             return WikiGroup::isMember($group);
762
763         if (isset($this->membership[$group])) {
764             return $this->membership[$group];
765         }
766         $request = $this->request;
767         $username = $this->_getUserName();
768
769         $this->membership[$group] = in_array($username,$this->getMembersOf($group));
770         return $this->membership[$group];
771     }
772     
773     /**
774      * Determines all of the groups of which the current user is a member.
775      *
776      * @param string $group Name of the group to check for membership.
777      * @return array Array of groups to which the user belongs.
778      */ 
779     function getAllGroupsIn(){
780         $request = &$this->request;
781         $username = $this->_getUserName();
782         $membership = array();
783
784         $specialgroups = $this->specialGroups();
785         foreach ($specialgroups as $group) {
786             if ($this->isMember($group)) {
787                 $this->membership[$group] = true;
788                 $membership[] = $group;
789             }
790         }
791         if ($ldap = ldap_connect(LDAP_AUTH_HOST)) { // must be a valid LDAP server!
792             $r = @ldap_bind($ldap);                 // this is an anonymous bind
793             $sr = ldap_search($ldap, "ou=Users,".$this->base_dn,"uid=$username");
794             $info = ldap_get_entries($ldap, $sr);
795             for ($i = 0; $i < $info["count"]; $i++) {
796                 if ($info[$i]["gidnumber"]["count"]) {
797                   $gid = $info[$i]["gidnumber"][0];
798                   $sr2 = ldap_search($ldap, "ou=Groups,".$this->base_dn,"gidNumber=$gid");
799                   $info2 = ldap_get_entries($ldap, $sr2);
800                   if ($info2["count"])
801                     $membership[] =  $info2[0]["cn"][0];
802                 }
803             }
804         }
805         ldap_close($ldap);
806         $this->membership = $membership;
807         return $membership;
808     }
809
810     /**
811      * Determines all of the members of a particular group.
812      * 
813      * Return all the members of the given group. LDAP just returns the gid of each user
814      * @param string $group Name of the group to get the full membership list of.
815      * @return array Array of usernames that have joined the group.
816      */ 
817     function getMembersOf($group){
818         $members = array();
819         if ($ldap = ldap_connect(LDAP_AUTH_HOST)) { // must be a valid LDAP server!
820             $r = @ldap_bind($ldap);                 // this is an anonymous bind
821             $sr = ldap_search($ldap, "ou=Groups,".$this->base_dn,"cn=$group");
822             $info = ldap_get_entries($ldap, $sr);
823             for ($i = 0; $i < $info["count"]; $i++) {
824                 $gid = $info[$i]["gidnumber"][0];
825                 $sr2 = ldap_search($ldap, "ou=Users,".$this->base_dn,"gidNumber=$gid");
826                 $info2 = ldap_get_entries($ldap, $sr2);
827                 for ($j = 0; $j < $info2["count"]; $j++) {
828                     $members[] = $info2[$j]["cn"][0];
829                 }
830             }
831         }
832         ldap_close($ldap);
833         return $members;
834     }
835 }
836
837 // $Log: not supported by cvs2svn $
838 // Revision 1.12  2004/02/23 21:30:25  rurban
839 // more PagePerm stuff: (working against 1.4.0)
840 //   ACL editing and simplification of ACL's to simple rwx------ string
841 //   not yet working.
842 //
843 // Revision 1.11  2004/02/07 10:41:25  rurban
844 // fixed auth from session (still double code but works)
845 // fixed GroupDB
846 // fixed DbPassUser upgrade and policy=old
847 // added GroupLdap
848 //
849 // Revision 1.10  2004/02/03 09:45:39  rurban
850 // LDAP cleanup, start of new Pref classes
851 //
852 // Revision 1.9  2004/02/01 09:14:11  rurban
853 // Started with Group_Ldap (not yet ready)
854 // added new _AuthInfo plugin to help in auth problems (warning: may display passwords)
855 // fixed some configurator vars
856 // renamed LDAP_AUTH_SEARCH to LDAP_BASE_DN
857 // changed PHPWIKI_VERSION from 1.3.8a to 1.3.8pre
858 // USE_DB_SESSION defaults to true on SQL
859 // changed GROUP_METHOD definition to string, not constants
860 // changed sample user DBAuthParams from UPDATE to REPLACE to be able to
861 //   create users. (Not to be used with external databases generally, but
862 //   with the default internal user table)
863 //
864 // fixed the IndexAsConfigProblem logic. this was flawed:
865 //   scripts which are the same virtual path defined their own lib/main call
866 //   (hmm, have to test this better, phpwiki.sf.net/demo works again)
867 //
868 // Revision 1.8  2004/01/27 23:23:39  rurban
869 // renamed ->Username => _userid for consistency
870 // renamed mayCheckPassword => mayCheckPass
871 // fixed recursion problem in WikiUserNew
872 // fixed bogo login (but not quite 100% ready yet, password storage)
873 //
874 // Revision 1.7  2004/01/26 16:52:40  rurban
875 // added GroupDB and GroupFile classes
876 //
877 // Revision 1.6  2003/12/07 19:29:11  carstenklapp
878 // Code Housecleaning: fixed syntax errors. (php -l *.php)
879 //
880 // Revision 1.5  2003/02/22 20:49:55  dairiki
881 // Fixes for "Call-time pass by reference has been deprecated" errors.
882 //
883 // Revision 1.4  2003/01/21 04:02:39  zorloc
884 // Added Log entry and page footer.
885 //
886
887 // Local Variables:
888 // mode: php
889 // tab-width: 8
890 // c-basic-offset: 4
891 // c-hanging-comment-ender-p: nil
892 // indent-tabs-mode: nil
893 // End:
894 ?>