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