1<?php 2 3use dokuwiki\Form\Form; 4use dokuwiki\plugin\twofactor\Manager; 5 6/** 7 * Twofactor Manager 8 * 9 * Allows to reset a user's twofactor data 10 */ 11class admin_plugin_twofactor extends DokuWiki_Admin_Plugin 12{ 13 protected $userList = array(); // list of users with attributes 14 protected $filter = array(); // user selection filter(s) 15 protected $start = 0; // index of first user to be displayed 16 protected $last = 0; // index of the last user to be displayed 17 protected $pagesize = 20; // number of users to list on one page 18 protected $disabled = ''; // if disabled set to explanatory string 19 20 /** @var helper_plugin_attribute */ 21 protected $attribute; 22 23 protected $manager; 24 25 /** 26 * Constructor 27 */ 28 public function __construct() 29 { 30 $this->manager = Manager::getInstance(); 31 if (!$this->manager->isReady()) return; 32 $this->attribute = plugin_load('helper', 'attribute'); 33 34 global $INPUT; 35 36 $this->filter = $INPUT->arr('filter'); 37 $this->start = $INPUT->int('start'); 38 } 39 40 /** @inheritdoc */ 41 public function handle() 42 { 43 global $INPUT; 44 45 if ($INPUT->has('reset') && checkSecurityToken()) { 46 $userdel = $INPUT->extract('reset')->str('reset'); 47 if ($userdel == $INPUT->server->str('REMOTE_USER')) { 48 msg($this->lang['reset_not_self'], -1); 49 return; 50 } 51 foreach ($this->manager->getAllProviders() as $providerID => $provider) { 52 $this->attribute->purge($providerID, $userdel); 53 } 54 $this->attribute->purge('twofactor', $userdel); 55 } 56 } 57 58 /** 59 * Output appropriate html 60 * 61 * @return bool 62 */ 63 public function html() 64 { 65 $users = $this->getUserData($this->filter); 66 $usercount = count($users); 67 $users = $this->applyPagination($users, $this->start, $this->pagesize); 68 69 echo $this->locale_xhtml('admin'); 70 if (!$this->manager->isReady()) { 71 return true; 72 } 73 74 $form = new Form(['method' => 'POST', 'class' => 'plugin_twofactor_admin']); 75 $form->setHiddenField('do', 'admin'); 76 $form->setHiddenField('page', 'twofactor'); 77 $form->setHiddenField('start', $this->start); 78 79 $form->addTagOpen('div')->addClass('table'); 80 $form->addTagOpen('table')->addClass('inline'); 81 $form = $this->addTableHead($form); 82 83 $form->addTagOpen('tbody'); 84 foreach ($users as $user => $userinfo) { 85 $form = $this->addTableUser($form, $user, $userinfo); 86 } 87 $form->addTagClose('tbody'); 88 89 $form->addTagOpen('tfooter'); 90 $form = $this->addTablePagination($form, $usercount, $this->start, $this->pagesize); 91 $form->addTagClose('tfooter'); 92 93 $form->addTagClose('table'); 94 $form->addTagClose('div'); 95 96 echo $form->toHTML(); 97 98 return true; 99 } 100 101 /** 102 * Add the table headers to the table in the given form 103 * @param Form $form 104 * @return Form 105 */ 106 protected function addTableHead(Form $form) 107 { 108 $form->addTagOpen('thead'); 109 110 // header 111 $form->addTagOpen('tr'); 112 $form->addTagOpen('th'); 113 $form->addHTML($this->getLang('user_id')); 114 $form->addTagClose('th'); 115 $form->addTagOpen('th'); 116 $form->addHTML($this->getLang('user_name')); 117 $form->addTagClose('th'); 118 $form->addTagOpen('th'); 119 $form->addHTML($this->getLang('user_mail')); 120 $form->addTagClose('th'); 121 $form->addTagOpen('th'); 122 $form->addHTML($this->getLang('action')); 123 $form->addTagClose('th'); 124 $form->addTagClose('tr'); 125 126 // filter 127 $form->addTagOpen('tr'); 128 $form->addTagOpen('th'); 129 $form->addTextInput('filter[user]'); 130 $form->addTagClose('th'); 131 $form->addTagOpen('th'); 132 $form->addTextInput('filter[name]'); 133 $form->addTagClose('th'); 134 $form->addTagOpen('th'); 135 $form->addTextInput('filter[mail]'); 136 $form->addTagClose('th'); 137 $form->addTagOpen('th'); 138 $form->addButton('', $this->getLang('search'))->attr('type', 'submit'); 139 $form->addTagClose('th'); 140 $form->addTagClose('tr'); 141 142 $form->addTagClose('thead'); 143 return $form; 144 } 145 146 /** 147 * Add 148 * 149 * @param Form $form 150 * @param $user 151 * @param $userinfo 152 * @return Form 153 */ 154 protected function addTableUser(Form $form, $user, $userinfo) 155 { 156 $form->addTagOpen('tr'); 157 $form->addTagOpen('td'); 158 $form->addHTML(hsc($user)); 159 $form->addTagClose('td'); 160 $form->addTagOpen('td'); 161 $form->addHTML(hsc($userinfo['name'])); 162 $form->addTagClose('td'); 163 $form->addTagOpen('td'); 164 $form->addHTML(hsc($userinfo['mail'])); 165 $form->addTagClose('td'); 166 $form->addTagOpen('td'); 167 $form->addButton('reset[' . $user . ']', $this->getLang('reset')) 168 ->attr('type', 'submit') 169 ->addClass('twofactor_resetconfirm'); 170 $form->addTagClose('td'); 171 $form->addTagClose('tr'); 172 return $form; 173 } 174 175 /** 176 * Add the pagination buttons to the form 177 * 178 * @param Form $form 179 * @param int $usercount 180 * @param int $start 181 * @param int $pagesize 182 * @return Form 183 */ 184 protected function addTablePagination(Form $form, $usercount, $start, $pagesize) 185 { 186 $form->addTagOpen('tr'); 187 $form->addTagOpen('td')->attr('colspan', '4'); 188 $form->addTagOpen('div')->addClass('pagination'); 189 190 // start 191 $btn = $form->addButton('start', $this->getLang('start'))->val('0'); 192 if ($start <= 0) $btn->attr('disabled', 'disabled'); 193 194 // prev 195 $btn = $form->addButton('start', $this->getLang('prev'))->val($start - $pagesize); 196 if ($start - $pagesize < 0) $btn->attr('disabled', 'disabled'); 197 198 // next 199 $btn = $form->addButton('start', $this->getLang('next'))->val($start + $pagesize); 200 if ($start + $pagesize >= $usercount) $btn->attr('disabled', 'disabled'); 201 202 // last 203 $btn = $form->addButton('start', $this->getLang('last'))->val($usercount - $pagesize); 204 if ($usercount - $pagesize <= 0) $btn->attr('disabled', 'disabled'); 205 if ($usercount - $pagesize == $start) $btn->attr('disabled', 'disabled'); 206 207 $form->addTagClose('div'); 208 $form->addTagClose('td'); 209 $form->addTagClose('tr'); 210 211 return $form; 212 } 213 214 /** 215 * Get the filtered users that have a twofactor provider set 216 * 217 * @param array $filter 218 * @return array 219 */ 220 protected function getUserData($filter) 221 { 222 $users = $this->attribute->enumerateUsers('twofactor'); 223 return $this->applyFilter($users, $filter); 224 } 225 226 /** 227 * Apply the given filters and return user details 228 * 229 * @param string[] $users simple list of user names 230 * @param array $filter 231 * @return array (user => userdata) 232 */ 233 protected function applyFilter($users, $filter) 234 { 235 global $auth; 236 $filtered = []; 237 238 $hasFilter = (bool)array_filter(array_values($filter)); 239 foreach ($users as $user) { 240 $userdata = $auth->getUserData($user); 241 if (!$userdata) continue; 242 $userdata['user'] = $user; 243 if ($hasFilter) { 244 foreach ($filter as $key => $value) { 245 if ($value && strstr($userdata[$key], $value)) { 246 $filtered[$user] = $userdata; 247 continue 2; 248 } 249 } 250 } else { 251 $filtered[$user] = $userdata; 252 } 253 } 254 return $filtered; 255 } 256 257 /** 258 * Get the current page of users 259 * 260 * @param array $users 261 * @param int $start 262 * @param int $pagesize 263 * @return array 264 */ 265 protected function applyPagination($users, $start, $pagesize) 266 { 267 return array_slice($users, $start, $pagesize, true); 268 } 269 270} 271