diff --git a/helper.php b/helper.php new file mode 100644 index 0000000..c24c4ce --- /dev/null +++ b/helper.php @@ -0,0 +1,76 @@ + + */ + +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +/** + * Class helper_plugin_aclinfo + */ +class helper_plugin_aclinfo extends DokuWiki_Plugin { + + /** + * Create a list of file permissions for a page + * + * @param string $pageid + */ + public function getACLInfo($page) { + global $AUTH_ACL; + + $info = array(); + $subjects = array(); + + /* + * Get the permissions for @ALL in the beginning, we will use it + * to compare and filter other permissions that are lower. + */ + $allperm = auth_aclcheck($page, '', array('ALL')); + + /* + * Go through each entry of the ACL rules. + */ + foreach($AUTH_ACL as $rule){ + $rule = preg_replace('/#.*$/', '', $rule); // Ignore comments + $subject = preg_split('/[ \t]+/', $rule)[1]; + $subject = urldecode($subject); + $groups = array(); + $user = ''; + + // Skip if we already checked this user/group + if(in_array($subject, $subjects)) + continue; + + $subjects[] = $subject; + + // Check if this entry is about a user or a group (starting with '@') + if(substr($subject, 0, 1) === '@') + $groups[] = substr($subject, 1); + else + $user = $subject; + + $perm = auth_aclcheck($page, $user, $groups); + + // Skip permissions of 0 or if lower than @ALL + if($perm == AUTH_NONE || ($subject != '@ALL' && $perm <= $allperm)) + continue; + + $info[] = array('subject' => $subject, 'perm' => $perm); + } + + return $info; + } + + /** + * Get a string representation for the permission info + * + * @param array $info + */ + public function getACLInfoString($info) { + return sprintf($this->getLang('perm'.$info['perm']), $info['subject']); + } +} diff --git a/syntax.php b/syntax.php index 800587d..27f6b20 100644 --- a/syntax.php +++ b/syntax.php @@ -2,6 +2,7 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr + * @author Frieder Schrempf */ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); @@ -14,6 +15,15 @@ * need to inherit from this class */ class syntax_plugin_aclinfo extends DokuWiki_Syntax_Plugin { + /** @var helper_plugin_aclinfo */ + protected $helper; + + /** + * syntax_plugin_aclinfo constructor. + */ + public function __construct() { + $this->helper = plugin_load('helper', 'aclinfo'); + } /** * What kind of syntax are we? @@ -58,6 +68,7 @@ function handle($match, $state, $pos, Doku_Handler $handler){ */ function render($format, Doku_Renderer $R, $data) { global $INFO; + if($format != 'xhtml') return false; if(!$data[0]) { @@ -66,71 +77,23 @@ function render($format, Doku_Renderer $R, $data) { $page = $data[0]; } - $perms = $this->_aclcheck($page); + $info = $this->helper->getACLInfo($page); + $R->listu_open(); - foreach((array)$perms as $who => $p){ + + /* + * Go through each entry of the ACL rules. + */ + foreach($info as $entry){ $R->listitem_open(1); $R->listcontent_open(); - $R->cdata(sprintf($this->getLang('perm'.$p), urldecode($who))); + $R->cdata($this->helper->getACLInfoString($entry)); $R->listcontent_close(); $R->listitem_close(); } $R->listu_close(); return true; } - - function _aclcheck($id){ - global $conf; - global $AUTH_ACL; - - $id = cleanID($id); - $ns = getNS($id); - $perms = array(); - - //check exact match first - $matches = preg_grep('/^'.preg_quote($id,'/').'\s+/',$AUTH_ACL); - if(count($matches)){ - foreach($matches as $match){ - $match = preg_replace('/#.*$/','',$match); //ignore comments - $acl = preg_split('/\s+/',$match); - if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL! - if(!isset($perms[$acl[1]])) $perms[$acl[1]] = $acl[2]; - } - } - - //still here? do the namespace checks - if($ns){ - $path = $ns.':\*'; - }else{ - $path = '\*'; //root document - } - - do{ - $matches = preg_grep('/^'.$path.'\s+/',$AUTH_ACL); - if(count($matches)){ - foreach($matches as $match){ - $match = preg_replace('/#.*$/','',$match); //ignore comments - $acl = preg_split('/\s+/',$match); - if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL! - if(!isset($perms[$acl[1]])) $perms[$acl[1]] = $acl[2]; - } - } - - //get next higher namespace - $ns = getNS($ns); - - if($path != '\*'){ - $path = $ns.':\*'; - if($path == ':\*') $path = '\*'; - }else{ - //we did this already - //break here - break; - } - }while(1); //this should never loop endless - - return $perms; - } } //Setup VIM: ex: et ts=4 enc=utf-8 :