2 rcs_id('$Id: PagePerm.php,v 1.33 2004-09-26 11:47:52 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
91 } elseif ($pagename == '.') { // stop recursion in pathological case.
92 // "." defined, without any acl
93 return array('default', new PagePermission());
95 return array('inherited', pagePermissions(getParentPage($pagename)));
99 function pagePermissionsSimpleFormat($perm_tree, $owner, $group=false) {
100 list($type,$perm) = pagePermissionsAcl($perm_tree[0], $perm_tree);
102 $type = $perm_tree[0];
103 $perm = pagePermissionsAcl($perm_tree);
104 if (is_object($perm_tree[1]))
105 $perm = $perm_tree[1];
106 elseif (is_array($perm_tree[1])) {
107 $perm_tree = pagePermissionsSimpleFormat($perm_tree[1],$owner,$group);
108 if (isa($perm_tree[1],'pagepermission'))
109 $perm = $perm_tree[1];
110 elseif (isa($perm_tree,'htmlelement'))
115 return HTML::tt(HTML::strong($perm->asRwxString($owner, $group)));
116 elseif ($type == 'default')
117 return HTML::tt($perm->asRwxString($owner, $group));
118 elseif ($type == 'inherited') {
119 return HTML::tt(array('class'=>'inherited', 'style'=>'color:#aaa;'),
120 $perm->asRwxString($owner, $group));
124 function pagePermissionsAcl($type,$perm_tree) {
125 $perm = $perm_tree[1];
126 while (!is_object($perm)) {
127 $perm_tree = pagePermissionsAcl($type, $perm);
128 $perm = $perm_tree[1];
130 return array($type,$perm);
135 function pagePermissionsAclFormat($perm_tree, $editable=false) {
136 list($type,$perm) = pagePermissionsAcl($perm_tree[0], $perm_tree);
138 return $perm->asEditableTable($type);
140 return $perm->asTable($type);
144 * Check permission per page.
145 * Returns true or false.
147 function mayAccessPage ($access, $pagename) {
149 return _requiredAuthorityForPagename($access, $pagename);
155 * Check the permissions for the current action.
156 * Walk down the inheritance tree. Collect all permissions until
157 * the minimum required level is gained, which is not
158 * overruled by more specific forbid rules.
159 * Todo: cache result per access and page in session?
161 function requiredAuthorityForPage ($action) {
163 $auth = _requiredAuthorityForPagename(action2access($action),
164 $request->getArg('pagename'));
165 assert($auth !== -1);
167 return $request->_user->_level;
169 return WIKIAUTH_UNOBTAINABLE;
172 // Translate action or plugin to the simplier access types:
173 function action2access ($action) {
193 $page = $request->getPage();
194 if (!$page->exists())
201 // probably create/edit but we cannot check all page permissions, can we?
211 //Todo: Plugins should be able to override its access type
212 if (isWikiWord($action))
220 // Recursive helper to do the real work
221 // TODO: check if a perm cache for page-(current+edit+change?)action pairs will help
222 function _requiredAuthorityForPagename($access, $pagename) {
224 static $permcache = array();
226 if (array_key_exists($pagename, $permcache)
227 and array_key_exists($access, $permcache[$pagename]))
228 return $permcache[$pagename][$access];
230 $page = $request->getPage($pagename);
231 // Page not found; check against default permissions
232 if (! $page->exists() ) {
233 $perm = new PagePermission();
234 $result = ($perm->isAuthorized($access, $request->_user) === true);
235 $permcache[$pagename][$access] = $result;
238 // no ACL defined; check for special dotfile or walk down
239 if (! ($perm = getPagePermissions($page))) {
240 if ($pagename == '.') {
241 $perm = new PagePermission();
242 if ($perm->isAuthorized('change', $request->_user)) {
243 // warn the user to set ACL of ".", if he has permissions to do so.
244 trigger_error(". (dotpage == rootpage for inheriting pageperm ACLs) exists without any ACL!\n".
245 "Please do ?action=setacl&pagename=.", E_USER_WARNING);
247 $result = ($perm->isAuthorized($access, $request->_user) === true);
248 $permcache[$pagename][$access] = $result;
250 } elseif ($pagename[0] == '.') {
251 $perm = new PagePermission(PagePermission::dotPerms());
252 $result = ($perm->isAuthorized($access, $request->_user) === true);
253 $permcache[$pagename][$access] = $result;
256 return _requiredAuthorityForPagename($access, getParentPage($pagename));
258 // ACL defined; check if isAuthorized returns true or false or undecided
259 $authorized = $perm->isAuthorized($access, $request->_user);
260 if ($authorized !== -1) { // interestingly true is also -1
261 $permcache[$pagename][$access] = $authorized;
263 } elseif ($pagename == '.') {
266 return _requiredAuthorityForPagename($access, getParentPage($pagename));
271 * @param string $pagename page from which the parent page is searched.
272 * @return string parent pagename or the (possibly pseudo) dot-pagename.
274 function getParentPage($pagename) {
275 if (isSubPage($pagename)) {
276 return subPageSlice($pagename,0);
282 // Read the ACL from the page
283 // Done: Not existing pages should NOT be queried.
284 // Check the parent page instead and don't take the default ACL's
285 function getPagePermissions ($page) {
286 if ($hash = $page->get('perm')) // hash => object
287 return new PagePermission(unserialize($hash));
292 // Store the ACL in the page
293 function setPagePermissions ($page,$perm) {
297 function getAccessDescription($access) {
298 static $accessDescriptions;
299 if (! $accessDescriptions) {
300 $accessDescriptions = array(
301 'list' => _("List this page and all subpages"),
302 'view' => _("View this page and all subpages"),
303 'edit' => _("Edit this page and all subpages"),
304 'create' => _("Create a new (sub)page"),
305 'dump' => _("Download the page contents"),
306 'change' => _("Change page attributes"),
307 'remove' => _("Remove this page"),
310 if (in_array($access, array_keys($accessDescriptions)))
311 return $accessDescriptions[$access];
317 function array_diff_assoc_recursive($array1, $array2) {
318 foreach ($array1 as $key => $value) {
319 if (is_array($value)) {
320 if (!is_array($array2[$key])) {
321 $difference[$key] = $value;
323 $new_diff = array_diff_assoc_recursive($value, $array2[$key]);
324 if ($new_diff != false) {
325 $difference[$key] = $new_diff;
328 } elseif(!isset($array2[$key]) || $array2[$key] != $value) {
329 $difference[$key] = $value;
332 return !isset($difference) ? 0 : $difference;
336 * The ACL object per page. It is stored in a page, but can also
337 * be merged with ACL's from other pages or taken from the master (pseudo) dot-file.
339 * A hash of "access" => "requires" pairs.
340 * "access" is a shortcut for common actions, which map to main.php actions
341 * "requires" required username or groupname or any special group => true or false
343 * Define any special rules here, like don't list dot-pages.
345 class PagePermission {
348 function PagePermission($hash = array()) {
349 $this->_group = &$GLOBALS['request']->getGroup();
350 if (is_array($hash) and !empty($hash)) {
351 $accessTypes = $this->accessTypes();
352 foreach ($hash as $access => $requires) {
353 if (in_array($access, $accessTypes))
354 $this->perm[$access] = $requires;
356 trigger_error(sprintf(_("Unsupported ACL access type %s ignored."), $access),
360 // set default permissions, the so called dot-file acl's
361 $this->perm = $this->defaultPerms();
367 * The workhorse to check the user against the current ACL pairs.
368 * Must translate the various special groups to the actual users settings
369 * (userid, group membership).
371 function isAuthorized($access,$user) {
372 if (!empty($this->perm{$access})) {
373 foreach ($this->perm[$access] as $group => $bool) {
374 if ($this->isMember($user,$group)) {
379 return -1; // undecided
383 * Translate the various special groups to the actual users settings
384 * (userid, group membership).
386 function isMember($user, $group) {
388 if ($group === ACL_EVERY) return true;
389 if (!isset($this->_group)) $member =& $request->getGroup();
390 else $member =& $this->_group;
391 //$user = & $request->_user;
392 if ($group === ACL_ADMIN) // WIKI_ADMIN or member of _("Administrators")
393 return $user->isAdmin() or
394 ($user->isAuthenticated() and
395 $member->isMember(GROUP_ADMIN));
396 if ($group === ACL_ANONYMOUS)
397 return ! $user->isSignedIn();
398 if ($group === ACL_BOGOUSER)
400 return isa($user,'_BogoUser') or
401 (isWikiWord($user->_userid) and $user->_level >= WIKIAUTH_BOGO);
402 else return isWikiWord($user->UserName());
403 if ($group === ACL_HASHOMEPAGE)
404 return $user->hasHomePage();
405 if ($group === ACL_SIGNED)
406 return $user->isSignedIn();
407 if ($group === ACL_AUTHENTICATED)
408 return $user->isAuthenticated();
409 if ($group === ACL_OWNER) {
410 $page = $request->getPage();
411 return ($user->isAuthenticated() and
412 $page->getOwner() === $user->UserName());
414 if ($group === ACL_CREATOR) {
415 $page = $request->getPage();
416 return ($user->isAuthenticated() and
417 $page->getCreator() === $user->UserName());
419 /* Or named groups or usernames.
420 Note: We don't seperate groups and users here.
421 Users overrides groups with the same name.
423 return $user->UserName() === $group or
424 $member->isMember($group);
428 * returns hash of default permissions.
429 * check if the page '.' exists and returns this instead.
431 function defaultPerms() {
432 //Todo: check for the existance of '.' and take this instead.
433 //Todo: honor more config.ini auth settings here
434 $perm = array('view' => array(ACL_EVERY => true),
435 'edit' => array(ACL_EVERY => true),
436 'create' => array(ACL_EVERY => true),
437 'list' => array(ACL_EVERY => true),
438 'remove' => array(ACL_ADMIN => true,
440 'change' => array(ACL_ADMIN => true,
443 $perm['dump'] = array(ACL_ADMIN => true,
446 $perm['dump'] = array(ACL_EVERY => true);
448 if (!ALLOW_ANON_USER) {
449 if (!ALLOW_USER_PASSWORDS)
450 $perm['view'] = array(ACL_SIGNED => true);
452 $perm['view'] = array(ACL_AUTHENTICATED => true);
453 $perm['view'][ACL_BOGOUSER] = ALLOW_BOGO_LOGIN ? true : false;
456 if (!ALLOW_ANON_EDIT) {
457 if (!ALLOW_USER_PASSWORDS)
458 $perm['edit'] = array(ACL_SIGNED => true);
460 $perm['edit'] = array(ACL_AUTHENTICATED => true);
461 $perm['edit'][ACL_BOGOUSER] = ALLOW_BOGO_LOGIN ? true : false;
462 $perm['create'] = $perm['edit'];
468 * FIXME: check valid groups and access
471 foreach ($this->perm as $access => $groups) {
472 foreach ($groups as $group => $bool) {
473 $this->perm[$access][$group] = (boolean) $bool;
479 * do a recursive comparison
481 function equal($otherperm) {
482 $diff = array_diff_assoc_recursive($this->perm, $otherperm);
487 * returns list of all supported access types.
489 function accessTypes() {
490 return array_keys(PagePermission::defaultPerms());
494 * special permissions for dot-files, beginning with '.'
495 * maybe also for '_' files?
497 function dotPerms() {
498 $def = array(ACL_ADMIN => true,
501 foreach (PagePermission::accessTypes() as $access) {
502 $perm[$access] = $def;
508 * dead code. not needed inside the object. see getPagePermissions($page)
510 function retrieve($page) {
511 $hash = $page->get('perm');
512 if ($hash) // hash => object
513 $perm = new PagePermission(unserialize($hash));
515 $perm = new PagePermission();
520 function store($page) {
523 return $page->set('perm',serialize($this->perm));
526 function groupName ($group) {
527 if ($group[0] == '_') return constant("GROUP".$group);
531 /* type: page, default, inherited */
532 function asTable($type) {
533 $table = HTML::table();
534 foreach ($this->perm as $access => $perms) {
535 $td = HTML::table(array('class' => 'cal','valign' => 'top'));
536 foreach ($perms as $group => $bool) {
537 $td->pushContent(HTML::tr(HTML::td(array('align'=>'right'),$group),
538 HTML::td($bool ? '[X]' : '[ ]')));
540 $table->pushContent(HTML::tr(array('valign' => 'top'),
541 HTML::td($access),HTML::td($td)));
543 if ($type == 'default')
544 $table->setAttr('style','border: dotted thin black; background-color:#eee;');
545 elseif ($type == 'inherited')
546 $table->setAttr('style','border: dotted thin black; background-color:#ddd;');
547 elseif ($type == 'page')
548 $table->setAttr('style','border: solid thin black; font-weight: bold;');
552 /* type: page, default, inherited */
553 function asEditableTable($type) {
555 if (!isset($this->_group)) {
556 $this->_group =& $GLOBALS['request']->getGroup();
558 $table = HTML::table();
559 $table->pushContent(HTML::tr(
560 HTML::th(array('align' => 'left'),
562 HTML::th(array('align'=>'right'),
564 HTML::th(_("Grant")),
565 HTML::th(_("Del/+")),
566 HTML::th(_("Description"))));
568 $allGroups = $this->_group->_specialGroups();
569 foreach ($this->_group->getAllGroupsIn() as $group) {
570 if (!in_array($group,$this->_group->specialGroups()))
571 $allGroups[] = $group;
573 //array_unique(array_merge($this->_group->getAllGroupsIn(),
574 $deletesrc = $WikiTheme->_findData('images/delete.png');
575 $addsrc = $WikiTheme->_findData('images/add.png');
576 $nbsp = HTML::raw(' ');
577 foreach ($this->perm as $access => $groups) {
578 //$permlist = HTML::table(array('class' => 'cal','valign' => 'top'));
580 $newperm = HTML::input(array('type' => 'checkbox',
581 'name' => "acl[_new_perm][$access]",
583 $addbutton = HTML::input(array('type' => 'checkbox',
584 'name' => "acl[_add_group][$access]",
587 'title' => _("Add this ACL"),
589 $newgroup = HTML::select(array('name' => "acl[_new_group][$access]",
590 'style'=> 'text-align: right;',
592 foreach ($allGroups as $groupname) {
593 if (!isset($groups[$groupname]))
594 $newgroup->pushContent(HTML::option(array('value' => $groupname),
595 $this->groupName($groupname)));
597 if (empty($groups)) {
598 $addbutton->setAttr('checked','checked');
599 $newperm->setAttr('checked','checked');
601 HTML::tr(array('valign' => 'top'),
602 HTML::td(HTML::strong($access.":")),
604 HTML::td($nbsp,$newperm),
605 HTML::td($nbsp,$addbutton),
606 HTML::td(HTML::em(getAccessDescription($access)))));
608 foreach ($groups as $group => $bool) {
609 $checkbox = HTML::input(array('type' => 'checkbox',
610 'name' => "acl[$access][$group]",
611 'title' => _("Allow / Deny"),
613 if ($bool) $checkbox->setAttr('checked','checked');
614 $checkbox = HTML(HTML::input(array('type' => 'hidden',
615 'name' => "acl[$access][$group]",
618 $deletebutton = HTML::input(array('type' => 'checkbox',
619 'name' => "acl[_del_group][$access][$group]",
620 'style' => 'background: #aaa url('.$deletesrc.')',
621 //'src' => $deletesrc,
623 'title' => _("Delete this ACL"),
628 HTML::td(HTML::strong($access.":")),
629 HTML::td(array('class' => 'cal-today','align'=>'right'),
630 HTML::strong($this->groupName($group))),
631 HTML::td(array('align'=>'center'),$nbsp,$checkbox),
632 HTML::td(array('align'=>'right','style' => 'background: #aaa url('.$deletesrc.') no-repeat'),$deletebutton),
633 HTML::td(HTML::em(getAccessDescription($access)))));
639 HTML::td(array('class' => 'cal-today','align'=>'right'),
640 HTML::strong($this->groupName($group))),
641 HTML::td(array('align'=>'center'),$nbsp,$checkbox),
642 HTML::td(array('align'=>'right','style' => 'background: #aaa url('.$deletesrc.') no-repeat'),$deletebutton),
648 HTML::tr(array('valign' => 'top'),
649 HTML::td(array('align'=>'right'),_("add ")),
651 HTML::td(array('align'=>'center'),$nbsp,$newperm),
652 HTML::td(array('align'=>'right','style' => 'background: #ccc url('.$addsrc.') no-repeat'),$addbutton),
653 HTML::td(HTML::small(_("Check to add this Acl")))));
655 if ($type == 'default')
656 $table->setAttr('style','border: dotted thin black; background-color:#eee;');
657 elseif ($type == 'inherited')
658 $table->setAttr('style','border: dotted thin black; background-color:#ddd;');
659 elseif ($type == 'page')
660 $table->setAttr('style','border: solid thin black; font-weight: bold;');
664 // Print ACL as lines of [+-]user[,group,...]:access[,access...]
665 // Seperate acl's by "; " or whitespace
666 // See http://opag.ca/wiki/HelpOnAccessControlLists
667 // As used by WikiAdminSetAclSimple
668 function asAclLines() {
671 foreach ($this->perm as $access => $groups) {
672 // unify groups for same access+bool
673 // view:CREATOR,-OWNER,
675 foreach ($groups as $group => $bool) {
676 $line .= ($bool?'':'-').$group.",";
678 if (substr($line,-1) == ',')
679 $s .= substr($line,0,-1)."; ";
681 if (substr($s,-2) == '; ')
682 $s = substr($s,0,-2);
687 // This is just a bad hack for testing.
688 // Simplify the ACL to a unix-like "rwx------+" string
690 function asRwxString($owner,$group=false) {
692 // simplify object => rwxrw---x+ string as in cygwin (+ denotes additional ACLs)
693 $perm =& $this->perm;
694 // get effective user and group
696 if (isset($perm['view'][$owner]) or
697 (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
699 if (isset($perm['edit'][$owner]) or
700 (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
702 if (isset($perm['change'][$owner]) or
703 (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
705 if (!empty($group)) {
706 if (isset($perm['view'][$group]) or
707 (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
709 if (isset($perm['edit'][$group]) or
710 (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
712 if (isset($perm['change'][$group]) or
713 (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
716 if (isset($perm['view'][ACL_EVERY]) or
717 (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
719 if (isset($perm['edit'][ACL_EVERY]) or
720 (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
722 if (isset($perm['change'][ACL_EVERY]) or
723 (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
729 // $Log: not supported by cvs2svn $
730 // Revision 1.32 2004/09/25 18:56:09 rurban
731 // avoid recursion bug on setacl for "."
733 // Revision 1.31 2004/09/25 18:34:45 rurban
734 // fix and warn on too restrictive ACL handling without ACL in existing . (dotpage)
736 // Revision 1.30 2004/09/25 16:24:02 rurban
737 // fix interesting PagePerm problem: -1 == true
739 // Revision 1.29 2004/07/03 08:04:19 rurban
740 // fixed implicit PersonalPage login (e.g. on edit), fixed to check against create ACL on create, not edit
742 // Revision 1.28 2004/06/25 14:29:17 rurban
743 // WikiGroup refactoring:
744 // global group attached to user, code for not_current user.
745 // improved helpers for special groups (avoid double invocations)
746 // new experimental config option ENABLE_XHTML_XML (fails with IE, and document.write())
747 // fixed a XHTML validation error on userprefs.tmpl
749 // Revision 1.27 2004/06/16 10:38:58 rurban
750 // Disallow refernces in calls if the declaration is a reference
751 // ("allow_call_time_pass_reference clean").
752 // PhpWiki is now allow_call_time_pass_reference = Off clean,
753 // but several external libraries may not.
754 // In detail these libs look to be affected (not tested):
758 // Revision 1.26 2004/06/14 11:31:36 rurban
759 // renamed global $Theme to $WikiTheme (gforge nameclash)
760 // inherit PageList default options from PageList
761 // default sortby=pagename
762 // use options in PageList_Selectable (limit, sortby, ...)
763 // added action revert, with button at action=diff
764 // added option regex to WikiAdminSearchReplace
766 // Revision 1.25 2004/06/08 13:51:57 rurban
767 // some comments only
769 // Revision 1.24 2004/06/08 10:54:46 rurban
770 // better acl dump representation, read back acl and owner
772 // Revision 1.23 2004/06/08 10:05:11 rurban
773 // simplified admin action shortcuts
775 // Revision 1.22 2004/06/07 22:44:14 rurban
776 // added simplified chown, setacl actions
778 // Revision 1.21 2004/06/07 22:28:03 rurban
779 // add acl field to mimified dump
781 // Revision 1.20 2004/06/07 18:39:03 rurban
782 // support for SetAclSimple
784 // Revision 1.19 2004/06/06 17:12:28 rurban
785 // fixed PagePerm non-object problem (mayAccessPage), also bug #967150
787 // Revision 1.18 2004/05/27 17:49:05 rurban
788 // renamed DB_Session to DbSession (in CVS also)
789 // added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
790 // remove leading slash in error message
791 // added force_unlock parameter to File_Passwd (no return on stale locks)
792 // fixed adodb session AffectedRows
793 // added FileFinder helpers to unify local filenames and DATA_PATH names
794 // editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
796 // Revision 1.17 2004/05/16 23:10:44 rurban
797 // update_locale wrongly resetted LANG, which broke japanese.
798 // japanese now correctly uses EUC_JP, not utf-8.
799 // more charset and lang headers to help the browser.
801 // Revision 1.16 2004/05/16 22:32:53 rurban
804 // Revision 1.15 2004/05/16 22:07:35 rurban
805 // check more config-default and predefined constants
806 // various PagePerm fixes:
807 // fix default PagePerms, esp. edit and view for Bogo and Password users
808 // implemented Creator and Owner
809 // BOGOUSERS renamed to BOGOUSER
810 // fixed syntax errors in signin.tmpl
812 // Revision 1.14 2004/05/15 22:54:49 rurban
813 // fixed important WikiDB bug with DEBUG > 0: wrong assertion
814 // improved SetAcl (works) and PagePerms, some WikiGroup helpers.
816 // Revision 1.13 2004/05/15 19:48:33 rurban
817 // fix some too loose PagePerms for signed, but not authenticated users
818 // (admin, owner, creator)
819 // no double login page header, better login msg.
820 // moved action_pdf to lib/pdf.php
822 // Revision 1.12 2004/05/04 22:34:25 rurban
825 // Revision 1.11 2004/05/02 21:26:38 rurban
826 // limit user session data (HomePageHandle and auth_dbi have to invalidated anyway)
827 // because they will not survive db sessions, if too large.
828 // extended action=upgrade
829 // some WikiTranslation button work
830 // revert WIKIAUTH_UNOBTAINABLE (need it for main.php)
831 // some temp. session debug statements
833 // Revision 1.10 2004/04/29 22:32:56 zorloc
834 // Slightly more elegant fix. Instead of WIKIAUTH_FORBIDDEN, the current user's level + 1 is returned on a false.
836 // Revision 1.9 2004/04/29 17:18:19 zorloc
837 // 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.
839 // Revision 1.8 2004/03/14 16:24:35 rurban
840 // authenti(fi)cation spelling
842 // Revision 1.7 2004/02/28 22:25:07 rurban
843 // First PagePerm implementation:
845 // $WikiTheme->setAnonEditUnknownLinks(false);
847 // Layout improvement with dangling links for mostly closed wiki's:
848 // If false, only users with edit permissions will be presented the
849 // special wikiunknown class with "?" and Tooltip.
850 // If true (default), any user will see the ?, but will be presented
851 // the PrintLoginForm on a click.
853 // Revision 1.6 2004/02/24 15:20:05 rurban
854 // fixed minor warnings: unchecked args, POST => Get urls for sortby e.g.
856 // Revision 1.5 2004/02/23 21:30:25 rurban
857 // more PagePerm stuff: (working against 1.4.0)
858 // ACL editing and simplification of ACL's to simple rwx------ string
861 // Revision 1.4 2004/02/12 13:05:36 rurban
862 // Rename functional for PearDB backend
863 // some other minor changes
864 // SiteMap comes with a not yet functional feature request: includepages (tbd)
866 // Revision 1.3 2004/02/09 03:58:12 rurban
867 // for now default DB_SESSION to false
869 // * not existing perms will now query the parent, and not
870 // return the default perm
871 // * added pagePermissions func which returns the object per page
872 // * added getAccessDescription
874 // * added global ->prepare (not yet used) with smart user/pref/member table prefixing.
875 // * force init of authdbh in the 2 db classes
877 // * fixed session handling (not triple auth request anymore)
878 // * don't store cookie prefs with sessions
879 // stdlib: global obj2hash helper from _AuthInfo, also needed for PagePerm
881 // Revision 1.2 2004/02/08 13:17:48 rurban
882 // This should be the functionality. Needs testing and some minor todos.
884 // Revision 1.1 2004/02/08 12:29:30 rurban
885 // initial version, not yet hooked into lib/main.php
893 // c-hanging-comment-ender-p: nil
894 // indent-tabs-mode: nil