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