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 /** @var array currently active filters */ 15 protected $filter = []; 16 /** @var int index of first user to be displayed */ 17 protected $start = 0; 18 /** @var int number of users to list on one page */ 19 protected $pagesize = 20; 20 /** @var Manager */ 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 /** @inheritdoc */ 56 public function html() 57 { 58 echo $this->locale_xhtml('admin'); 59 if (!$this->manager->isReady()) { 60 return true; 61 } 62 63 $users = $this->getUserData($this->filter); 64 $usercount = count($users); 65 $users = $this->applyPagination($users, $this->start, $this->pagesize); 66 67 $form = new Form(['method' => 'POST', 'class' => 'plugin_twofactor_admin']); 68 $form->setHiddenField('do', 'admin'); 69 $form->setHiddenField('page', 'twofactor'); 70 $form->setHiddenField('start', $this->start); 71 72 $form->addTagOpen('div')->addClass('table'); 73 $form->addTagOpen('table')->addClass('inline'); 74 $form = $this->addTableHead($form); 75 76 $form->addTagOpen('tbody'); 77 foreach ($users as $user => $userinfo) { 78 $form = $this->addTableUser($form, $user, $userinfo); 79 } 80 $form->addTagClose('tbody'); 81 82 $form->addTagOpen('tfooter'); 83 $form = $this->addTablePagination($form, $usercount, $this->start, $this->pagesize); 84 $form->addTagClose('tfooter'); 85 86 $form->addTagClose('table'); 87 $form->addTagClose('div'); 88 89 echo $form->toHTML(); 90 91 return true; 92 } 93 94 /** 95 * Add the table headers to the table in the given form 96 * @param Form $form 97 * @return Form 98 */ 99 protected function addTableHead(Form $form) 100 { 101 $form->addTagOpen('thead'); 102 103 // header 104 $form->addTagOpen('tr'); 105 $form->addTagOpen('th'); 106 $form->addHTML($this->getLang('user_id')); 107 $form->addTagClose('th'); 108 $form->addTagOpen('th'); 109 $form->addHTML($this->getLang('user_name')); 110 $form->addTagClose('th'); 111 $form->addTagOpen('th'); 112 $form->addHTML($this->getLang('user_mail')); 113 $form->addTagClose('th'); 114 $form->addTagOpen('th'); 115 $form->addHTML($this->getLang('action')); 116 $form->addTagClose('th'); 117 $form->addTagClose('tr'); 118 119 // filter 120 $form->addTagOpen('tr'); 121 $form->addTagOpen('th'); 122 $form->addTextInput('filter[user]'); 123 $form->addTagClose('th'); 124 $form->addTagOpen('th'); 125 $form->addTextInput('filter[name]'); 126 $form->addTagClose('th'); 127 $form->addTagOpen('th'); 128 $form->addTextInput('filter[mail]'); 129 $form->addTagClose('th'); 130 $form->addTagOpen('th'); 131 $form->addButton('', $this->getLang('search'))->attr('type', 'submit'); 132 $form->addTagClose('th'); 133 $form->addTagClose('tr'); 134 135 $form->addTagClose('thead'); 136 return $form; 137 } 138 139 /** 140 * Add 141 * 142 * @param Form $form 143 * @param $user 144 * @param $userinfo 145 * @return Form 146 */ 147 protected function addTableUser(Form $form, $user, $userinfo) 148 { 149 $form->addTagOpen('tr'); 150 $form->addTagOpen('td'); 151 $form->addHTML(hsc($user)); 152 $form->addTagClose('td'); 153 $form->addTagOpen('td'); 154 $form->addHTML(hsc($userinfo['name'])); 155 $form->addTagClose('td'); 156 $form->addTagOpen('td'); 157 $form->addHTML(hsc($userinfo['mail'])); 158 $form->addTagClose('td'); 159 $form->addTagOpen('td'); 160 $form->addButton('reset[' . $user . ']', $this->getLang('reset')) 161 ->attr('type', 'submit') 162 ->addClass('twofactor_resetconfirm'); 163 $form->addTagClose('td'); 164 $form->addTagClose('tr'); 165 return $form; 166 } 167 168 /** 169 * Add the pagination buttons to the form 170 * 171 * @param Form $form 172 * @param int $usercount 173 * @param int $start 174 * @param int $pagesize 175 * @return Form 176 */ 177 protected function addTablePagination(Form $form, $usercount, $start, $pagesize) 178 { 179 $form->addTagOpen('tr'); 180 $form->addTagOpen('td')->attr('colspan', '4'); 181 $form->addTagOpen('div')->addClass('pagination'); 182 183 // start 184 $btn = $form->addButton('start', $this->getLang('start'))->val('0'); 185 if ($start <= 0) $btn->attr('disabled', 'disabled'); 186 187 // prev 188 $btn = $form->addButton('start', $this->getLang('prev'))->val($start - $pagesize); 189 if ($start - $pagesize < 0) $btn->attr('disabled', 'disabled'); 190 191 // next 192 $btn = $form->addButton('start', $this->getLang('next'))->val($start + $pagesize); 193 if ($start + $pagesize >= $usercount) $btn->attr('disabled', 'disabled'); 194 195 // last 196 $btn = $form->addButton('start', $this->getLang('last'))->val($usercount - $pagesize); 197 if ($usercount - $pagesize <= 0) $btn->attr('disabled', 'disabled'); 198 if ($usercount - $pagesize == $start) $btn->attr('disabled', 'disabled'); 199 200 $form->addTagClose('div'); 201 $form->addTagClose('td'); 202 $form->addTagClose('tr'); 203 204 return $form; 205 } 206 207 /** 208 * Get the filtered users that have a twofactor provider set 209 * 210 * @param array $filter 211 * @return array 212 */ 213 protected function getUserData($filter) 214 { 215 $users = Settings::findUsers('twofactor'); 216 return $this->applyFilter($users, $filter); 217 } 218 219 /** 220 * Apply the given filters and return user details 221 * 222 * @param string[] $users simple list of user names 223 * @param array $filter 224 * @return array (user => userdata) 225 */ 226 protected function applyFilter($users, $filter) 227 { 228 global $auth; 229 $filtered = []; 230 231 $hasFilter = (bool)array_filter(array_values($filter)); 232 foreach ($users as $user) { 233 $userdata = $auth->getUserData($user); 234 if (!$userdata) continue; 235 $userdata['user'] = $user; 236 if ($hasFilter) { 237 foreach ($filter as $key => $value) { 238 $q = preg_quote($value, '/'); 239 if ($value && preg_match("/$q/iu", $userdata[$key])) { 240 $filtered[$user] = $userdata; 241 continue 2; 242 } 243 } 244 } else { 245 $filtered[$user] = $userdata; 246 } 247 } 248 return $filtered; 249 } 250 251 /** 252 * Get the current page of users 253 * 254 * @param array $users 255 * @param int $start 256 * @param int $pagesize 257 * @return array 258 */ 259 protected function applyPagination($users, $start, $pagesize) 260 { 261 return array_slice($users, $start, $pagesize, true); 262 } 263 264} 265