]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/PagePerm.php
renamed global $Theme to $WikiTheme (gforge nameclash)
[SourceForge/phpwiki.git] / lib / PagePerm.php
1 <?php // -*-php-*-
2 rcs_id('$Id: PagePerm.php,v 1.26 2004-06-14 11:31:36 rurban Exp $');
3 /*
4  Copyright 2004 $ThePhpWikiProgrammingTeam
5
6  This file is part of PhpWiki.
7
8  PhpWiki is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12
13  PhpWiki is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with PhpWiki; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 /**
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)
28
29    Permissions may be inherited from its parent pages, a optional the 
30    optional master page ("."), and predefined default permissions, if "." 
31    is not defined.
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
35
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, 
42        when login is tried.
43      Request::getDisallowedActionDescription($action)
44        helper to localize the _notAuthorized message per action, 
45        when it aborts
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 
51        action + page pair
52
53      The defined main.php actions map to simplier access types:
54        browse => view
55        edit   => edit
56        create => edit or create
57        remove => remove
58        rename => change
59        store prefs => change
60        list in PageList => list
61 */
62
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');
73
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) {
79     global $request;
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());
85         else {
86             return array('inherited',pagePermissions(getParentPage($pagename)));
87         }
88     } elseif ($perm = getPagePermissions($page)) {
89         return array('page',$perm);
90     // or no permissions defined; returned inherited permissions, to be displayed in gray
91     } else {
92         return array('inherited',pagePermissions(getParentPage($pagename)));
93     }
94 }
95
96 function pagePermissionsSimpleFormat($perm_tree, $owner, $group=false) {
97     list($type,$perm) = pagePermissionsAcl($perm_tree[0], $perm_tree);
98     /*
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'))
108             return $perm_tree;
109     }
110     */
111     if ($type == 'page')
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));
118     }
119 }
120
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];
126     }
127     return array($type,$perm);
128 }
129
130 // view => who
131 // edit => who
132 function pagePermissionsAclFormat($perm_tree, $editable=false) {
133     list($type,$perm) = pagePermissionsAcl($perm_tree[0], $perm_tree);
134     if ($editable)
135         return $perm->asEditableTable($type);
136     else
137         return $perm->asTable($type);
138 }
139
140 /**
141  * Check permission per page.
142  * Returns true or false.
143  */
144 function mayAccessPage ($access, $pagename) {
145     if (ENABLE_PAGEPERM)
146         return _requiredAuthorityForPagename($access, $pagename);
147     else
148         return true;
149 }
150
151 /** 
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?
157  */
158 function requiredAuthorityForPage ($action) {
159     $auth = _requiredAuthorityForPagename(action2access($action),
160                                           $GLOBALS['request']->getArg('pagename'));
161     assert($auth !== -1);
162     if ($auth)
163         return $GLOBALS['request']->_user->_level;
164     else
165         return WIKIAUTH_UNOBTAINABLE;
166 }
167
168 // Translate action or plugin to the simplier access types:
169 function action2access ($action) {
170     global $request;
171     switch ($action) {
172     case 'browse':
173     case 'viewsource':
174     case 'diff':
175     case 'select':
176     case 'xmlrpc':
177     case 'search':
178     case 'pdf':
179         return 'view';
180     case 'zip':
181     case 'ziphtml':
182     case 'dumpserial':
183     case 'dumphtml':
184         return 'dump';
185     case 'revert':
186     case 'edit':
187         return 'edit';
188     case 'create':
189         $page = $request->getPage();
190         $current = $page->getCurrentRevision();
191         if ($current->hasDefaultContents())
192             return 'edit';
193         else
194             return 'view'; 
195         break;
196     case 'upload':
197     case 'loadfile': 
198         // probably create/edit but we cannot check all page permissions, can we?
199     case 'remove':
200     case 'lock':
201     case 'unlock':
202     case 'upgrade':
203     case 'chown':
204     case 'setacl':
205     case 'rename':
206             return 'change';
207     default:
208         //Todo: Plugins should be able to override its access type
209         if (isWikiWord($action))
210             return 'view';
211         else
212             return 'change';
213         break;
214     }
215 }
216
217 // Recursive helper to do the real work
218 function _requiredAuthorityForPagename($access, $pagename) {
219     global $request;
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);
225     }
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);
231         }
232         return _requiredAuthorityForPagename($access, getParentPage($pagename));
233     }
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
237         return $authorized;
238     else
239         return _requiredAuthorityForPagename($access, getParentPage($pagename));
240 }
241
242 /**
243  * @param  string $pagename   page from which the parent page is searched.
244  * @return string parent      pagename or the (possibly pseudo) dot-pagename.
245  */
246 function getParentPage($pagename) {
247     if (isSubPage($pagename)) {
248         return subPageSlice($pagename,0);
249     } else {
250         return '.';
251     }
252 }
253
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));
260     else 
261         return false;
262 }
263
264 // Store the ACL in the page
265 function setPagePermissions ($page,$perm) {
266     $perm->store($page);
267 }
268
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"),
280                                     );
281     }
282     if (in_array($access, array_keys($accessDescriptions)))
283         return $accessDescriptions[$access];
284     else
285         return $access;
286 }
287
288 // from php.net docs
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;
294              } else {
295                  $new_diff = array_diff_assoc_recursive($value, $array2[$key]);
296                  if ($new_diff != false) {
297                      $difference[$key] = $new_diff;
298                  } 
299              }
300          } elseif(!isset($array2[$key]) || $array2[$key] != $value) {
301              $difference[$key] = $value;
302          }
303     }
304     return !isset($difference) ? 0 : $difference;
305 }
306
307 /**
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.
310  *
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
314  *
315  * Define any special rules here, like don't list dot-pages.
316  */ 
317 class PagePermission {
318     var $perm;
319
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;
327                 else
328                     trigger_error(sprintf(_("Unsupported ACL access type %s ignored."), $access),
329                                   E_USER_WARNING);
330             }
331         } else {
332             // set default permissions, the so called dot-file acl's
333             $this->perm = $this->defaultPerms();
334         }
335         return $this;
336     }
337
338     /**
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).
342      */
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)) {
347                     return $bool;
348                 }
349             }
350         }
351         return -1; // undecided
352     }
353
354     /**
355      * Translate the various special groups to the actual users settings 
356      * (userid, group membership).
357      */
358     function isMember($user, $group) {
359         global $request;
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)
371             if (ENABLE_USER_NEW)
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());
385         }
386         if ($group === ACL_CREATOR) {
387             $page = $request->getPage();
388             return ($user->isAuthenticated() and 
389                     $page->getCreator() === $user->UserName());
390         }
391         /* Or named groups or usernames.
392            Note: We don't seperate groups and users here. 
393            Users overrides groups with the same name. 
394         */
395         return $user->UserName() === $group or
396                $member->isMember($group);
397     }
398
399     /**
400      * returns hash of default permissions.
401      * check if the page '.' exists and returns this instead.
402      */
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,
411                                         ACL_OWNER => true),
412                       'change' => array(ACL_ADMIN => true,
413                                         ACL_OWNER => true));
414         if (ZIPDUMP_AUTH)
415             $perm['dump'] = array(ACL_ADMIN => true,
416                                   ACL_OWNER => true);
417         else
418             $perm['dump'] = array(ACL_EVERY => true);
419         // view:
420         if (!ALLOW_ANON_USER) {
421             if (!ALLOW_USER_PASSWORDS) 
422                 $perm['view'] = array(ACL_SIGNED => true);
423             else                
424                 $perm['view'] = array(ACL_AUTHENTICATED => true);
425             $perm['view'][ACL_BOGOUSER] = ALLOW_BOGO_LOGIN ? true : false;
426         }
427         // edit:
428         if (!ALLOW_ANON_EDIT) {
429             if (!ALLOW_USER_PASSWORDS) 
430                 $perm['edit'] = array(ACL_SIGNED => true);
431             else                
432                 $perm['edit'] = array(ACL_AUTHENTICATED => true);
433             $perm['edit'][ACL_BOGOUSER] = ALLOW_BOGO_LOGIN ? true : false;
434             $perm['create'] = $perm['edit'];
435         }
436         return $perm;
437     }
438
439     /**
440      * FIXME: check valid groups and access
441      */
442     function sanify() {
443         foreach ($this->perm as $access => $groups) {
444             foreach ($groups as $group => $bool) {
445                 $this->perm[$access][$group] = (boolean) $bool;
446             }
447         }
448     }
449
450     /**
451      * do a recursive comparison
452      */
453     function equal($otherperm) {
454         $diff = array_diff_assoc_recursive($this->perm, $otherperm);
455         return empty($diff);
456     }
457     
458     /**
459      * returns list of all supported access types.
460      */
461     function accessTypes() {
462         return array_keys(PagePermission::defaultPerms());
463     }
464
465     /**
466      * special permissions for dot-files, beginning with '.'
467      * maybe also for '_' files?
468      */
469     function dotPerms() {
470         $def = array(ACL_ADMIN => true,
471                      ACL_OWNER => true);
472         $perm = array();
473         foreach (PagePermission::accessTypes() as $access) {
474             $perm[$access] = $def;
475         }
476         return $perm;
477     }
478
479     /**
480      *  dead code. not needed inside the object. see getPagePermissions($page)
481      */
482     function retrieve($page) {
483         $hash = $page->get('perm');
484         if ($hash)  // hash => object
485             $perm = new PagePermission(unserialize($hash));
486         else 
487             $perm = new PagePermission();
488         $perm->sanify();
489         return $perm;
490     }
491
492     function store($page) {
493         // object => hash
494         $this->sanify();
495         return $page->set('perm',serialize($this->perm));
496     }
497
498     function groupName ($group) {
499         if ($group[0] == '_') return constant("GROUP".$group);
500         else return $group;
501     }
502     
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]' : '[ ]')));
511             }
512             $table->pushContent(HTML::tr(array('valign' => 'top'),
513                                          HTML::td($access),HTML::td($td)));
514         }
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;');
521         return $table;
522     }
523     
524     /* type: page, default, inherited */
525     function asEditableTable($type) {
526         global $WikiTheme;
527         if (!isset($this->_group)) { 
528             $this->_group =& WikiGroup::getGroup($GLOBALS['request']);
529         }
530         $table = HTML::table();
531         $table->pushContent(HTML::tr(
532                                      HTML::th(array('align' => 'left'),
533                                               _("Access")),
534                                      HTML::th(array('align'=>'right'),
535                                               _("Group/User")),
536                                      HTML::th(_("Grant")),
537                                      HTML::th(_("Del/+")),
538                                      HTML::th(_("Description"))));
539         
540         $allGroups = $this->_group->_specialGroups();
541         foreach ($this->_group->getAllGroupsIn() as $group) {
542             if (!in_array($group,$this->_group->specialGroups()))
543                 $allGroups[] = $group;
544         }
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('&nbsp;');
549         foreach ($this->perm as $access => $groups) {
550             //$permlist = HTML::table(array('class' => 'cal','valign' => 'top'));
551             $first_only = true;
552             $newperm = HTML::input(array('type' => 'checkbox',
553                                          'name' => "acl[_new_perm][$access]",
554                                          'value' => 1));
555             $addbutton = HTML::input(array('type' => 'checkbox',
556                                            'name' => "acl[_add_group][$access]",
557                                            //'src'  => $addsrc,
558                                            //'alt'   => "Add",
559                                            'title' => _("Add this ACL"),
560                                            'value' => 1));
561             $newgroup = HTML::select(array('name' => "acl[_new_group][$access]",
562                                            'style'=> 'text-align: right;',
563                                            'size' => 1));
564             foreach ($allGroups as $groupname) {
565                 if (!isset($groups[$groupname]))
566                     $newgroup->pushContent(HTML::option(array('value' => $groupname),
567                                                         $this->groupName($groupname)));
568             }
569             if (empty($groups)) {
570                 $addbutton->setAttr('checked','checked');
571                 $newperm->setAttr('checked','checked');
572                 $table->pushContent(
573                     HTML::tr(array('valign' => 'top'),
574                              HTML::td(HTML::strong($access.":")),
575                              HTML::td($newgroup),
576                              HTML::td($nbsp,$newperm),
577                              HTML::td($nbsp,$addbutton),
578                              HTML::td(HTML::em(getAccessDescription($access)))));
579             }
580             foreach ($groups as $group => $bool) {
581                 $checkbox = HTML::input(array('type' => 'checkbox',
582                                               'name' => "acl[$access][$group]",
583                                               'title' => _("Allow / Deny"),
584                                               'value' => 1));
585                 if ($bool) $checkbox->setAttr('checked','checked');
586                 $checkbox = HTML(HTML::input(array('type' => 'hidden',
587                                                    'name' => "acl[$access][$group]",
588                                                    'value' => 0)),
589                                  $checkbox);
590                 $deletebutton = HTML::input(array('type' => 'checkbox',
591                                                   'name' => "acl[_del_group][$access][$group]",
592                                                   'style' => 'background: #aaa url('.$deletesrc.')',
593                                                   //'src'  => $deletesrc,
594                                                   //'alt'   => "Del",
595                                                   'title' => _("Delete this ACL"),
596                                                   'value' => 1));
597                 if ($first_only) {
598                     $table->pushContent(
599                         HTML::tr(
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)))));
606                     $first_only = false;
607                 } else {
608                     $table->pushContent(
609                         HTML::tr(
610                                  HTML::td(),
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),
615                                  HTML::td()));
616                 }
617             }
618             if (!empty($groups))
619                 $table->pushContent(
620                     HTML::tr(array('valign' => 'top'),
621                              HTML::td(array('align'=>'right'),_("add ")),
622                              HTML::td($newgroup),
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")))));
626         }
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;');
633         return $table;
634     }
635
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() {
641         $s = ''; $line = '';
642         $this->sanify();
643         foreach ($this->perm as $access => $groups) {
644             // unify groups for same access+bool
645             //    view:CREATOR,-OWNER,
646             $line = $access.':';
647             foreach ($groups as $group => $bool) {
648                 $line .= ($bool?'':'-').$group.",";
649             }
650             if (substr($line,-1) == ',')
651                 $s .= substr($line,0,-1)."; ";
652         }
653         if (substr($s,-2) == '; ')
654             $s = substr($s,0,-2);
655         return $s;
656     }
657
658
659     // This is just a bad hack for testing.
660     // Simplify the ACL to a unix-like "rwx------+" string
661     // See getfacl(8)
662     function asRwxString($owner,$group=false) {
663         global $request;
664         // simplify object => rwxrw---x+ string as in cygwin (+ denotes additional ACLs)
665         $perm =& $this->perm;
666         // get effective user and group
667         $s = '---------+';
668         if (isset($perm['view'][$owner]) or 
669             (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
670             $s[0] = 'r';
671         if (isset($perm['edit'][$owner]) or 
672             (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
673             $s[1] = 'w';
674         if (isset($perm['change'][$owner]) or 
675             (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
676             $s[2] = 'x';
677         if (!empty($group)) {
678             if (isset($perm['view'][$group]) or 
679                 (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
680                 $s[3] = 'r';
681             if (isset($perm['edit'][$group]) or 
682                 (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
683                 $s[4] = 'w';
684             if (isset($perm['change'][$group]) or 
685                 (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
686                 $s[5] = 'x';
687         }
688         if (isset($perm['view'][ACL_EVERY]) or 
689             (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
690             $s[6] = 'r';
691         if (isset($perm['edit'][ACL_EVERY]) or 
692             (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
693             $s[7] = 'w';
694         if (isset($perm['change'][ACL_EVERY]) or 
695             (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
696             $s[8] = 'x';
697         return $s;
698     }
699 }
700
701 // $Log: not supported by cvs2svn $
702 // Revision 1.25  2004/06/08 13:51:57  rurban
703 // some comments only
704 //
705 // Revision 1.24  2004/06/08 10:54:46  rurban
706 // better acl dump representation, read back acl and owner
707 //
708 // Revision 1.23  2004/06/08 10:05:11  rurban
709 // simplified admin action shortcuts
710 //
711 // Revision 1.22  2004/06/07 22:44:14  rurban
712 // added simplified chown, setacl actions
713 //
714 // Revision 1.21  2004/06/07 22:28:03  rurban
715 // add acl field to mimified dump
716 //
717 // Revision 1.20  2004/06/07 18:39:03  rurban
718 // support for SetAclSimple
719 //
720 // Revision 1.19  2004/06/06 17:12:28  rurban
721 // fixed PagePerm non-object problem (mayAccessPage), also bug #967150
722 //
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
731 //
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.
736 //
737 // Revision 1.16  2004/05/16 22:32:53  rurban
738 // setacl icons
739 //
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
747 //
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.
751 //
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
757 //
758 // Revision 1.12  2004/05/04 22:34:25  rurban
759 // more pdf support
760 //
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
768 //
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.
771 //
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.
774 //
775 // Revision 1.8  2004/03/14 16:24:35  rurban
776 // authenti(fi)cation spelling
777 //
778 // Revision 1.7  2004/02/28 22:25:07  rurban
779 // First PagePerm implementation:
780 //
781 // $WikiTheme->setAnonEditUnknownLinks(false);
782 //
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.
788 //
789 // Revision 1.6  2004/02/24 15:20:05  rurban
790 // fixed minor warnings: unchecked args, POST => Get urls for sortby e.g.
791 //
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
795 //   not yet working.
796 //
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)
801 //
802 // Revision 1.3  2004/02/09 03:58:12  rurban
803 // for now default DB_SESSION to false
804 // PagePerm:
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
809 // WikiUserNew:
810 //   * added global ->prepare (not yet used) with smart user/pref/member table prefixing.
811 //   * force init of authdbh in the 2 db classes
812 // main:
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
816 //
817 // Revision 1.2  2004/02/08 13:17:48  rurban
818 // This should be the functionality. Needs testing and some minor todos.
819 //
820 // Revision 1.1  2004/02/08 12:29:30  rurban
821 // initial version, not yet hooked into lib/main.php
822 //
823 //
824
825 // Local Variables:
826 // mode: php
827 // tab-width: 8
828 // c-basic-offset: 4
829 // c-hanging-comment-ender-p: nil
830 // indent-tabs-mode: nil
831 // End:
832 ?>