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 if(method_exists($hlpACL, 'initAclConfig')) { 33 $hlpACL->initAclConfig(); 34 } else { 35 /** @deprecated Call for current stable release */ 36 $hlpACL->_init_acl_config(); 37 } 38 39 // ACL lines as array 40 $acl = $hlpACL->acl; 41 ksort($acl); 42 43 // check for exact id 44 if (isset($acl[$id])) { 45 // process matched rule 46 $this->addRule($acl[$id], $rules); 47 // stop traversing if we reached a total access block for @ALL 48 if (isset($acl[$id]['@ALL'])) return $rules; 49 } 50 51 // walk namespace segments up 52 $ns = $id; 53 do { 54 $ns = getNS($ns); 55 // no namespace, check permissions for root 56 if (!$ns && isset($acl['*'])) { 57 $this->addRule($acl['*'], $rules); 58 // stop traversing if we reached a total access block for @ALL 59 if (isset($acl['*']['@ALL'])) { 60 $ns = false; 61 continue; 62 } 63 } 64 // check namespace 65 if (isset($acl[$ns . ':*'])) { 66 $this->addRule($acl[$ns . ':*'], $rules); 67 // stop traversing if we reached a total access block for @ALL 68 if (isset($acl[$ns . ':*']['@ALL'])) $ns = false; 69 } 70 } while ($ns); 71 72 return $rules; 73 } 74 75 /** 76 * Splits a rule set into query-digestible chunks 77 * 78 * @param array $rules 79 * @return array 80 */ 81 public function splitRules($rules) 82 { 83 $splitACL = [ 84 'groups_include' => [], 85 'groups_exclude' => [], 86 'users_include' => [], 87 'users_exclude' => [], 88 ]; 89 90 foreach ($rules as $key => $perm) { 91 if (strpos($key, '@') === 0) { 92 $type = $perm ? 'groups_include' : 'groups_exclude'; 93 } else { 94 $type = $perm ? 'users_include' : 'users_exclude'; 95 } 96 $splitACL[$type][] = ltrim($key, '@'); 97 } 98 99 return $splitACL; 100 } 101 102 /** 103 * Adds specific access rules to a rule set covering a full namespace path. 104 * Omit access block for @ALL since it is assumed. 105 * 106 * @param array $rule Collection of access permissions for a certain location 107 * @param array $rules Set of rules already 108 */ 109 protected function addRule($rule, &$rules) 110 { 111 $localrules = []; 112 113 foreach ($rule as $key => $perm) { 114 // set read permissions for a given group or user 115 // but skip if already defined for a more specific path 116 if ($key !== '@ALL' && !array_key_exists($key, $rules)) { 117 $localrules[$key] = $perm > AUTH_NONE; 118 } elseif ($key === '@ALL' && $perm > AUTH_NONE) { 119 $localrules[$key] = true; 120 } 121 } 122 123 $rules = array_merge($rules, $localrules); 124 } 125} 126