2 rcs_id('$Id: PagePerm.php,v 1.31 2004-09-25 18:34:45 rurban Exp $');
4 Copyright 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
24 Permissions per page and action based on current user,
25 ownership and group membership implemented with ACL's (Access Control Lists),
26 opposed to the simplier unix like ugo:rwx system.
27 The previous system was only based on action and current user. (lib/main.php)
29 Permissions may be inherited from its parent pages, a optional the
30 optional master page ("."), and predefined default permissions, if "."
32 Pagenames starting with "." have special default permissions.
33 For Authentication see WikiUserNew.php, WikiGroup.php and main.php
34 Page Permissions are in PhpWiki since v1.3.9 and enabled since v1.4.0
36 This file might replace the following functions from main.php:
37 Request::_notAuthorized($require_level)
38 display the denied message and optionally a login form
39 to gain higher privileges
40 Request::getActionDescription($action)
41 helper to localize the _notAuthorized message per action,
43 Request::getDisallowedActionDescription($action)
44 helper to localize the _notAuthorized message per action,
46 Request::requiredAuthority($action)
47 returns the needed user level
48 has a hook for plugins on POST
49 Request::requiredAuthorityForAction($action)
50 just returns the level per action, will be replaced with the
53 The defined main.php actions map to simplier access types:
56 create => edit or create
60 list in PageList => list
63 /* Symbolic special ACL groups. Untranslated to be stored in page metadata*/
64 define('ACL_EVERY', '_EVERY');
65 define('ACL_ANONYMOUS', '_ANONYMOUS');
66 define('ACL_BOGOUSER', '_BOGOUSER');
67 define('ACL_HASHOMEPAGE', '_HASHOMEPAGE');
68 define('ACL_SIGNED', '_SIGNED');
69 define('ACL_AUTHENTICATED','_AUTHENTICATED');
70 define('ACL_ADMIN', '_ADMIN');
71 define('ACL_OWNER', '_OWNER');
72 define('ACL_CREATOR', '_CREATOR');
74 // Return an page permissions array for this page.
75 // To provide ui helpers to view and change page permissions:
76 // <tr><th>Group</th><th>Access</th><th>Allow or Forbid</th></tr>
77 // <tr><td>$group</td><td>_($access)</td><td> [ ] </td></tr>
78 function pagePermissions($pagename) {
80 $page = $request->getPage($pagename);
81 // Page not found (new page); returned inherited permissions, to be displayed in gray
82 if (! $page->exists() ) {
83 if ($pagename == '.') // stop recursion
84 return array('default',new PagePermission());
86 return array('inherited',pagePermissions(getParentPage($pagename)));
88 } elseif ($perm = getPagePermissions($page)) {
89 return array('page',$perm);
90 // or no permissions defined; returned inherited permissions, to be displayed in gray
92 return array('inherited',pagePermissions(getParentPage($pagename)));
96 function pagePermissionsSimpleFormat($perm_tree, $owner, $group=false) {
97 list($type,$perm) = pagePermissionsAcl($perm_tree[0], $perm_tree);
99 $type = $perm_tree[0];
100 $perm = pagePermissionsAcl($perm_tree);
101 if (is_object($perm_tree[1]))
102 $perm = $perm_tree[1];
103 elseif (is_array($perm_tree[1])) {
104 $perm_tree = pagePermissionsSimpleFormat($perm_tree[1],$owner,$group);
105 if (isa($perm_tree[1],'pagepermission'))
106 $perm = $perm_tree[1];
107 elseif (isa($perm_tree,'htmlelement'))
112 return HTML::tt(HTML::strong($perm->asRwxString($owner, $group)));
113 elseif ($type == 'default')
114 return HTML::tt($perm->asRwxString($owner, $group));
115 elseif ($type == 'inherited') {
116 return HTML::tt(array('class'=>'inherited', 'style'=>'color:#aaa;'),
117 $perm->asRwxString($owner, $group));
121 function pagePermissionsAcl($type,$perm_tree) {
122 $perm = $perm_tree[1];
123 while (!is_object($perm)) {
124 $perm_tree = pagePermissionsAcl($type, $perm);
125 $perm = $perm_tree[1];
127 return array($type,$perm);
132 function pagePermissionsAclFormat($perm_tree, $editable=false) {
133 list($type,$perm) = pagePermissionsAcl($perm_tree[0], $perm_tree);
135 return $perm->asEditableTable($type);
137 return $perm->asTable($type);
141 * Check permission per page.
142 * Returns true or false.
144 function mayAccessPage ($access, $pagename) {
146 return _requiredAuthorityForPagename($access, $pagename);
152 * Check the permissions for the current action.
153 * Walk down the inheritance tree. Collect all permissions until
154 * the minimum required level is gained, which is not
155 * overruled by more specific forbid rules.
156 * Todo: cache result per access and page in session?
158 function requiredAuthorityForPage ($action) {
160 $auth = _requiredAuthorityForPagename(action2access($action),
161 $request->getArg('pagename'));
162 assert($auth !== -1);
164 return $request->_user->_level;
166 return WIKIAUTH_UNOBTAINABLE;
169 // Translate action or plugin to the simplier access types:
170 function action2access ($action) {
190 $page = $request->getPage();
191 if (!$page->exists())
198 // probably create/edit but we cannot check all page permissions, can we?
208 //Todo: Plugins should be able to override its access type
209 if (isWikiWord($action))
217 // Recursive helper to do the real work
218 function _requiredAuthorityForPagename($access, $pagename) {
220 $page = $request->getPage($pagename);
221 // Page not found; check against default permissions
222 if (! $page->exists() ) {
223 $perm = new PagePermission();
224 return ($perm->isAuthorized($access, $request->_user) === true);
226 // no ACL defined; check for special dotfile or walk down
227 if (! ($perm = getPagePermissions($page))) {
228 if ($pagename == '.') {
229 trigger_error(". (dotpage == rootpage for inheriting pageperm ACLs) exists without any ACL!\n".
230 "Please do ?action=setacl&pagename=.", E_USER_WARNING);
231 $perm = new PagePermission();
232 return ($perm->isAuthorized($access, $request->_user) === true);
233 } elseif ($pagename[0] == '.') {
234 $perm = new PagePermission(PagePermission::dotPerms());
235 return ($perm->isAuthorized($access, $request->_user) === true);
237 return _requiredAuthorityForPagename($access, getParentPage($pagename));
239 // ACL defined; check if isAuthorized returns true or false or undecided
240 $authorized = $perm->isAuthorized($access, $request->_user);
241 if ($authorized !== -1) // interestingly true is also -1
244 return _requiredAuthorityForPagename($access, getParentPage($pagename));
248 * @param string $pagename page from which the parent page is searched.
249 * @return string parent pagename or the (possibly pseudo) dot-pagename.
251 function getParentPage($pagename) {
252 if (isSubPage($pagename)) {
253 return subPageSlice($pagename,0);
259 // Read the ACL from the page
260 // Done: Not existing pages should NOT be queried.
261 // Check the parent page instead and don't take the default ACL's
262 function getPagePermissions ($page) {
263 if ($hash = $page->get('perm')) // hash => object
264 return new PagePermission(unserialize($hash));
269 // Store the ACL in the page
270 function setPagePermissions ($page,$perm) {
274 function getAccessDescription($access) {
275 static $accessDescriptions;
276 if (! $accessDescriptions) {
277 $accessDescriptions = array(
278 'list' => _("List this page and all subpages"),
279 'view' => _("View this page and all subpages"),
280 'edit' => _("Edit this page and all subpages"),
281 'create' => _("Create a new (sub)page"),
282 'dump' => _("Download the page contents"),
283 'change' => _("Change page attributes"),
284 'remove' => _("Remove this page"),
287 if (in_array($access, array_keys($accessDescriptions)))
288 return $accessDescriptions[$access];
294 function array_diff_assoc_recursive($array1, $array2) {
295 foreach ($array1 as $key => $value) {
296 if (is_array($value)) {
297 if (!is_array($array2[$key])) {
298 $difference[$key] = $value;
300 $new_diff = array_diff_assoc_recursive($value, $array2[$key]);
301 if ($new_diff != false) {
302 $difference[$key] = $new_diff;
305 } elseif(!isset($array2[$key]) || $array2[$key] != $value) {
306 $difference[$key] = $value;
309 return !isset($difference) ? 0 : $difference;
313 * The ACL object per page. It is stored in a page, but can also
314 * be merged with ACL's from other pages or taken from the master (pseudo) dot-file.
316 * A hash of "access" => "requires" pairs.
317 * "access" is a shortcut for common actions, which map to main.php actions
318 * "requires" required username or groupname or any special group => true or false
320 * Define any special rules here, like don't list dot-pages.
322 class PagePermission {
325 function PagePermission($hash = array()) {
326 $this->_group = &$GLOBALS['request']->getGroup();
327 if (is_array($hash) and !empty($hash)) {
328 $accessTypes = $this->accessTypes();
329 foreach ($hash as $access => $requires) {
330 if (in_array($access, $accessTypes))
331 $this->perm[$access] = $requires;
333 trigger_error(sprintf(_("Unsupported ACL access type %s ignored."), $access),
337 // set default permissions, the so called dot-file acl's
338 $this->perm = $this->defaultPerms();
344 * The workhorse to check the user against the current ACL pairs.
345 * Must translate the various special groups to the actual users settings
346 * (userid, group membership).
348 function isAuthorized($access,$user) {
349 if (!empty($this->perm{$access})) {
350 foreach ($this->perm[$access] as $group => $bool) {
351 if ($this->isMember($user,$group)) {
356 return -1; // undecided
360 * Translate the various special groups to the actual users settings
361 * (userid, group membership).
363 function isMember($user, $group) {
365 if ($group === ACL_EVERY) return true;
366 if (!isset($this->_group)) $member =& $request->getGroup();
367 else $member =& $this->_group;
368 //$user = & $request->_user;
369 if ($group === ACL_ADMIN) // WIKI_ADMIN or member of _("Administrators")
370 return $user->isAdmin() or
371 ($user->isAuthenticated() and
372 $member->isMember(GROUP_ADMIN));
373 if ($group === ACL_ANONYMOUS)
374 return ! $user->isSignedIn();
375 if ($group === ACL_BOGOUSER)
377 return isa($user,'_BogoUser') or
378 (isWikiWord($user->_userid) and $user->_level >= WIKIAUTH_BOGO);
379 else return isWikiWord($user->UserName());
380 if ($group === ACL_HASHOMEPAGE)
381 return $user->hasHomePage();
382 if ($group === ACL_SIGNED)
383 return $user->isSignedIn();
384 if ($group === ACL_AUTHENTICATED)
385 return $user->isAuthenticated();
386 if ($group === ACL_OWNER) {
387 $page = $request->getPage();
388 return ($user->isAuthenticated() and
389 $page->getOwner() === $user->UserName());
391 if ($group === ACL_CREATOR) {
392 $page = $request->getPage();
393 return ($user->isAuthenticated() and
394 $page->getCreator() === $user->UserName());
396 /* Or named groups or usernames.
397 Note: We don't seperate groups and users here.
398 Users overrides groups with the same name.
400 return $user->UserName() === $group or
401 $member->isMember($group);
405 * returns hash of default permissions.
406 * check if the page '.' exists and returns this instead.
408 function defaultPerms() {
409 //Todo: check for the existance of '.' and take this instead.
410 //Todo: honor more config.ini auth settings here
411 $perm = array('view' => array(ACL_EVERY => true),
412 'edit' => array(ACL_EVERY => true),
413 'create' => array(ACL_EVERY => true),
414 'list' => array(ACL_EVERY => true),
415 'remove' => array(ACL_ADMIN => true,
417 'change' => array(ACL_ADMIN => true,
420 $perm['dump'] = array(ACL_ADMIN => true,
423 $perm['dump'] = array(ACL_EVERY => true);
425 if (!ALLOW_ANON_USER) {
426 if (!ALLOW_USER_PASSWORDS)
427 $perm['view'] = array(ACL_SIGNED => true);
429 $perm['view'] = array(ACL_AUTHENTICATED => true);
430 $perm['view'][ACL_BOGOUSER] = ALLOW_BOGO_LOGIN ? true : false;
433 if (!ALLOW_ANON_EDIT) {
434 if (!ALLOW_USER_PASSWORDS)
435 $perm['edit'] = array(ACL_SIGNED => true);
437 $perm['edit'] = array(ACL_AUTHENTICATED => true);
438 $perm['edit'][ACL_BOGOUSER] = ALLOW_BOGO_LOGIN ? true : false;
439 $perm['create'] = $perm['edit'];
445 * FIXME: check valid groups and access
448 foreach ($this->perm as $access => $groups) {
449 foreach ($groups as $group => $bool) {
450 $this->perm[$access][$group] = (boolean) $bool;
456 * do a recursive comparison
458 function equal($otherperm) {
459 $diff = array_diff_assoc_recursive($this->perm, $otherperm);
464 * returns list of all supported access types.
466 function accessTypes() {
467 return array_keys(PagePermission::defaultPerms());
471 * special permissions for dot-files, beginning with '.'
472 * maybe also for '_' files?
474 function dotPerms() {
475 $def = array(ACL_ADMIN => true,
478 foreach (PagePermission::accessTypes() as $access) {
479 $perm[$access] = $def;
485 * dead code. not needed inside the object. see getPagePermissions($page)
487 function retrieve($page) {
488 $hash = $page->get('perm');
489 if ($hash) // hash => object
490 $perm = new PagePermission(unserialize($hash));
492 $perm = new PagePermission();
497 function store($page) {
500 return $page->set('perm',serialize($this->perm));
503 function groupName ($group) {
504 if ($group[0] == '_') return constant("GROUP".$group);
508 /* type: page, default, inherited */
509 function asTable($type) {
510 $table = HTML::table();
511 foreach ($this->perm as $access => $perms) {
512 $td = HTML::table(array('class' => 'cal','valign' => 'top'));
513 foreach ($perms as $group => $bool) {
514 $td->pushContent(HTML::tr(HTML::td(array('align'=>'right'),$group),
515 HTML::td($bool ? '[X]' : '[ ]')));
517 $table->pushContent(HTML::tr(array('valign' => 'top'),
518 HTML::td($access),HTML::td($td)));
520 if ($type == 'default')
521 $table->setAttr('style','border: dotted thin black; background-color:#eee;');
522 elseif ($type == 'inherited')
523 $table->setAttr('style','border: dotted thin black; background-color:#ddd;');
524 elseif ($type == 'page')
525 $table->setAttr('style','border: solid thin black; font-weight: bold;');
529 /* type: page, default, inherited */
530 function asEditableTable($type) {
532 if (!isset($this->_group)) {
533 $this->_group =& $GLOBALS['request']->getGroup();
535 $table = HTML::table();
536 $table->pushContent(HTML::tr(
537 HTML::th(array('align' => 'left'),
539 HTML::th(array('align'=>'right'),
541 HTML::th(_("Grant")),
542 HTML::th(_("Del/+")),
543 HTML::th(_("Description"))));
545 $allGroups = $this->_group->_specialGroups();
546 foreach ($this->_group->getAllGroupsIn() as $group) {
547 if (!in_array($group,$this->_group->specialGroups()))
548 $allGroups[] = $group;
550 //array_unique(array_merge($this->_group->getAllGroupsIn(),
551 $deletesrc = $WikiTheme->_findData('images/delete.png');
552 $addsrc = $WikiTheme->_findData('images/add.png');
553 $nbsp = HTML::raw(' ');
554 foreach ($this->perm as $access => $groups) {
555 //$permlist = HTML::table(array('class' => 'cal','valign' => 'top'));
557 $newperm = HTML::input(array('type' => 'checkbox',
558 'name' => "acl[_new_perm][$access]",
560 $addbutton = HTML::input(array('type' => 'checkbox',
561 'name' => "acl[_add_group][$access]",
564 'title' => _("Add this ACL"),
566 $newgroup = HTML::select(array('name' => "acl[_new_group][$access]",
567 'style'=> 'text-align: right;',
569 foreach ($allGroups as $groupname) {
570 if (!isset($groups[$groupname]))
571 $newgroup->pushContent(HTML::option(array('value' => $groupname),
572 $this->groupName($groupname)));
574 if (empty($groups)) {
575 $addbutton->setAttr('checked','checked');
576 $newperm->setAttr('checked','checked');
578 HTML::tr(array('valign' => 'top'),
579 HTML::td(HTML::strong($access.":")),
581 HTML::td($nbsp,$newperm),
582 HTML::td($nbsp,$addbutton),
583 HTML::td(HTML::em(getAccessDescription($access)))));
585 foreach ($groups as $group => $bool) {
586 $checkbox = HTML::input(array('type' => 'checkbox',
587 'name' => "acl[$access][$group]",
588 'title' => _("Allow / Deny"),
590 if ($bool) $checkbox->setAttr('checked','checked');
591 $checkbox = HTML(HTML::input(array('type' => 'hidden',
592 'name' => "acl[$access][$group]",
595 $deletebutton = HTML::input(array('type' => 'checkbox',
596 'name' => "acl[_del_group][$access][$group]",
597 'style' => 'background: #aaa url('.$deletesrc.')',
598 //'src' => $deletesrc,
600 'title' => _("Delete this ACL"),
605 HTML::td(HTML::strong($access.":")),
606 HTML::td(array('class' => 'cal-today','align'=>'right'),
607 HTML::strong($this->groupName($group))),
608 HTML::td(array('align'=>'center'),$nbsp,$checkbox),
609 HTML::td(array('align'=>'right','style' => 'background: #aaa url('.$deletesrc.') no-repeat'),$deletebutton),
610 HTML::td(HTML::em(getAccessDescription($access)))));
616 HTML::td(array('class' => 'cal-today','align'=>'right'),
617 HTML::strong($this->groupName($group))),
618 HTML::td(array('align'=>'center'),$nbsp,$checkbox),
619 HTML::td(array('align'=>'right','style' => 'background: #aaa url('.$deletesrc.') no-repeat'),$deletebutton),
625 HTML::tr(array('valign' => 'top'),
626 HTML::td(array('align'=>'right'),_("add ")),
628 HTML::td(array('align'=>'center'),$nbsp,$newperm),
629 HTML::td(array('align'=>'right','style' => 'background: #ccc url('.$addsrc.') no-repeat'),$addbutton),
630 HTML::td(HTML::small(_("Check to add this Acl")))));
632 if ($type == 'default')
633 $table->setAttr('style','border: dotted thin black; background-color:#eee;');
634 elseif ($type == 'inherited')
635 $table->setAttr('style','border: dotted thin black; background-color:#ddd;');
636 elseif ($type == 'page')
637 $table->setAttr('style','border: solid thin black; font-weight: bold;');
641 // Print ACL as lines of [+-]user[,group,...]:access[,access...]
642 // Seperate acl's by "; " or whitespace
643 // See http://opag.ca/wiki/HelpOnAccessControlLists
644 // As used by WikiAdminSetAclSimple
645 function asAclLines() {
648 foreach ($this->perm as $access => $groups) {
649 // unify groups for same access+bool
650 // view:CREATOR,-OWNER,
652 foreach ($groups as $group => $bool) {
653 $line .= ($bool?'':'-').$group.",";
655 if (substr($line,-1) == ',')
656 $s .= substr($line,0,-1)."; ";
658 if (substr($s,-2) == '; ')
659 $s = substr($s,0,-2);
664 // This is just a bad hack for testing.
665 // Simplify the ACL to a unix-like "rwx------+" string
667 function asRwxString($owner,$group=false) {
669 // simplify object => rwxrw---x+ string as in cygwin (+ denotes additional ACLs)
670 $perm =& $this->perm;
671 // get effective user and group
673 if (isset($perm['view'][$owner]) or
674 (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
676 if (isset($perm['edit'][$owner]) or
677 (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
679 if (isset($perm['change'][$owner]) or
680 (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
682 if (!empty($group)) {
683 if (isset($perm['view'][$group]) or
684 (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
686 if (isset($perm['edit'][$group]) or
687 (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
689 if (isset($perm['change'][$group]) or
690 (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
693 if (isset($perm['view'][ACL_EVERY]) or
694 (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
696 if (isset($perm['edit'][ACL_EVERY]) or
697 (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
699 if (isset($perm['change'][ACL_EVERY]) or
700 (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
706 // $Log: not supported by cvs2svn $
707 // Revision 1.30 2004/09/25 16:24:02 rurban
708 // fix interesting PagePerm problem: -1 == true
710 // Revision 1.29 2004/07/03 08:04:19 rurban
711 // fixed implicit PersonalPage login (e.g. on edit), fixed to check against create ACL on create, not edit
713 // Revision 1.28 2004/06/25 14:29:17 rurban
714 // WikiGroup refactoring:
715 // global group attached to user, code for not_current user.
716 // improved helpers for special groups (avoid double invocations)
717 // new experimental config option ENABLE_XHTML_XML (fails with IE, and document.write())
718 // fixed a XHTML validation error on userprefs.tmpl
720 // Revision 1.27 2004/06/16 10:38:58 rurban
721 // Disallow refernces in calls if the declaration is a reference
722 // ("allow_call_time_pass_reference clean").
723 // PhpWiki is now allow_call_time_pass_reference = Off clean,
724 // but several external libraries may not.
725 // In detail these libs look to be affected (not tested):
729 // Revision 1.26 2004/06/14 11:31:36 rurban
730 // renamed global $Theme to $WikiTheme (gforge nameclash)
731 // inherit PageList default options from PageList
732 // default sortby=pagename
733 // use options in PageList_Selectable (limit, sortby, ...)
734 // added action revert, with button at action=diff
735 // added option regex to WikiAdminSearchReplace
737 // Revision 1.25 2004/06/08 13:51:57 rurban
738 // some comments only
740 // Revision 1.24 2004/06/08 10:54:46 rurban
741 // better acl dump representation, read back acl and owner
743 // Revision 1.23 2004/06/08 10:05:11 rurban
744 // simplified admin action shortcuts
746 // Revision 1.22 2004/06/07 22:44:14 rurban
747 // added simplified chown, setacl actions
749 // Revision 1.21 2004/06/07 22:28:03 rurban
750 // add acl field to mimified dump
752 // Revision 1.20 2004/06/07 18:39:03 rurban
753 // support for SetAclSimple
755 // Revision 1.19 2004/06/06 17:12:28 rurban
756 // fixed PagePerm non-object problem (mayAccessPage), also bug #967150
758 // Revision 1.18 2004/05/27 17:49:05 rurban
759 // renamed DB_Session to DbSession (in CVS also)
760 // added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
761 // remove leading slash in error message
762 // added force_unlock parameter to File_Passwd (no return on stale locks)
763 // fixed adodb session AffectedRows
764 // added FileFinder helpers to unify local filenames and DATA_PATH names
765 // editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
767 // Revision 1.17 2004/05/16 23:10:44 rurban
768 // update_locale wrongly resetted LANG, which broke japanese.
769 // japanese now correctly uses EUC_JP, not utf-8.
770 // more charset and lang headers to help the browser.
772 // Revision 1.16 2004/05/16 22:32:53 rurban
775 // Revision 1.15 2004/05/16 22:07:35 rurban
776 // check more config-default and predefined constants
777 // various PagePerm fixes:
778 // fix default PagePerms, esp. edit and view for Bogo and Password users
779 // implemented Creator and Owner
780 // BOGOUSERS renamed to BOGOUSER
781 // fixed syntax errors in signin.tmpl
783 // Revision 1.14 2004/05/15 22:54:49 rurban
784 // fixed important WikiDB bug with DEBUG > 0: wrong assertion
785 // improved SetAcl (works) and PagePerms, some WikiGroup helpers.
787 // Revision 1.13 2004/05/15 19:48:33 rurban
788 // fix some too loose PagePerms for signed, but not authenticated users
789 // (admin, owner, creator)
790 // no double login page header, better login msg.
791 // moved action_pdf to lib/pdf.php
793 // Revision 1.12 2004/05/04 22:34:25 rurban
796 // Revision 1.11 2004/05/02 21:26:38 rurban
797 // limit user session data (HomePageHandle and auth_dbi have to invalidated anyway)
798 // because they will not survive db sessions, if too large.
799 // extended action=upgrade
800 // some WikiTranslation button work
801 // revert WIKIAUTH_UNOBTAINABLE (need it for main.php)
802 // some temp. session debug statements
804 // Revision 1.10 2004/04/29 22:32:56 zorloc
805 // Slightly more elegant fix. Instead of WIKIAUTH_FORBIDDEN, the current user's level + 1 is returned on a false.
807 // Revision 1.9 2004/04/29 17:18:19 zorloc
808 // Fixes permission failure issues. With PagePermissions and Disabled Actions when user did not have permission WIKIAUTH_FORBIDDEN was returned. In WikiUser this was ok because WIKIAUTH_FORBIDDEN had a value of 11 -- thus no user could perform that action. But WikiUserNew has a WIKIAUTH_FORBIDDEN value of -1 -- thus a user without sufficent permission to do anything. The solution is a new high value permission level (WIKIAUTH_UNOBTAINABLE) to be the default level for access failure.
810 // Revision 1.8 2004/03/14 16:24:35 rurban
811 // authenti(fi)cation spelling
813 // Revision 1.7 2004/02/28 22:25:07 rurban
814 // First PagePerm implementation:
816 // $WikiTheme->setAnonEditUnknownLinks(false);
818 // Layout improvement with dangling links for mostly closed wiki's:
819 // If false, only users with edit permissions will be presented the
820 // special wikiunknown class with "?" and Tooltip.
821 // If true (default), any user will see the ?, but will be presented
822 // the PrintLoginForm on a click.
824 // Revision 1.6 2004/02/24 15:20:05 rurban
825 // fixed minor warnings: unchecked args, POST => Get urls for sortby e.g.
827 // Revision 1.5 2004/02/23 21:30:25 rurban
828 // more PagePerm stuff: (working against 1.4.0)
829 // ACL editing and simplification of ACL's to simple rwx------ string
832 // Revision 1.4 2004/02/12 13:05:36 rurban
833 // Rename functional for PearDB backend
834 // some other minor changes
835 // SiteMap comes with a not yet functional feature request: includepages (tbd)
837 // Revision 1.3 2004/02/09 03:58:12 rurban
838 // for now default DB_SESSION to false
840 // * not existing perms will now query the parent, and not
841 // return the default perm
842 // * added pagePermissions func which returns the object per page
843 // * added getAccessDescription
845 // * added global ->prepare (not yet used) with smart user/pref/member table prefixing.
846 // * force init of authdbh in the 2 db classes
848 // * fixed session handling (not triple auth request anymore)
849 // * don't store cookie prefs with sessions
850 // stdlib: global obj2hash helper from _AuthInfo, also needed for PagePerm
852 // Revision 1.2 2004/02/08 13:17:48 rurban
853 // This should be the functionality. Needs testing and some minor todos.
855 // Revision 1.1 2004/02/08 12:29:30 rurban
856 // initial version, not yet hooked into lib/main.php
864 // c-hanging-comment-ender-p: nil
865 // indent-tabs-mode: nil