1<?php 2/** 3 * DokuWiki Plugin elasticsearch (Helper Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Andreas Gohr <gohr@cosmocode.de> 7 * @author Anna Dabrowska <dabrowska@cosmocode.de> 8 */ 9 10// must be run within Dokuwiki 11if(!defined('DOKU_INC')) die(); 12 13/** 14 * User-independent ACL methods 15 */ 16class helper_plugin_elasticsearch_acl extends DokuWiki_Plugin 17{ 18 /** 19 * Returns a full list of (read) permissions for users and groups whose access to a given page 20 * is defined in the ACLs. 21 * Traverses the whole rule set and resolves overrides and exclusions. 22 * 23 * @param string $id Page id 24 * @return array 25 */ 26 public function getPageACL($id) { 27 $id = cleanID($id); 28 $rules = []; 29 30 /** @var admin_plugin_acl $hlpACL */ 31 $hlpACL = plugin_load('admin', 'acl'); 32 $hlpACL->_init_acl_config(); 33 34 // ACL lines as array 35 $acl = $hlpACL->acl; 36 ksort($acl); 37 38 // check for exact id 39 if (isset($acl[$id])) { 40 // process matched rule 41 $this->addRule($acl[$id], $rules); 42 // stop traversing if we reached a total access block for @ALL 43 if (isset($acl[$id]['@ALL'])) return $rules; 44 } 45 46 // walk namespace segments up 47 $ns = $id; 48 do { 49 $ns = getNS($ns); 50 // no namespace, check permissions for root 51 if (!$ns && isset($acl['*'])) { 52 $this->addRule($acl['*'], $rules); 53 // stop traversing if we reached a total access block for @ALL 54 if (isset($acl['*']['@ALL'])) { 55 $ns = false; 56 continue; 57 } 58 } 59 // check namespace 60 if (isset($acl[$ns . ':*'])) { 61 $this->addRule($acl[$ns . ':*'], $rules); 62 // stop traversing if we reached a total access block for @ALL 63 if (isset($acl[$ns . ':*']['@ALL'])) $ns = false; 64 } 65 } while ($ns); 66 67 return $rules; 68 } 69 70 /** 71 * Splits a rule set into query-digestible chunks 72 * 73 * @param array $rules 74 * @return array 75 */ 76 public function splitRules($rules) 77 { 78 $splitACL = [ 79 'groups_include' => [], 80 'groups_exclude' => [], 81 'users_include' => [], 82 'users_exclude' => [], 83 ]; 84 85 foreach ($rules as $key => $perm) { 86 if (strpos($key, '@') === 0) { 87 $type = $perm ? 'groups_include' : 'groups_exclude'; 88 } else { 89 $type = $perm ? 'users_include' : 'users_exclude'; 90 } 91 $splitACL[$type][] = ltrim($key, '@'); 92 } 93 94 return $splitACL; 95 } 96 97 /** 98 * Adds specific access rules to a rule set covering a full namespace path. 99 * Omit access block for @ALL since it is assumed. 100 * 101 * @param array $rule Collection of access permissions for a certain location 102 * @param array $rules Set of rules already 103 */ 104 protected function addRule($rule, &$rules) 105 { 106 $localrules = []; 107 108 foreach ($rule as $key => $perm) { 109 // set read permissions for a given group or user 110 // but skip if already defined for a more specific path 111 if ($key !== '@ALL' && !array_key_exists($key, $rules)) { 112 $localrules[$key] = $perm > AUTH_NONE; 113 } elseif ($key === '@ALL' && $perm > AUTH_NONE) { 114 $localrules[$key] = true; 115 } 116 } 117 118 $rules = array_merge($rules, $localrules); 119 } 120} 121