1<?php 2 3/** 4 * Class action_plugin_usermanagerextended_extend 5 */ 6class action_plugin_usermanagerextended_extend extends DokuWiki_Action_Plugin 7{ 8 9 /** 10 * @param \Doku_Event_Handler $controller 11 */ 12 public function register(\Doku_Event_Handler $controller) 13 { 14 $controller->register_hook('ADMINPLUGIN_ACCESS_CHECK', 'AFTER', $this, 'handleAccess'); 15 $controller->register_hook('AUTH_USER_CHANGE', 'BEFORE', $this, 'handlePermissions'); 16 } 17 18 /** 19 * Grant managers access to user manager 20 * 21 * @param \Doku_Event $event 22 */ 23 public function handleAccess(\Doku_Event $event) 24 { 25 if ($event->data['instance'] instanceof \admin_plugin_usermanager) { 26 $event->data['hasAccess'] = auth_ismanager(); 27 } 28 } 29 30 /** 31 * Prevent managers from making changes beyond their privileges: 32 * - do not modify superusers 33 * - do not create superusers or managers (by adding users or groups) 34 * 35 * @param \Doku_Event $event 36 * @return bool 37 */ 38 public function handlePermissions(\Doku_Event $event) 39 { 40 // preliminary checks 41 global $INPUT; 42 if ($INPUT->str('page') !== 'usermanager') return true; 43 if (auth_isadmin()) return true; 44 if (!auth_ismanager()) return $this->deny($event); 45 46 $modUser = $event->data['params'][0]; 47 48 // more checks 49 if (is_array($modUser)) { 50 foreach ($modUser as $user) { 51 $this->checkModUser($user, $event); 52 } 53 } else { 54 $this->checkModUser($modUser, $event); 55 } 56 57 return true; 58 } 59 60 /** 61 * Check if modification of given user is allowed 62 * 63 * @param string $modUser 64 * @param \Doku_Event $event 65 * @return bool 66 */ 67 protected function checkModUser($modUser, \Doku_Event $event) 68 { 69 global $auth, $conf; 70 71 // rule: don't touch admins 72 // auth_isadmin() needs to receive groups or it will match against the groups of REMOTE_USER! 73 $existingUser = $auth->getUserData($modUser); 74 if ($existingUser && auth_isadmin($modUser, $existingUser['grps'])) return $this->deny($event); 75 76 // rule: don't create admins or managers 77 // check groups in modification parameters 78 if ($event->data['type'] === 'create') { 79 $groups = $event->data['params'][4]; 80 } elseif ($event->data['type'] === 'modify') { 81 $groups = $event->data['params'][1]['grps']; 82 } 83 84 // those new groups should be enough because we do not prevent demoting managers 85 // like we did with admins 86 if ( 87 !empty($groups) && 88 auth_isMember( 89 join(',', [$conf['superuser'], $conf['manager']]), 90 $modUser, 91 $groups 92 ) 93 ) { 94 return $this->deny($event); 95 } 96 97 return true; 98 } 99 100 /** 101 * Wrap up modification denial 102 * 103 * @param \Doku_Event $event 104 * @return false 105 */ 106 protected function deny(\Doku_Event $event) 107 { 108 $event->preventDefault(); 109 110 msg($this->getLang('error_forbidden'), -1); 111 return false; 112 } 113} 114