2 rcs_id('$Id: PagePerm.php,v 1.26 2004-06-14 11:31:36 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) {
159 $auth = _requiredAuthorityForPagename(action2access($action),
160 $GLOBALS['request']->getArg('pagename'));
161 assert($auth !== -1);
163 return $GLOBALS['request']->_user->_level;
165 return WIKIAUTH_UNOBTAINABLE;
168 // Translate action or plugin to the simplier access types:
169 function action2access ($action) {
189 $page = $request->getPage();
190 $current = $page->getCurrentRevision();
191 if ($current->hasDefaultContents())
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[0] == '.') {
229 $perm = new PagePermission(PagePermission::dotPerms());
230 return ($perm->isAuthorized($access, $request->_user) === true);
232 return _requiredAuthorityForPagename($access, getParentPage($pagename));
234 // ACL defined; check if isAuthorized returns true or false or undecided
235 $authorized = $perm->isAuthorized($access, $request->_user);
236 if ($authorized != -1) // -1 for undecided
239 return _requiredAuthorityForPagename($access, getParentPage($pagename));
243 * @param string $pagename page from which the parent page is searched.
244 * @return string parent pagename or the (possibly pseudo) dot-pagename.
246 function getParentPage($pagename) {
247 if (isSubPage($pagename)) {
248 return subPageSlice($pagename,0);
254 // Read the ACL from the page
255 // Done: Not existing pages should NOT be queried.
256 // Check the parent page instead and don't take the default ACL's
257 function getPagePermissions ($page) {
258 if ($hash = $page->get('perm')) // hash => object
259 return new PagePermission(unserialize($hash));
264 // Store the ACL in the page
265 function setPagePermissions ($page,$perm) {
269 function getAccessDescription($access) {
270 static $accessDescriptions;
271 if (! $accessDescriptions) {
272 $accessDescriptions = array(
273 'list' => _("List this page and all subpages"),
274 'view' => _("View this page and all subpages"),
275 'edit' => _("Edit this page and all subpages"),
276 'create' => _("Create a new (sub)page"),
277 'dump' => _("Download the page contents"),
278 'change' => _("Change page attributes"),
279 'remove' => _("Remove this page"),
282 if (in_array($access, array_keys($accessDescriptions)))
283 return $accessDescriptions[$access];
289 function array_diff_assoc_recursive($array1, $array2) {
290 foreach ($array1 as $key => $value) {
291 if (is_array($value)) {
292 if (!is_array($array2[$key])) {
293 $difference[$key] = $value;
295 $new_diff = array_diff_assoc_recursive($value, $array2[$key]);
296 if ($new_diff != false) {
297 $difference[$key] = $new_diff;
300 } elseif(!isset($array2[$key]) || $array2[$key] != $value) {
301 $difference[$key] = $value;
304 return !isset($difference) ? 0 : $difference;
308 * The ACL object per page. It is stored in a page, but can also
309 * be merged with ACL's from other pages or taken from the master (pseudo) dot-file.
311 * A hash of "access" => "requires" pairs.
312 * "access" is a shortcut for common actions, which map to main.php actions
313 * "requires" required username or groupname or any special group => true or false
315 * Define any special rules here, like don't list dot-pages.
317 class PagePermission {
320 function PagePermission($hash = array()) {
321 $this->_group = &WikiGroup::getGroup($GLOBALS['request']);
322 if (is_array($hash) and !empty($hash)) {
323 $accessTypes = $this->accessTypes();
324 foreach ($hash as $access => $requires) {
325 if (in_array($access, $accessTypes))
326 $this->perm[$access] = $requires;
328 trigger_error(sprintf(_("Unsupported ACL access type %s ignored."), $access),
332 // set default permissions, the so called dot-file acl's
333 $this->perm = $this->defaultPerms();
339 * The workhorse to check the user against the current ACL pairs.
340 * Must translate the various special groups to the actual users settings
341 * (userid, group membership).
343 function isAuthorized($access,$user) {
344 if (!empty($this->perm{$access})) {
345 foreach ($this->perm[$access] as $group => $bool) {
346 if ($this->isMember($user,$group)) {
351 return -1; // undecided
355 * Translate the various special groups to the actual users settings
356 * (userid, group membership).
358 function isMember($user, $group) {
360 if ($group === ACL_EVERY) return true;
361 if (!isset($this->_group)) $member =& WikiGroup::getGroup($request);
362 else $member =& $this->_group;
363 //$user = & $request->_user;
364 if ($group === ACL_ADMIN) // WIKI_ADMIN or member of _("Administrators")
365 return $user->isAdmin() or
366 ($user->isAuthenticated() and
367 $member->isMember(GROUP_ADMIN));
368 if ($group === ACL_ANONYMOUS)
369 return ! $user->isSignedIn();
370 if ($group === ACL_BOGOUSER)
372 return isa($user,'_BogoUser') or
373 (isWikiWord($user->_userid) and $user->_level >= WIKIAUTH_BOGO);
374 else return isWikiWord($user->UserName());
375 if ($group === ACL_HASHOMEPAGE)
376 return $user->hasHomePage();
377 if ($group === ACL_SIGNED)
378 return $user->isSignedIn();
379 if ($group === ACL_AUTHENTICATED)
380 return $user->isAuthenticated();
381 if ($group === ACL_OWNER) {
382 $page = $request->getPage();
383 return ($user->isAuthenticated() and
384 $page->getOwner() === $user->UserName());
386 if ($group === ACL_CREATOR) {
387 $page = $request->getPage();
388 return ($user->isAuthenticated() and
389 $page->getCreator() === $user->UserName());
391 /* Or named groups or usernames.
392 Note: We don't seperate groups and users here.
393 Users overrides groups with the same name.
395 return $user->UserName() === $group or
396 $member->isMember($group);
400 * returns hash of default permissions.
401 * check if the page '.' exists and returns this instead.
403 function defaultPerms() {
404 //Todo: check for the existance of '.' and take this instead.
405 //Todo: honor more config.ini auth settings here
406 $perm = array('view' => array(ACL_EVERY => true),
407 'edit' => array(ACL_EVERY => true),
408 'create' => array(ACL_EVERY => true),
409 'list' => array(ACL_EVERY => true),
410 'remove' => array(ACL_ADMIN => true,
412 'change' => array(ACL_ADMIN => true,
415 $perm['dump'] = array(ACL_ADMIN => true,
418 $perm['dump'] = array(ACL_EVERY => true);
420 if (!ALLOW_ANON_USER) {
421 if (!ALLOW_USER_PASSWORDS)
422 $perm['view'] = array(ACL_SIGNED => true);
424 $perm['view'] = array(ACL_AUTHENTICATED => true);
425 $perm['view'][ACL_BOGOUSER] = ALLOW_BOGO_LOGIN ? true : false;
428 if (!ALLOW_ANON_EDIT) {
429 if (!ALLOW_USER_PASSWORDS)
430 $perm['edit'] = array(ACL_SIGNED => true);
432 $perm['edit'] = array(ACL_AUTHENTICATED => true);
433 $perm['edit'][ACL_BOGOUSER] = ALLOW_BOGO_LOGIN ? true : false;
434 $perm['create'] = $perm['edit'];
440 * FIXME: check valid groups and access
443 foreach ($this->perm as $access => $groups) {
444 foreach ($groups as $group => $bool) {
445 $this->perm[$access][$group] = (boolean) $bool;
451 * do a recursive comparison
453 function equal($otherperm) {
454 $diff = array_diff_assoc_recursive($this->perm, $otherperm);
459 * returns list of all supported access types.
461 function accessTypes() {
462 return array_keys(PagePermission::defaultPerms());
466 * special permissions for dot-files, beginning with '.'
467 * maybe also for '_' files?
469 function dotPerms() {
470 $def = array(ACL_ADMIN => true,
473 foreach (PagePermission::accessTypes() as $access) {
474 $perm[$access] = $def;
480 * dead code. not needed inside the object. see getPagePermissions($page)
482 function retrieve($page) {
483 $hash = $page->get('perm');
484 if ($hash) // hash => object
485 $perm = new PagePermission(unserialize($hash));
487 $perm = new PagePermission();
492 function store($page) {
495 return $page->set('perm',serialize($this->perm));
498 function groupName ($group) {
499 if ($group[0] == '_') return constant("GROUP".$group);
503 /* type: page, default, inherited */
504 function asTable($type) {
505 $table = HTML::table();
506 foreach ($this->perm as $access => $perms) {
507 $td = HTML::table(array('class' => 'cal','valign' => 'top'));
508 foreach ($perms as $group => $bool) {
509 $td->pushContent(HTML::tr(HTML::td(array('align'=>'right'),$group),
510 HTML::td($bool ? '[X]' : '[ ]')));
512 $table->pushContent(HTML::tr(array('valign' => 'top'),
513 HTML::td($access),HTML::td($td)));
515 if ($type == 'default')
516 $table->setAttr('style','border: dotted thin black; background-color:#eee;');
517 elseif ($type == 'inherited')
518 $table->setAttr('style','border: dotted thin black; background-color:#ddd;');
519 elseif ($type == 'page')
520 $table->setAttr('style','border: solid thin black; font-weight: bold;');
524 /* type: page, default, inherited */
525 function asEditableTable($type) {
527 if (!isset($this->_group)) {
528 $this->_group =& WikiGroup::getGroup($GLOBALS['request']);
530 $table = HTML::table();
531 $table->pushContent(HTML::tr(
532 HTML::th(array('align' => 'left'),
534 HTML::th(array('align'=>'right'),
536 HTML::th(_("Grant")),
537 HTML::th(_("Del/+")),
538 HTML::th(_("Description"))));
540 $allGroups = $this->_group->_specialGroups();
541 foreach ($this->_group->getAllGroupsIn() as $group) {
542 if (!in_array($group,$this->_group->specialGroups()))
543 $allGroups[] = $group;
545 //array_unique(array_merge($this->_group->getAllGroupsIn(),
546 $deletesrc = $WikiTheme->_findData('images/delete.png');
547 $addsrc = $WikiTheme->_findData('images/add.png');
548 $nbsp = HTML::raw(' ');
549 foreach ($this->perm as $access => $groups) {
550 //$permlist = HTML::table(array('class' => 'cal','valign' => 'top'));
552 $newperm = HTML::input(array('type' => 'checkbox',
553 'name' => "acl[_new_perm][$access]",
555 $addbutton = HTML::input(array('type' => 'checkbox',
556 'name' => "acl[_add_group][$access]",
559 'title' => _("Add this ACL"),
561 $newgroup = HTML::select(array('name' => "acl[_new_group][$access]",
562 'style'=> 'text-align: right;',
564 foreach ($allGroups as $groupname) {
565 if (!isset($groups[$groupname]))
566 $newgroup->pushContent(HTML::option(array('value' => $groupname),
567 $this->groupName($groupname)));
569 if (empty($groups)) {
570 $addbutton->setAttr('checked','checked');
571 $newperm->setAttr('checked','checked');
573 HTML::tr(array('valign' => 'top'),
574 HTML::td(HTML::strong($access.":")),
576 HTML::td($nbsp,$newperm),
577 HTML::td($nbsp,$addbutton),
578 HTML::td(HTML::em(getAccessDescription($access)))));
580 foreach ($groups as $group => $bool) {
581 $checkbox = HTML::input(array('type' => 'checkbox',
582 'name' => "acl[$access][$group]",
583 'title' => _("Allow / Deny"),
585 if ($bool) $checkbox->setAttr('checked','checked');
586 $checkbox = HTML(HTML::input(array('type' => 'hidden',
587 'name' => "acl[$access][$group]",
590 $deletebutton = HTML::input(array('type' => 'checkbox',
591 'name' => "acl[_del_group][$access][$group]",
592 'style' => 'background: #aaa url('.$deletesrc.')',
593 //'src' => $deletesrc,
595 'title' => _("Delete this ACL"),
600 HTML::td(HTML::strong($access.":")),
601 HTML::td(array('class' => 'cal-today','align'=>'right'),
602 HTML::strong($this->groupName($group))),
603 HTML::td(array('align'=>'center'),$nbsp,$checkbox),
604 HTML::td(array('align'=>'right','style' => 'background: #aaa url('.$deletesrc.') no-repeat'),$deletebutton),
605 HTML::td(HTML::em(getAccessDescription($access)))));
611 HTML::td(array('class' => 'cal-today','align'=>'right'),
612 HTML::strong($this->groupName($group))),
613 HTML::td(array('align'=>'center'),$nbsp,$checkbox),
614 HTML::td(array('align'=>'right','style' => 'background: #aaa url('.$deletesrc.') no-repeat'),$deletebutton),
620 HTML::tr(array('valign' => 'top'),
621 HTML::td(array('align'=>'right'),_("add ")),
623 HTML::td(array('align'=>'center'),$nbsp,$newperm),
624 HTML::td(array('align'=>'right','style' => 'background: #ccc url('.$addsrc.') no-repeat'),$addbutton),
625 HTML::td(HTML::small(_("Check to add this Acl")))));
627 if ($type == 'default')
628 $table->setAttr('style','border: dotted thin black; background-color:#eee;');
629 elseif ($type == 'inherited')
630 $table->setAttr('style','border: dotted thin black; background-color:#ddd;');
631 elseif ($type == 'page')
632 $table->setAttr('style','border: solid thin black; font-weight: bold;');
636 // Print ACL as lines of [+-]user[,group,...]:access[,access...]
637 // Seperate acl's by "; " or whitespace
638 // See http://opag.ca/wiki/HelpOnAccessControlLists
639 // As used by WikiAdminSetAclSimple
640 function asAclLines() {
643 foreach ($this->perm as $access => $groups) {
644 // unify groups for same access+bool
645 // view:CREATOR,-OWNER,
647 foreach ($groups as $group => $bool) {
648 $line .= ($bool?'':'-').$group.",";
650 if (substr($line,-1) == ',')
651 $s .= substr($line,0,-1)."; ";
653 if (substr($s,-2) == '; ')
654 $s = substr($s,0,-2);
659 // This is just a bad hack for testing.
660 // Simplify the ACL to a unix-like "rwx------+" string
662 function asRwxString($owner,$group=false) {
664 // simplify object => rwxrw---x+ string as in cygwin (+ denotes additional ACLs)
665 $perm =& $this->perm;
666 // get effective user and group
668 if (isset($perm['view'][$owner]) or
669 (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
671 if (isset($perm['edit'][$owner]) or
672 (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
674 if (isset($perm['change'][$owner]) or
675 (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
677 if (!empty($group)) {
678 if (isset($perm['view'][$group]) or
679 (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
681 if (isset($perm['edit'][$group]) or
682 (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
684 if (isset($perm['change'][$group]) or
685 (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
688 if (isset($perm['view'][ACL_EVERY]) or
689 (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
691 if (isset($perm['edit'][ACL_EVERY]) or
692 (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
694 if (isset($perm['change'][ACL_EVERY]) or
695 (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
701 // $Log: not supported by cvs2svn $
702 // Revision 1.25 2004/06/08 13:51:57 rurban
703 // some comments only
705 // Revision 1.24 2004/06/08 10:54:46 rurban
706 // better acl dump representation, read back acl and owner
708 // Revision 1.23 2004/06/08 10:05:11 rurban
709 // simplified admin action shortcuts
711 // Revision 1.22 2004/06/07 22:44:14 rurban
712 // added simplified chown, setacl actions
714 // Revision 1.21 2004/06/07 22:28:03 rurban
715 // add acl field to mimified dump
717 // Revision 1.20 2004/06/07 18:39:03 rurban
718 // support for SetAclSimple
720 // Revision 1.19 2004/06/06 17:12:28 rurban
721 // fixed PagePerm non-object problem (mayAccessPage), also bug #967150
723 // Revision 1.18 2004/05/27 17:49:05 rurban
724 // renamed DB_Session to DbSession (in CVS also)
725 // added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
726 // remove leading slash in error message
727 // added force_unlock parameter to File_Passwd (no return on stale locks)
728 // fixed adodb session AffectedRows
729 // added FileFinder helpers to unify local filenames and DATA_PATH names
730 // editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
732 // Revision 1.17 2004/05/16 23:10:44 rurban
733 // update_locale wrongly resetted LANG, which broke japanese.
734 // japanese now correctly uses EUC_JP, not utf-8.
735 // more charset and lang headers to help the browser.
737 // Revision 1.16 2004/05/16 22:32:53 rurban
740 // Revision 1.15 2004/05/16 22:07:35 rurban
741 // check more config-default and predefined constants
742 // various PagePerm fixes:
743 // fix default PagePerms, esp. edit and view for Bogo and Password users
744 // implemented Creator and Owner
745 // BOGOUSERS renamed to BOGOUSER
746 // fixed syntax errors in signin.tmpl
748 // Revision 1.14 2004/05/15 22:54:49 rurban
749 // fixed important WikiDB bug with DEBUG > 0: wrong assertion
750 // improved SetAcl (works) and PagePerms, some WikiGroup helpers.
752 // Revision 1.13 2004/05/15 19:48:33 rurban
753 // fix some too loose PagePerms for signed, but not authenticated users
754 // (admin, owner, creator)
755 // no double login page header, better login msg.
756 // moved action_pdf to lib/pdf.php
758 // Revision 1.12 2004/05/04 22:34:25 rurban
761 // Revision 1.11 2004/05/02 21:26:38 rurban
762 // limit user session data (HomePageHandle and auth_dbi have to invalidated anyway)
763 // because they will not survive db sessions, if too large.
764 // extended action=upgrade
765 // some WikiTranslation button work
766 // revert WIKIAUTH_UNOBTAINABLE (need it for main.php)
767 // some temp. session debug statements
769 // Revision 1.10 2004/04/29 22:32:56 zorloc
770 // Slightly more elegant fix. Instead of WIKIAUTH_FORBIDDEN, the current user's level + 1 is returned on a false.
772 // Revision 1.9 2004/04/29 17:18:19 zorloc
773 // 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.
775 // Revision 1.8 2004/03/14 16:24:35 rurban
776 // authenti(fi)cation spelling
778 // Revision 1.7 2004/02/28 22:25:07 rurban
779 // First PagePerm implementation:
781 // $WikiTheme->setAnonEditUnknownLinks(false);
783 // Layout improvement with dangling links for mostly closed wiki's:
784 // If false, only users with edit permissions will be presented the
785 // special wikiunknown class with "?" and Tooltip.
786 // If true (default), any user will see the ?, but will be presented
787 // the PrintLoginForm on a click.
789 // Revision 1.6 2004/02/24 15:20:05 rurban
790 // fixed minor warnings: unchecked args, POST => Get urls for sortby e.g.
792 // Revision 1.5 2004/02/23 21:30:25 rurban
793 // more PagePerm stuff: (working against 1.4.0)
794 // ACL editing and simplification of ACL's to simple rwx------ string
797 // Revision 1.4 2004/02/12 13:05:36 rurban
798 // Rename functional for PearDB backend
799 // some other minor changes
800 // SiteMap comes with a not yet functional feature request: includepages (tbd)
802 // Revision 1.3 2004/02/09 03:58:12 rurban
803 // for now default DB_SESSION to false
805 // * not existing perms will now query the parent, and not
806 // return the default perm
807 // * added pagePermissions func which returns the object per page
808 // * added getAccessDescription
810 // * added global ->prepare (not yet used) with smart user/pref/member table prefixing.
811 // * force init of authdbh in the 2 db classes
813 // * fixed session handling (not triple auth request anymore)
814 // * don't store cookie prefs with sessions
815 // stdlib: global obj2hash helper from _AuthInfo, also needed for PagePerm
817 // Revision 1.2 2004/02/08 13:17:48 rurban
818 // This should be the functionality. Needs testing and some minor todos.
820 // Revision 1.1 2004/02/08 12:29:30 rurban
821 // initial version, not yet hooked into lib/main.php
829 // c-hanging-comment-ender-p: nil
830 // indent-tabs-mode: nil