2 rcs_id('$Id: WikiGroup.php,v 1.10 2004-02-03 09:45:39 rurban Exp $');
4 Copyright 2003, 2004 $ThePhpWikiProgrammingTeam
6 This file is part of PhpWiki.
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.
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.
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
23 // for now we provide no default memberhsip method. this might change.
24 // (!defined('GROUP_METHOD')) define('GROUP_METHOD', "WIKIPAGE");
26 if (!defined('GROUP_METHOD') or !in_array(GROUP_METHOD,array('NONE','WIKIPAGE','DB','FILE','LDAP')))
27 trigger_error(_("No or unsupported GROUP_METHOD defined"), E_USER_WARNING);
30 * WikiGroup is an abstract class to provide the base functions for determining
33 * WikiGroup is an abstract class with three functions:
34 * <ol><li />Provide the static method getGroup with will return the proper
36 * <li />Provide an interface for subclasses to implement.
37 * <li />Provide fallover methods (with error msgs) if not impemented in subclass.
39 * Do not ever instantiate this class use: $group = &WikiGroup::getGroup($request);
40 * This will instantiate the proper subclass.
41 * @author Joby Walker <zorloc@imperium.org>
46 /** The global WikiRequest object */
48 /** Array of groups $username is confirmed to belong to */
52 * Initializes a WikiGroup object which should never happen. Use:
53 * $group = &WikiGroup::getGroup($request);
54 * @param object $request The global WikiRequest object -- ignored.
56 function WikiGroup(&$request){
61 * Gets the current username and erases $this->membership if is different than
62 * the stored $this->username
63 * @return string Current username.
65 function _getUserName(){
66 $request = &$this->request;
67 $user = $request->getUser();
68 $username = $user->getID();
69 if ($username != $this->username) {
70 $this->membership = array();
71 $this->username = $username;
77 * Static method to return the WikiGroup subclass used in this wiki. Controlled
78 * by the constant GROUP_METHOD.
79 * @param object $request The global WikiRequest object.
80 * @return object Subclass of WikiGroup selected via GROUP_METHOD.
82 function getGroup($request){
83 switch (GROUP_METHOD){
85 return new GroupNone($request);
88 return new GroupWikiPage($request);
91 return new GroupDB($request);
94 return new GroupFile($request);
98 return new GroupLDAP($request);
102 trigger_error(_("No or unsupported GROUP_METHOD defined"), E_USER_WARNING);
103 return new WikiGroup($request);
108 * Determines if the current user is a member of a group.
110 * This method is an abstraction. The group is ignored, an error is sent, and
111 * false (not a member of the group) is returned.
112 * @param string $group Name of the group to check for membership (ignored).
113 * @return boolean True if user is a member, else false (always false).
115 function isMember($group){
116 trigger_error("Method 'isMember' not implemented in this GROUP_METHOD",
122 * Determines all of the groups of which the current user is a member.
124 * This method is an abstraction. An error is sent and an empty
126 * @return array Array of groups to which the user belongs (always empty).
128 function getAllGroupsIn(){
129 trigger_error("Method 'getAllGroupsIn' not implemented in this GROUP_METHOD",
135 * Determines all of the members of a particular group.
137 * This method is an abstraction. The group is ignored, an error is sent,
138 * and an empty array is returned
139 * @param string $group Name of the group to get the full membership list of.
140 * @return array Array of usernames that have joined the group (always empty).
142 function getMembersOf($group){
143 trigger_error("Method 'getMembersof' not implemented in this GROUP_METHOD",
149 * Add the current or specified user to a group.
151 * This method is an abstraction. The group and user are ignored, an error
152 * is sent, and false (not added) is always returned.
153 * @param string $group User added to this group.
154 * @param string $user Username to add to the group (default = current user).
155 * @return bool On true user was added, false if not.
157 function setMemberOf($group, $user = false){
158 trigger_error("Method 'setMemberOf' not implemented in this GROUP_METHOD",
164 * Remove the current or specified user to a group.
166 * This method is an abstraction. The group and user are ignored, and error
167 * is sent, and false (not removed) is always returned.
168 * @param string $group User removed from this group.
169 * @param string $user Username to remove from the group (default = current user).
170 * @return bool On true user was removed, false if not.
172 function removeMemberOf($group, $user = false){
173 trigger_error("Method 'removeMemberOf' not implemented in this GROUP_METHOD",
180 * GroupNone disables all Group funtionality
182 * All of the GroupNone functions return false or empty values to indicate failure or
183 * no results. Use GroupNone if group controls are not desired.
184 * @author Joby Walker <zorloc@imperium.org>
186 class GroupNone extends WikiGroup{
191 * Ignores the parameter provided.
192 * @param object $request The global WikiRequest object - ignored.
194 function GroupNone(&$request){
199 * Determines if the current user is a member of a group.
201 * The group is ignored and false (not a member of the group) is returned.
202 * @param string $group Name of the group to check for membership (ignored).
203 * @return boolean True if user is a member, else false (always false).
205 function isMember($group){
210 * Determines all of the groups of which the current user is a member.
212 * The group is ignored and an empty array (a member of no groups) is returned.
213 * @param string $group Name of the group to check for membership (ignored).
214 * @return array Array of groups to which the user belongs (always empty).
216 function getAllGroupsIn(){
221 * Determines all of the members of a particular group.
223 * The group is ignored and an empty array (a member of no groups) is returned.
224 * @param string $group Name of the group to check for membership (ignored).
225 * @return array Array of groups user belongs to (always empty).
227 function getMembersOf($group){
234 * GroupWikiPage provides group functionality via pages within the Wiki.
236 * GroupWikiPage is the Wiki way of managing a group. Every group will have
237 * a page. To modify the membership of the group, one only needs to edit the
238 * membership list on the page.
239 * @author Joby Walker <zorloc@imperium.org>
241 class GroupWikiPage extends WikiGroup{
246 * Initiallizes the three superclass instance variables
247 * @param object $request The global WikiRequest object.
249 function GroupWikiPage(&$request){
250 $this->request = &$request;
251 $this->username = null;
252 $this->membership = array();
256 * Determines if the current user is a member of a group.
258 * To determine membership in a particular group, this method checks the
259 * superclass instance variable $membership to see if membership has
260 * already been determined. If not, then the group page is parsed to
261 * determine membership.
262 * @param string $group Name of the group to check for membership.
263 * @return boolean True if user is a member, else false.
265 function isMember($group){
266 $request = $this->request;
267 $username = $this->_getUserName();
268 if (isset($this->membership[$group])) {
269 return $this->membership[$group];
271 $group_page = $request->getPage($group);
272 if ($this->_inGroupPage($group_page)) {
273 $this->membership[$group] = true;
276 $this->membership[$group] = false;
281 * Private method to take a WikiDB_Page and parse to determine if the
282 * current_user is a member of the group.
283 * @param object $group_page WikiDB_Page object for the group's page
284 * @return boolean True if user is a member, else false.
287 function _inGroupPage($group_page){
288 $group_revision = $group_page->getCurrentRevision();
289 if ($group_revision->hasDefaultContents()) {
290 $group = $group_page->getName();
291 trigger_error(sprintf(_("Group %s does not exist"),$group), E_USER_WARNING);
294 $contents = $group_revision->getContent();
295 $match = '/^\s*[\*\#]+\s*' . $username . '\s*$/';
296 foreach($contents as $line){
297 if (preg_match($match, $line)) {
305 * Determines all of the groups of which the current user is a member.
307 * Checks the root Group page ('CategoryGroup') for the list of all groups,
308 * then checks each group to see if the current user is a member.
309 * @param string $group Name of the group to check for membership.
310 * @return array Array of groups to which the user belongs.
312 function getAllGroupsIn(){
313 $request = &$this->request;
314 $username = $this->_getUserName();
315 $membership = array();
316 $dbh = &$request->getDbh();
317 $master_page = $request->getPage('CategoryGroup');
318 $master_list = $master_page->getLinks(true);
319 while($group_page = $master_list->next()){
320 if ($this->_inGroupPage($group_page)) {
321 $group = $group_page->getName();
322 $membership[$group] = true;
324 $membership[$group] = false;
327 $this->membership = $membership;
332 * Determines all of the members of a particular group.
334 * Checks a group's page to return all the current members. Currently this
335 * method is disabled and triggers an error and returns an empty array.
336 * @param string $group Name of the group to get the full membership list of.
337 * @return array Array of usernames that have joined the group (always empty).
339 function getMembersOf($group){
340 trigger_error("GroupWikiPage::getMembersof is not yet implimented",
344 * Waiting for a reliable way to check if a string is a username.
345 $request = $this->request;
347 $group_page = $request->getPage($group);
348 $group_revision = $group_page->getCurrentRevision();
349 if ($group_revision->hasDefaultContents()) {
350 trigger_error("Group $group does not exist", E_USER_WARNING);
353 $contents = $group_revision->getContent();
354 $match = '/^(\s*[\*\#]+\s*)(\w+)(\s*)$/';
356 foreach($contents as $line){
358 if(preg_match($match, $line, $matches)){
359 $members[] = $matches[2];
368 * GroupDb is configured by $DbAuthParams[] statements
372 class GroupDb extends WikiGroup {
377 * @param object $request The global WikiRequest object.
379 function GroupDb(&$request){
380 $this->request = &$request;
381 $this->username = null;
382 $this->membership = array();
384 if (empty($DBAuthParams['group_members']) or
385 empty($DBAuthParams['user_groups']) or
386 empty($DBAuthParams['is_member'])) {
387 trigger_error(_("No GROUP_DB SQL statements defined"), E_USER_WARNING);
390 $dbh = _PassUser::getAuthDbh();
391 $this->_is_member = $dbh->prepare(preg_replace(array('"$userid"','"$groupname"'),array('?','?'),$DBAuthParams['is_member']));
392 $this->_group_members = $dbh->prepare(preg_replace('"$groupname"','?',$DBAuthParams['group_members']));
393 $this->_user_groups = $dbh->prepare(preg_replace('"$userid"','?',$DBAuthParams['user_groups']));
397 * Determines if the current user is a member of a group.
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.
406 function isMember($group) {
407 $request = $this->request;
408 $username = $this->_getUserName();
409 if (isset($this->membership[$group])) {
410 return $this->membership[$group];
412 $dbh = _PassUser::getAuthDbh();
413 $db_result = $dbh->execute($this->_is_member,$username,$group);
414 if ($db_result->numRows() > 0) {
415 $this->membership[$group] = true;
418 $this->membership[$group] = false;
423 * Determines all of the groups of which the current user is a member.
425 * then checks each group to see if the current user is a member.
426 * @param string $group Name of the group to check for membership.
427 * @return array Array of groups to which the user belongs.
429 function getAllGroupsIn(){
430 $request = &$this->request;
431 $username = $this->_getUserName();
432 $membership = array();
434 $dbh = _PassUser::getAuthDbh();
435 $db_result = $dbh->execute($this->_user_groups,$username);
436 if ($db_result->numRows() > 0) {
437 while (list($group) = $db_result->fetchRow()) {
438 $membership[] = $group;
441 $this->membership = $membership;
446 * Determines all of the members of a particular group.
448 * Checks a group's page to return all the current members. Currently this
449 * method is disabled and triggers an error and returns an empty array.
450 * @param string $group Name of the group to get the full membership list of.
451 * @return array Array of usernames that have joined the group.
453 function getMembersOf($group){
454 $request = &$this->request;
455 $username = $this->_getUserName();
458 $dbh = _PassUser::getAuthDbh();
459 $db_result = $dbh->execute($this->_group_members,$group);
460 if ($db_result->numRows() > 0) {
461 while (list($userid) = $db_result->fetchRow()) {
462 $members[] = $userid;
470 * GroupFile is configured by AUTH_GROUP_FILE
471 * groupname: user1 user2 ...
475 class GroupFile extends WikiGroup {
480 * @param object $request The global WikiRequest object.
482 function GroupFile(&$request){
483 $this->request = &$request;
484 $this->username = null;
485 $this->membership = array();
487 if (!defined('AUTH_GROUP_FILE')) {
488 trigger_error(_("AUTH_GROUP_FILE not defined"), E_USER_WARNING);
491 if (!file_exists(AUTH_GROUP_FILE)) {
492 trigger_error(sprintf(_("Cannot open AUTH_GROUP_FILE %s"), AUTH_GROUP_FILE), E_USER_WARNING);
495 require 'lib/pear/File_Passwd.php';
496 $this->_file = File_Passwd($file);
500 * Determines if the current user is a member of a group.
502 * To determine membership in a particular group, this method checks the
503 * superclass instance variable $membership to see if membership has
504 * already been determined. If not, then the group file is parsed to
505 * determine membership.
506 * @param string $group Name of the group to check for membership.
507 * @return boolean True if user is a member, else false.
509 function isMember($group) {
510 $request = $this->request;
511 $username = $this->_getUserName();
512 if (isset($this->membership[$group])) {
513 return $this->membership[$group];
516 foreach ($this->_file->users[] as $g => $u) {
517 $users = explode(' ',$u);
518 if (in_array($username,$users)) {
519 $this->membership[$group] = true;
523 $this->membership[$group] = false;
528 * Determines all of the groups of which the current user is a member.
530 * then checks each group to see if the current user is a member.
531 * @param string $group Name of the group to check for membership.
532 * @return array Array of groups to which the user belongs.
534 function getAllGroupsIn(){
535 $request = &$this->request;
536 $username = $this->_getUserName();
537 $membership = array();
539 foreach ($this->_file->users[] as $group => $u) {
540 $users = explode(' ',$u);
541 if (in_array($username,$users)) {
542 $this->membership[$group] = true;
543 $membership[] = $group;
546 $this->membership = $membership;
551 * Determines all of the members of a particular group.
553 * Checks a group's page to return all the current members. Currently this
554 * method is disabled and triggers an error and returns an empty array.
555 * @param string $group Name of the group to get the full membership list of.
556 * @return array Array of usernames that have joined the group.
558 function getMembersOf($group){
559 $request = &$this->request;
560 $username = $this->_getUserName();
563 if (!empty($this->_file->users[$group])) {
564 return explode(' ',$this->_file->users[$group]);
571 * Ldap is configured in index.php
575 class GroupLdap extends WikiGroup {
580 * @param object $request The global WikiRequest object.
582 function GroupLdap(&$request){
583 $this->request = &$request;
584 $this->username = null;
585 $this->membership = array();
587 if (!defined("LDAP_AUTH_HOST")) {
588 trigger_error(_("LDAP_AUTH_HOST not defined"), E_USER_WARNING);
591 if (! function_exists('ldap_open')) {
593 if (! function_exists('ldap_open')) {
594 trigger_error(_("No LDAP in this PHP version"), E_USER_WARNING);
601 * Determines if the current user is a member of a group.
604 * @param string $group Name of the group to check for membership.
605 * @return boolean True if user is a member, else false.
607 function isMember($group) {
608 if (isset($this->membership[$group])) {
609 return $this->membership[$group];
611 $request = $this->request;
612 $username = $this->_getUserName();
613 if ($ldap = ldap_connect(LDAP_AUTH_HOST)) { // must be a valid LDAP server!
614 $r = @ldap_bind($ldap); // this is an anonymous bind
615 $st_search = "uid=$username member=$group";
616 $sr = ldap_search($ldap, LDAP_BASE_DN,
618 $info = ldap_get_entries($ldap, $sr);
619 if ($info["count"] > 0) {
621 $this->membership[$group] = true;
625 $this->membership[$group] = false;
630 * Determines all of the groups of which the current user is a member.
633 * @param string $group Name of the group to check for membership.
634 * @return array Array of groups to which the user belongs.
636 function getAllGroupsIn(){
637 $request = &$this->request;
638 $username = $this->_getUserName();
639 $membership = array();
641 if ($ldap = ldap_connect(LDAP_AUTH_HOST)) { // must be a valid LDAP server!
642 $r = @ldap_bind($ldap); // this is an anonymous bind
643 $st_search = "uid=$username";
644 $sr = ldap_search($ldap, LDAP_BASE_DN,
646 $info = ldap_get_entries($ldap, $sr); // there may be more hits with this userid. try every
647 for ($i = 0; $i < $info["count"]; $i++) {
648 $dn = $info[$i]["member"];
649 if ($r = @ldap_bind($ldap, $dn, $group)) {
650 $membership[] = $group;
655 $this->membership = $membership;
660 * Determines all of the members of a particular group.
662 * Checks a group's page to return all the current members. Currently this
663 * method is disabled and triggers an error and returns an empty array.
664 * @param string $group Name of the group to get the full membership list of.
665 * @return array Array of usernames that have joined the group.
667 function getMembersOf($group){
668 $request = &$this->request;
669 $username = $this->_getUserName();
672 $dbh = _PassUser::getAuthDbh();
673 $db_result = $dbh->execute($this->_group_members,$group);
674 if ($db_result->numRows() > 0) {
675 while (list($userid) = $db_result->fetchRow()) {
676 $members[] = $userid;
684 // $Log: not supported by cvs2svn $
685 // Revision 1.9 2004/02/01 09:14:11 rurban
686 // Started with Group_Ldap (not yet ready)
687 // added new _AuthInfo plugin to help in auth problems (warning: may display passwords)
688 // fixed some configurator vars
689 // renamed LDAP_AUTH_SEARCH to LDAP_BASE_DN
690 // changed PHPWIKI_VERSION from 1.3.8a to 1.3.8pre
691 // USE_DB_SESSION defaults to true on SQL
692 // changed GROUP_METHOD definition to string, not constants
693 // changed sample user DBAuthParams from UPDATE to REPLACE to be able to
694 // create users. (Not to be used with external databases generally, but
695 // with the default internal user table)
697 // fixed the IndexAsConfigProblem logic. this was flawed:
698 // scripts which are the same virtual path defined their own lib/main call
699 // (hmm, have to test this better, phpwiki.sf.net/demo works again)
701 // Revision 1.8 2004/01/27 23:23:39 rurban
702 // renamed ->Username => _userid for consistency
703 // renamed mayCheckPassword => mayCheckPass
704 // fixed recursion problem in WikiUserNew
705 // fixed bogo login (but not quite 100% ready yet, password storage)
707 // Revision 1.7 2004/01/26 16:52:40 rurban
708 // added GroupDB and GroupFile classes
710 // Revision 1.6 2003/12/07 19:29:11 carstenklapp
711 // Code Housecleaning: fixed syntax errors. (php -l *.php)
713 // Revision 1.5 2003/02/22 20:49:55 dairiki
714 // Fixes for "Call-time pass by reference has been deprecated" errors.
716 // Revision 1.4 2003/01/21 04:02:39 zorloc
717 // Added Log entry and page footer.
724 // c-hanging-comment-ender-p: nil
725 // indent-tabs-mode: nil