]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/PagePerm.php
added simplified chown, setacl actions
[SourceForge/phpwiki.git] / lib / PagePerm.php
1 <?php // -*-php-*-
2 rcs_id('$Id: PagePerm.php,v 1.22 2004-06-07 22:44:14 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::bold($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 'edit':
186         return 'edit';
187     case 'create':
188         $page = $request->getPage();
189         $current = $page->getCurrentRevision();
190         if ($current->hasDefaultContents())
191             return 'edit';
192         else
193             return 'view'; 
194         break;
195     case 'upload':
196     case 'loadfile': 
197         // probably create/edit but we cannot check all page permissions, can we?
198     case 'remove':
199     case 'lock':
200     case 'unlock':
201     case 'upgrade':
202     case 'chown':
203     case 'setacl':
204             return 'change';
205     default:
206         //Todo: Plugins should be able to override its access type
207         if (isWikiWord($action))
208             return 'view';
209         else
210             return 'change';
211         break;
212     }
213 }
214
215 // Recursive helper to do the real work
216 function _requiredAuthorityForPagename($access, $pagename) {
217     global $request;
218     $page = $request->getPage($pagename);
219     // Page not found; check against default permissions
220     if (! $page->exists() ) {
221         $perm = new PagePermission();
222         return ($perm->isAuthorized($access, $request->_user) === true);
223     }
224     // no ACL defined; check for special dotfile or walk down
225     if (! ($perm = getPagePermissions($page))) { 
226         if ($pagename[0] == '.') {
227             $perm = new PagePermission(PagePermission::dotPerms());
228             return ($perm->isAuthorized($access, $request->_user) === true);
229         }
230         return _requiredAuthorityForPagename($access, getParentPage($pagename));
231     }
232     // ACL defined; check if isAuthorized returns true or false or undecided
233     $authorized = $perm->isAuthorized($access, $request->_user);
234     if ($authorized != -1) // -1 for undecided
235         return $authorized;
236     else
237         return _requiredAuthorityForPagename($access, getParentPage($pagename));
238 }
239
240 /**
241  * @param  string $pagename   page from which the parent page is searched.
242  * @return string parent      pagename or the (possibly pseudo) dot-pagename.
243  */
244 function getParentPage($pagename) {
245     if (isSubPage($pagename)) {
246         return subPageSlice($pagename,0);
247     } else {
248         return '.';
249     }
250 }
251
252 // Read the ACL from the page
253 // Done: Not existing pages should NOT be queried. 
254 // Check the parent page instead and don't take the default ACL's
255 function getPagePermissions ($page) {
256     if ($hash = $page->get('perm'))  // hash => object
257         return new PagePermission(unserialize($hash));
258     else 
259         return false;
260 }
261
262 // Store the ACL in the page
263 function setPagePermissions ($page,$perm) {
264     $perm->store($page);
265 }
266
267 function getAccessDescription($access) {
268     static $accessDescriptions;
269     if (! $accessDescriptions) {
270         $accessDescriptions = array(
271                                     'list'     => _("List this page and all subpages"),
272                                     'view'     => _("View this page and all subpages"),
273                                     'edit'     => _("Edit this page and all subpages"),
274                                     'create'   => _("Create a new (sub)page"),
275                                     'dump'     => _("Download the page contents"),
276                                     'change'   => _("Change page attributes"),
277                                     'remove'   => _("Remove this page"),
278                                     );
279     }
280     if (in_array($access, array_keys($accessDescriptions)))
281         return $accessDescriptions[$access];
282     else
283         return $access;
284 }
285
286 // from php.net docs
287 function array_diff_assoc_recursive($array1, $array2) {
288     foreach ($array1 as $key => $value) {
289          if (is_array($value)) {
290              if (!is_array($array2[$key])) {
291                  $difference[$key] = $value;
292              } else {
293                  $new_diff = array_diff_assoc_recursive($value, $array2[$key]);
294                  if ($new_diff != false) {
295                      $difference[$key] = $new_diff;
296                  } 
297              }
298          } elseif(!isset($array2[$key]) || $array2[$key] != $value) {
299              $difference[$key] = $value;
300          }
301     }
302     return !isset($difference) ? 0 : $difference;
303 }
304
305 /**
306  * The ACL object per page. It is stored in a page, but can also 
307  * be merged with ACL's from other pages or taken from the master (pseudo) dot-file.
308  *
309  * A hash of "access" => "requires" pairs.
310  *   "access"   is a shortcut for common actions, which map to main.php actions
311  *   "requires" required username or groupname or any special group => true or false
312  *
313  * Define any special rules here, like don't list dot-pages.
314  */ 
315 class PagePermission {
316     var $perm;
317
318     function PagePermission($hash = array()) {
319         $this->_group = &WikiGroup::getGroup($GLOBALS['request']);
320         if (is_array($hash) and !empty($hash)) {
321             $accessTypes = $this->accessTypes();
322             foreach ($hash as $access => $requires) {
323                 if (in_array($access, $accessTypes))
324                     $this->perm[$access] = $requires;
325                 else
326                     trigger_error(sprintf(_("Unsupported ACL access type %s ignored."), $access),
327                                   E_USER_WARNING);
328             }
329         } else {
330             // set default permissions, the so called dot-file acl's
331             $this->perm = $this->defaultPerms();
332         }
333         return $this;
334     }
335
336     /**
337      * The workhorse to check the user against the current ACL pairs.
338      * Must translate the various special groups to the actual users settings 
339      * (userid, group membership).
340      */
341     function isAuthorized($access,$user) {
342         if (!empty($this->perm{$access})) {
343             foreach ($this->perm[$access] as $group => $bool) {
344                 if ($this->isMember($user,$group)) {
345                     return $bool;
346                 }
347             }
348         }
349         return -1; // undecided
350     }
351
352     /**
353      * Translate the various special groups to the actual users settings 
354      * (userid, group membership).
355      */
356     function isMember($user, $group) {
357         global $request;
358         if ($group === ACL_EVERY) return true;
359         if (!isset($this->_group)) $member =& WikiGroup::getGroup($request);
360         else $member =& $this->_group;
361         //$user = & $request->_user;
362         if ($group === ACL_ADMIN)   // WIKI_ADMIN or member of _("Administrators")
363             return $user->isAdmin() or 
364                    ($user->isAuthenticated() and 
365                    $member->isMember(GROUP_ADMIN));
366         if ($group === ACL_ANONYMOUS) 
367             return ! $user->isSignedIn();
368         if ($group === ACL_BOGOUSER)
369             if (ENABLE_USER_NEW)
370                 return isa($user,'_BogoUser') or 
371                       (isWikiWord($user->_userid) and $user->_level >= WIKIAUTH_BOGO);
372             else return isWikiWord($user->UserName());
373         if ($group === ACL_HASHOMEPAGE)
374             return $user->hasHomePage();
375         if ($group === ACL_SIGNED)
376             return $user->isSignedIn();
377         if ($group === ACL_AUTHENTICATED)
378             return $user->isAuthenticated();
379         if ($group === ACL_OWNER) {
380             $page = $request->getPage();
381             return ($user->isAuthenticated() and 
382                     $page->getOwner() === $user->UserName());
383         }
384         if ($group === ACL_CREATOR) {
385             $page = $request->getPage();
386             return ($user->isAuthenticated() and 
387                     $page->getCreator() === $user->UserName());
388         }
389         /* Or named groups or usernames.
390            Note: We don't seperate groups and users here. 
391            Users overrides groups with the same name. 
392         */
393         return $user->UserName() === $group or
394                $member->isMember($group);
395     }
396
397     /**
398      * returns hash of default permissions.
399      * check if the page '.' exists and returns this instead.
400      */
401     function defaultPerms() {
402         //Todo: check for the existance of '.' and take this instead.
403         //Todo: honor more config.ini auth settings here
404         $perm = array('view'   => array(ACL_EVERY => true),
405                       'edit'   => array(ACL_EVERY => true),
406                       'create' => array(ACL_EVERY => true),
407                       'list'   => array(ACL_EVERY => true),
408                       'remove' => array(ACL_ADMIN => true,
409                                         ACL_OWNER => true),
410                       'change' => array(ACL_ADMIN => true,
411                                         ACL_OWNER => true));
412         if (ZIPDUMP_AUTH)
413             $perm['dump'] = array(ACL_ADMIN => true,
414                                   ACL_OWNER => true);
415         else
416             $perm['dump'] = array(ACL_EVERY => true);
417         // view:
418         if (!ALLOW_ANON_USER) {
419             if (!ALLOW_USER_PASSWORDS) 
420                 $perm['view'] = array(ACL_SIGNED => true);
421             else                
422                 $perm['view'] = array(ACL_AUTHENTICATED => true);
423             $perm['view'][ACL_BOGOUSER] = ALLOW_BOGO_LOGIN ? true : false;
424         }
425         // edit:
426         if (!ALLOW_ANON_EDIT) {
427             if (!ALLOW_USER_PASSWORDS) 
428                 $perm['edit'] = array(ACL_SIGNED => true);
429             else                
430                 $perm['edit'] = array(ACL_AUTHENTICATED => true);
431             $perm['edit'][ACL_BOGOUSER] = ALLOW_BOGO_LOGIN ? true : false;
432             $perm['create'] = $perm['edit'];
433         }
434         return $perm;
435     }
436
437     function sanify() {
438         foreach ($this->perm as $access => $groups) {
439             foreach ($groups as $group => $bool) {
440                 $this->perm[$access][$group] = (boolean) $bool;
441             }
442         }
443     }
444
445     /**
446      * do a recursive comparison
447      */
448     function equal($otherperm) {
449         $diff = array_diff_assoc_recursive($this->perm, $otherperm);
450         return empty($diff);
451     }
452     
453     /**
454      * returns list of all supported access types.
455      */
456     function accessTypes() {
457         return array_keys(PagePermission::defaultPerms());
458     }
459
460     /**
461      * special permissions for dot-files, beginning with '.'
462      * maybe also for '_' files?
463      */
464     function dotPerms() {
465         $def = array(ACL_ADMIN => true,
466                      ACL_OWNER => true);
467         $perm = array();
468         foreach (PagePermission::accessTypes() as $access) {
469             $perm[$access] = $def;
470         }
471         return $perm;
472     }
473
474     /**
475      *  dead code. not needed inside the object. see getPagePermissions($page)
476      */
477     function retrieve($page) {
478         $hash = $page->get('perm');
479         if ($hash)  // hash => object
480             $perm = new PagePermission(unserialize($hash));
481         else 
482             $perm = new PagePermission();
483         $perm->sanify();
484         return $perm;
485     }
486
487     function store($page) {
488         // object => hash
489         $this->sanify();
490         return $page->set('perm',serialize($this->perm));
491     }
492
493     function groupName ($group) {
494         if ($group[0] == '_') return constant("GROUP".$group);
495         else return $group;
496     }
497     
498     /* type: page, default, inherited */
499     function asTable($type) {
500         $table = HTML::table();
501         foreach ($this->perm as $access => $perms) {
502             $td = HTML::table(array('class' => 'cal','valign' => 'top'));
503             foreach ($perms as $group => $bool) {
504                 $td->pushContent(HTML::tr(HTML::td(array('align'=>'right'),$group),
505                                                    HTML::td($bool ? '[X]' : '[ ]')));
506             }
507             $table->pushContent(HTML::tr(array('valign' => 'top'),
508                                          HTML::td($access),HTML::td($td)));
509         }
510         if ($type == 'default')
511             $table->setAttr('style','border: dotted thin black; background-color:#eee;');
512         elseif ($type == 'inherited')
513             $table->setAttr('style','border: dotted thin black; background-color:#ddd;');
514         elseif ($type == 'page')
515             $table->setAttr('style','border: solid thin black; font-weight: bold;');
516         return $table;
517     }
518     
519     /* type: page, default, inherited */
520     function asEditableTable($type) {
521         global $Theme;
522         if (!isset($this->_group)) { 
523             $this->_group =& WikiGroup::getGroup($GLOBALS['request']);
524         }
525         $table = HTML::table();
526         $table->pushContent(HTML::tr(
527                                      HTML::th(array('align' => 'left'),
528                                               _("Access")),
529                                      HTML::th(array('align'=>'right'),
530                                               _("Group/User")),
531                                      HTML::th(_("Grant")),
532                                      HTML::th(_("Del/+")),
533                                      HTML::th(_("Description"))));
534         
535         $allGroups = $this->_group->_specialGroups();
536         foreach ($this->_group->getAllGroupsIn() as $group) {
537             if (!in_array($group,$this->_group->specialGroups()))
538                 $allGroups[] = $group;
539         }
540         //array_unique(array_merge($this->_group->getAllGroupsIn(),
541         $deletesrc = $Theme->_findData('images/delete.png');
542         $addsrc = $Theme->_findData('images/add.png');
543         $nbsp = HTML::raw('&nbsp;');
544         foreach ($this->perm as $access => $groups) {
545             //$permlist = HTML::table(array('class' => 'cal','valign' => 'top'));
546             $first_only = true;
547             $newperm = HTML::input(array('type' => 'checkbox',
548                                          'name' => "acl[_new_perm][$access]",
549                                          'value' => 1));
550             $addbutton = HTML::input(array('type' => 'checkbox',
551                                            'name' => "acl[_add_group][$access]",
552                                            //'src'  => $addsrc,
553                                            //'alt'   => "Add",
554                                            'title' => _("Add this ACL"),
555                                            'value' => 1));
556             $newgroup = HTML::select(array('name' => "acl[_new_group][$access]",
557                                            'style'=> 'text-align: right;',
558                                            'size' => 1));
559             foreach ($allGroups as $groupname) {
560                 if (!isset($groups[$groupname]))
561                     $newgroup->pushContent(HTML::option(array('value' => $groupname),
562                                                         $this->groupName($groupname)));
563             }
564             if (empty($groups)) {
565                 $addbutton->setAttr('checked','checked');
566                 $newperm->setAttr('checked','checked');
567                 $table->pushContent(
568                     HTML::tr(array('valign' => 'top'),
569                              HTML::td(HTML::strong($access.":")),
570                              HTML::td($newgroup),
571                              HTML::td($nbsp,$newperm),
572                              HTML::td($nbsp,$addbutton),
573                              HTML::td(HTML::em(getAccessDescription($access)))));
574             }
575             foreach ($groups as $group => $bool) {
576                 $checkbox = HTML::input(array('type' => 'checkbox',
577                                               'name' => "acl[$access][$group]",
578                                               'title' => _("Allow / Deny"),
579                                               'value' => 1));
580                 if ($bool) $checkbox->setAttr('checked','checked');
581                 $checkbox = HTML(HTML::input(array('type' => 'hidden',
582                                                    'name' => "acl[$access][$group]",
583                                                    'value' => 0)),
584                                  $checkbox);
585                 $deletebutton = HTML::input(array('type' => 'checkbox',
586                                                   'name' => "acl[_del_group][$access][$group]",
587                                                   'style' => 'background: #aaa url('.$deletesrc.')',
588                                                   //'src'  => $deletesrc,
589                                                   //'alt'   => "Del",
590                                                   'title' => _("Delete this ACL"),
591                                                   'value' => 1));
592                 if ($first_only) {
593                     $table->pushContent(
594                         HTML::tr(
595                                  HTML::td(HTML::strong($access.":")),
596                                  HTML::td(array('class' => 'cal-today','align'=>'right'),
597                                           HTML::strong($this->groupName($group))),
598                                  HTML::td(array('align'=>'center'),$nbsp,$checkbox),
599                                  HTML::td(array('align'=>'right','style' => 'background: #aaa url('.$deletesrc.') no-repeat'),$deletebutton),
600                                  HTML::td(HTML::em(getAccessDescription($access)))));
601                     $first_only = false;
602                 } else {
603                     $table->pushContent(
604                         HTML::tr(
605                                  HTML::td(),
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()));
611                 }
612             }
613             if (!empty($groups))
614                 $table->pushContent(
615                     HTML::tr(array('valign' => 'top'),
616                              HTML::td(array('align'=>'right'),_("add ")),
617                              HTML::td($newgroup),
618                              HTML::td(array('align'=>'center'),$nbsp,$newperm),
619                              HTML::td(array('align'=>'right','style' => 'background: #ccc url('.$addsrc.') no-repeat'),$addbutton),
620                              HTML::td(HTML::small(_("Check to add this Acl")))));
621         }
622         if ($type == 'default')
623             $table->setAttr('style','border: dotted thin black; background-color:#eee;');
624         elseif ($type == 'inherited')
625             $table->setAttr('style','border: dotted thin black; background-color:#ddd;');
626         elseif ($type == 'page')
627             $table->setAttr('style','border: solid thin black; font-weight: bold;');
628         return $table;
629     }
630
631     // Print ACL as lines of [+-]user[,group,...]:access[,access...]
632     // Seperate acl's by whitespace (here "\n", but " " is also acceptable on reading)
633     // See http://opag.ca/wiki/HelpOnAccessControlLists
634     // As used by WikiAdminSetAclSimple
635     function asAclLines($group=false) {
636         $s = '';
637         $this->sanify();
638         foreach ($this->perm as $access => $groups) {
639             // TODO: unify groups for same access+bool
640             //    +CREATOR,OWNER:view
641             // TODO: unify access for same groups+bool
642             //    +OWNER:view,edit
643             foreach ($groups as $group => $bool) {
644                 $s .= ($bool?'+':'-').$this->groupName($group).':'.$access."\n";
645             }
646         }
647         return $s;
648     }
649
650
651     // This is just a bad hack for testing.
652     // Simplify the ACL to a unix-like "rwx------+" string
653     // See getfacl(8)
654     function asRwxString($owner,$group=false) {
655         global $request;
656         // simplify object => rwxrw---x+ string as in cygwin (+ denotes additional ACLs)
657         $perm =& $this->perm;
658         // get effective user and group
659         $s = '---------+';
660         if (isset($perm['view'][$owner]) or 
661             (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
662             $s[0] = 'r';
663         if (isset($perm['edit'][$owner]) or 
664             (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
665             $s[1] = 'w';
666         if (isset($perm['change'][$owner]) or 
667             (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
668             $s[2] = 'x';
669         if (!empty($group)) {
670             if (isset($perm['view'][$group]) or 
671                 (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
672                 $s[3] = 'r';
673             if (isset($perm['edit'][$group]) or 
674                 (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
675                 $s[4] = 'w';
676             if (isset($perm['change'][$group]) or 
677                 (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
678                 $s[5] = 'x';
679         }
680         if (isset($perm['view'][ACL_EVERY]) or 
681             (isset($perm['view'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
682             $s[6] = 'r';
683         if (isset($perm['edit'][ACL_EVERY]) or 
684             (isset($perm['edit'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
685             $s[7] = 'w';
686         if (isset($perm['change'][ACL_EVERY]) or 
687             (isset($perm['change'][ACL_AUTHENTICATED]) and $request->_user->isAuthenticated()))
688             $s[8] = 'x';
689         return $s;
690     }
691 }
692
693 // $Log: not supported by cvs2svn $
694 // Revision 1.21  2004/06/07 22:28:03  rurban
695 // add acl field to mimified dump
696 //
697 // Revision 1.20  2004/06/07 18:39:03  rurban
698 // support for SetAclSimple
699 //
700 // Revision 1.19  2004/06/06 17:12:28  rurban
701 // fixed PagePerm non-object problem (mayAccessPage), also bug #967150
702 //
703 // Revision 1.18  2004/05/27 17:49:05  rurban
704 // renamed DB_Session to DbSession (in CVS also)
705 // added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
706 // remove leading slash in error message
707 // added force_unlock parameter to File_Passwd (no return on stale locks)
708 // fixed adodb session AffectedRows
709 // added FileFinder helpers to unify local filenames and DATA_PATH names
710 // editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
711 //
712 // Revision 1.17  2004/05/16 23:10:44  rurban
713 // update_locale wrongly resetted LANG, which broke japanese.
714 // japanese now correctly uses EUC_JP, not utf-8.
715 // more charset and lang headers to help the browser.
716 //
717 // Revision 1.16  2004/05/16 22:32:53  rurban
718 // setacl icons
719 //
720 // Revision 1.15  2004/05/16 22:07:35  rurban
721 // check more config-default and predefined constants
722 // various PagePerm fixes:
723 //   fix default PagePerms, esp. edit and view for Bogo and Password users
724 //   implemented Creator and Owner
725 //   BOGOUSERS renamed to BOGOUSER
726 // fixed syntax errors in signin.tmpl
727 //
728 // Revision 1.14  2004/05/15 22:54:49  rurban
729 // fixed important WikiDB bug with DEBUG > 0: wrong assertion
730 // improved SetAcl (works) and PagePerms, some WikiGroup helpers.
731 //
732 // Revision 1.13  2004/05/15 19:48:33  rurban
733 // fix some too loose PagePerms for signed, but not authenticated users
734 //  (admin, owner, creator)
735 // no double login page header, better login msg.
736 // moved action_pdf to lib/pdf.php
737 //
738 // Revision 1.12  2004/05/04 22:34:25  rurban
739 // more pdf support
740 //
741 // Revision 1.11  2004/05/02 21:26:38  rurban
742 // limit user session data (HomePageHandle and auth_dbi have to invalidated anyway)
743 //   because they will not survive db sessions, if too large.
744 // extended action=upgrade
745 // some WikiTranslation button work
746 // revert WIKIAUTH_UNOBTAINABLE (need it for main.php)
747 // some temp. session debug statements
748 //
749 // Revision 1.10  2004/04/29 22:32:56  zorloc
750 // Slightly more elegant fix.  Instead of WIKIAUTH_FORBIDDEN, the current user's level + 1 is returned on a false.
751 //
752 // Revision 1.9  2004/04/29 17:18:19  zorloc
753 // 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.
754 //
755 // Revision 1.8  2004/03/14 16:24:35  rurban
756 // authenti(fi)cation spelling
757 //
758 // Revision 1.7  2004/02/28 22:25:07  rurban
759 // First PagePerm implementation:
760 //
761 // $Theme->setAnonEditUnknownLinks(false);
762 //
763 // Layout improvement with dangling links for mostly closed wiki's:
764 // If false, only users with edit permissions will be presented the
765 // special wikiunknown class with "?" and Tooltip.
766 // If true (default), any user will see the ?, but will be presented
767 // the PrintLoginForm on a click.
768 //
769 // Revision 1.6  2004/02/24 15:20:05  rurban
770 // fixed minor warnings: unchecked args, POST => Get urls for sortby e.g.
771 //
772 // Revision 1.5  2004/02/23 21:30:25  rurban
773 // more PagePerm stuff: (working against 1.4.0)
774 //   ACL editing and simplification of ACL's to simple rwx------ string
775 //   not yet working.
776 //
777 // Revision 1.4  2004/02/12 13:05:36  rurban
778 // Rename functional for PearDB backend
779 // some other minor changes
780 // SiteMap comes with a not yet functional feature request: includepages (tbd)
781 //
782 // Revision 1.3  2004/02/09 03:58:12  rurban
783 // for now default DB_SESSION to false
784 // PagePerm:
785 //   * not existing perms will now query the parent, and not
786 //     return the default perm
787 //   * added pagePermissions func which returns the object per page
788 //   * added getAccessDescription
789 // WikiUserNew:
790 //   * added global ->prepare (not yet used) with smart user/pref/member table prefixing.
791 //   * force init of authdbh in the 2 db classes
792 // main:
793 //   * fixed session handling (not triple auth request anymore)
794 //   * don't store cookie prefs with sessions
795 // stdlib: global obj2hash helper from _AuthInfo, also needed for PagePerm
796 //
797 // Revision 1.2  2004/02/08 13:17:48  rurban
798 // This should be the functionality. Needs testing and some minor todos.
799 //
800 // Revision 1.1  2004/02/08 12:29:30  rurban
801 // initial version, not yet hooked into lib/main.php
802 //
803 //
804
805 // Local Variables:
806 // mode: php
807 // tab-width: 8
808 // c-basic-offset: 4
809 // c-hanging-comment-ender-p: nil
810 // indent-tabs-mode: nil
811 // End:
812 ?>