1163ac707SMichael Wilmes<?php 2f62d0e33SAndreas Gohr 3f62d0e33SAndreas Gohruse dokuwiki\Form\Form; 4f62d0e33SAndreas Gohruse dokuwiki\plugin\twofactor\Manager; 5f62d0e33SAndreas Gohr 6f62d0e33SAndreas Gohr/** 7163ac707SMichael Wilmes * Twofactor Manager 8163ac707SMichael Wilmes * 9*bbe22a6aSAndreas Gohr * Allows to reset a user's twofactor data 10163ac707SMichael Wilmes */ 11d0a31016SAndreas Gohrclass admin_plugin_twofactor extends DokuWiki_Admin_Plugin 12d0a31016SAndreas Gohr{ 13f62d0e33SAndreas Gohr protected $userList = array(); // list of users with attributes 14f62d0e33SAndreas Gohr protected $filter = array(); // user selection filter(s) 15f62d0e33SAndreas Gohr protected $start = 0; // index of first user to be displayed 16f62d0e33SAndreas Gohr protected $last = 0; // index of the last user to be displayed 17f62d0e33SAndreas Gohr protected $pagesize = 20; // number of users to list on one page 18f62d0e33SAndreas Gohr protected $disabled = ''; // if disabled set to explanatory string 19f62d0e33SAndreas Gohr 20f62d0e33SAndreas Gohr /** @var helper_plugin_attribute */ 21f62d0e33SAndreas Gohr protected $attribute; 22163ac707SMichael Wilmes 23*bbe22a6aSAndreas Gohr protected $manager; 24*bbe22a6aSAndreas Gohr 25163ac707SMichael Wilmes /** 26163ac707SMichael Wilmes * Constructor 27163ac707SMichael Wilmes */ 28d0a31016SAndreas Gohr public function __construct() 29d0a31016SAndreas Gohr { 30*bbe22a6aSAndreas Gohr $this->manager = Manager::getInstance(); 31*bbe22a6aSAndreas Gohr if (!$this->manager->isReady()) return; 32f62d0e33SAndreas Gohr $this->attribute = plugin_load('helper', 'attribute'); 33*bbe22a6aSAndreas Gohr 34*bbe22a6aSAndreas Gohr global $INPUT; 35*bbe22a6aSAndreas Gohr 36*bbe22a6aSAndreas Gohr $this->filter = $INPUT->arr('filter'); 37*bbe22a6aSAndreas Gohr $this->start = $INPUT->int('start'); 38163ac707SMichael Wilmes } 392cc41bddSMichael Wilmes 40f62d0e33SAndreas Gohr /** @inheritdoc */ 41d0a31016SAndreas Gohr public function handle() 42d0a31016SAndreas Gohr { 43*bbe22a6aSAndreas Gohr global $INPUT; 44*bbe22a6aSAndreas Gohr 45*bbe22a6aSAndreas Gohr if ($INPUT->has('reset') && checkSecurityToken()) { 46*bbe22a6aSAndreas Gohr $userdel = $INPUT->extract('reset')->str('reset'); 47*bbe22a6aSAndreas Gohr if ($userdel == $INPUT->server->str('REMOTE_USER')) { 48*bbe22a6aSAndreas Gohr msg($this->lang['reset_not_self'], -1); 49*bbe22a6aSAndreas Gohr return; 50b71db9c8SMichael Wilmes } 51*bbe22a6aSAndreas Gohr foreach ($this->manager->getAllProviders() as $providerID => $provider) { 52*bbe22a6aSAndreas Gohr $this->attribute->purge($providerID, $userdel); 53163ac707SMichael Wilmes } 54*bbe22a6aSAndreas Gohr $this->attribute->purge('twofactor', $userdel); 55163ac707SMichael Wilmes } 56163ac707SMichael Wilmes } 57163ac707SMichael Wilmes 58163ac707SMichael Wilmes /** 59163ac707SMichael Wilmes * Output appropriate html 60163ac707SMichael Wilmes * 61163ac707SMichael Wilmes * @return bool 62163ac707SMichael Wilmes */ 63d0a31016SAndreas Gohr public function html() 64d0a31016SAndreas Gohr { 65*bbe22a6aSAndreas Gohr $users = $this->getUserData($this->filter); 66*bbe22a6aSAndreas Gohr $usercount = count($users); 67*bbe22a6aSAndreas Gohr $users = $this->applyPagination($users, $this->start, $this->pagesize); 68163ac707SMichael Wilmes 69f62d0e33SAndreas Gohr echo $this->locale_xhtml('admin'); 70*bbe22a6aSAndreas Gohr if (!$this->manager->isReady()) { 71*bbe22a6aSAndreas Gohr return true; 72*bbe22a6aSAndreas Gohr } 73f62d0e33SAndreas Gohr 74*bbe22a6aSAndreas Gohr $form = new Form(['method' => 'POST', 'class' => 'plugin_twofactor_admin']); 75f62d0e33SAndreas Gohr $form->setHiddenField('do', 'admin'); 76f62d0e33SAndreas Gohr $form->setHiddenField('page', 'twofactor'); 77f62d0e33SAndreas Gohr $form->setHiddenField('start', $this->start); 78f62d0e33SAndreas Gohr 79f62d0e33SAndreas Gohr $form->addTagOpen('div')->addClass('table'); 80f62d0e33SAndreas Gohr $form->addTagOpen('table')->addClass('inline'); 81f62d0e33SAndreas Gohr $form = $this->addTableHead($form); 82f62d0e33SAndreas Gohr 83f62d0e33SAndreas Gohr $form->addTagOpen('tbody'); 84f62d0e33SAndreas Gohr foreach ($users as $user => $userinfo) { 85f62d0e33SAndreas Gohr $form = $this->addTableUser($form, $user, $userinfo); 86f62d0e33SAndreas Gohr } 87f62d0e33SAndreas Gohr $form->addTagClose('tbody'); 88f62d0e33SAndreas Gohr 89*bbe22a6aSAndreas Gohr $form->addTagOpen('tfooter'); 90*bbe22a6aSAndreas Gohr $form = $this->addTablePagination($form, $usercount, $this->start, $this->pagesize); 91*bbe22a6aSAndreas Gohr $form->addTagClose('tfooter'); 92*bbe22a6aSAndreas Gohr 93f62d0e33SAndreas Gohr $form->addTagClose('table'); 94f62d0e33SAndreas Gohr $form->addTagClose('div'); 95f62d0e33SAndreas Gohr 96f62d0e33SAndreas Gohr echo $form->toHTML(); 97f62d0e33SAndreas Gohr 98b71db9c8SMichael Wilmes return true; 99b71db9c8SMichael Wilmes } 100b71db9c8SMichael Wilmes 101163ac707SMichael Wilmes /** 102f62d0e33SAndreas Gohr * Add the table headers to the table in the given form 103f62d0e33SAndreas Gohr * @param Form $form 104f62d0e33SAndreas Gohr * @return Form 105163ac707SMichael Wilmes */ 106f62d0e33SAndreas Gohr protected function addTableHead(Form $form) 107f62d0e33SAndreas Gohr { 108f62d0e33SAndreas Gohr $form->addTagOpen('thead'); 109f62d0e33SAndreas Gohr 110f62d0e33SAndreas Gohr // header 111f62d0e33SAndreas Gohr $form->addTagOpen('tr'); 112f62d0e33SAndreas Gohr $form->addTagOpen('th'); 113f62d0e33SAndreas Gohr $form->addHTML($this->getLang('user_id')); 114f62d0e33SAndreas Gohr $form->addTagClose('th'); 115f62d0e33SAndreas Gohr $form->addTagOpen('th'); 116f62d0e33SAndreas Gohr $form->addHTML($this->getLang('user_name')); 117f62d0e33SAndreas Gohr $form->addTagClose('th'); 118f62d0e33SAndreas Gohr $form->addTagOpen('th'); 119f62d0e33SAndreas Gohr $form->addHTML($this->getLang('user_mail')); 120f62d0e33SAndreas Gohr $form->addTagClose('th'); 121f62d0e33SAndreas Gohr $form->addTagOpen('th'); 122f62d0e33SAndreas Gohr $form->addHTML($this->getLang('action')); 123f62d0e33SAndreas Gohr $form->addTagClose('th'); 124f62d0e33SAndreas Gohr $form->addTagClose('tr'); 125f62d0e33SAndreas Gohr 126f62d0e33SAndreas Gohr // filter 127f62d0e33SAndreas Gohr $form->addTagOpen('tr'); 128f62d0e33SAndreas Gohr $form->addTagOpen('th'); 129*bbe22a6aSAndreas Gohr $form->addTextInput('filter[user]'); 130f62d0e33SAndreas Gohr $form->addTagClose('th'); 131f62d0e33SAndreas Gohr $form->addTagOpen('th'); 132*bbe22a6aSAndreas Gohr $form->addTextInput('filter[name]'); 133f62d0e33SAndreas Gohr $form->addTagClose('th'); 134f62d0e33SAndreas Gohr $form->addTagOpen('th'); 135*bbe22a6aSAndreas Gohr $form->addTextInput('filter[mail]'); 136f62d0e33SAndreas Gohr $form->addTagClose('th'); 137f62d0e33SAndreas Gohr $form->addTagOpen('th'); 138f62d0e33SAndreas Gohr $form->addButton('', $this->getLang('search'))->attr('type', 'submit'); 139f62d0e33SAndreas Gohr $form->addTagClose('th'); 140f62d0e33SAndreas Gohr $form->addTagClose('tr'); 141f62d0e33SAndreas Gohr 142f62d0e33SAndreas Gohr $form->addTagClose('thead'); 143f62d0e33SAndreas Gohr return $form; 144163ac707SMichael Wilmes } 145163ac707SMichael Wilmes 146f62d0e33SAndreas Gohr /** 147f62d0e33SAndreas Gohr * Add 148f62d0e33SAndreas Gohr * 149f62d0e33SAndreas Gohr * @param Form $form 150f62d0e33SAndreas Gohr * @param $user 151f62d0e33SAndreas Gohr * @param $userinfo 152f62d0e33SAndreas Gohr * @return Form 153f62d0e33SAndreas Gohr */ 154f62d0e33SAndreas Gohr protected function addTableUser(Form $form, $user, $userinfo) 155f62d0e33SAndreas Gohr { 156f62d0e33SAndreas Gohr $form->addTagOpen('tr'); 157f62d0e33SAndreas Gohr $form->addTagOpen('td'); 158f62d0e33SAndreas Gohr $form->addHTML(hsc($user)); 159f62d0e33SAndreas Gohr $form->addTagClose('td'); 160f62d0e33SAndreas Gohr $form->addTagOpen('td'); 161f62d0e33SAndreas Gohr $form->addHTML(hsc($userinfo['name'])); 162f62d0e33SAndreas Gohr $form->addTagClose('td'); 163f62d0e33SAndreas Gohr $form->addTagOpen('td'); 164f62d0e33SAndreas Gohr $form->addHTML(hsc($userinfo['mail'])); 165f62d0e33SAndreas Gohr $form->addTagClose('td'); 166f62d0e33SAndreas Gohr $form->addTagOpen('td'); 167*bbe22a6aSAndreas Gohr $form->addButton('reset[' . $user . ']', $this->getLang('reset')) 168*bbe22a6aSAndreas Gohr ->attr('type', 'submit') 169*bbe22a6aSAndreas Gohr ->addClass('twofactor_resetconfirm'); 170f62d0e33SAndreas Gohr $form->addTagClose('td'); 171f62d0e33SAndreas Gohr $form->addTagClose('tr'); 172f62d0e33SAndreas Gohr return $form; 173163ac707SMichael Wilmes } 174163ac707SMichael Wilmes 175f62d0e33SAndreas Gohr /** 176*bbe22a6aSAndreas Gohr * Add the pagination buttons to the form 177163ac707SMichael Wilmes * 178*bbe22a6aSAndreas Gohr * @param Form $form 179*bbe22a6aSAndreas Gohr * @param int $usercount 180*bbe22a6aSAndreas Gohr * @param int $start 181*bbe22a6aSAndreas Gohr * @param int $pagesize 182*bbe22a6aSAndreas Gohr * @return Form 183163ac707SMichael Wilmes */ 184*bbe22a6aSAndreas Gohr protected function addTablePagination(Form $form, $usercount, $start, $pagesize) 185d0a31016SAndreas Gohr { 186*bbe22a6aSAndreas Gohr $form->addTagOpen('tr'); 187*bbe22a6aSAndreas Gohr $form->addTagOpen('td')->attr('colspan', '4'); 188*bbe22a6aSAndreas Gohr $form->addTagOpen('div')->addClass('pagination'); 189163ac707SMichael Wilmes 190*bbe22a6aSAndreas Gohr // start 191*bbe22a6aSAndreas Gohr $btn = $form->addButton('start', $this->getLang('start'))->val('0'); 192*bbe22a6aSAndreas Gohr if ($start <= 0) $btn->attr('disabled', 'disabled'); 193163ac707SMichael Wilmes 194*bbe22a6aSAndreas Gohr // prev 195*bbe22a6aSAndreas Gohr $btn = $form->addButton('start', $this->getLang('prev'))->val($start - $pagesize); 196*bbe22a6aSAndreas Gohr if ($start - $pagesize < 0) $btn->attr('disabled', 'disabled'); 197*bbe22a6aSAndreas Gohr 198*bbe22a6aSAndreas Gohr // next 199*bbe22a6aSAndreas Gohr $btn = $form->addButton('start', $this->getLang('next'))->val($start + $pagesize); 200*bbe22a6aSAndreas Gohr if ($start + $pagesize >= $usercount) $btn->attr('disabled', 'disabled'); 201*bbe22a6aSAndreas Gohr 202*bbe22a6aSAndreas Gohr // last 203*bbe22a6aSAndreas Gohr $btn = $form->addButton('start', $this->getLang('last'))->val($usercount - $pagesize); 204*bbe22a6aSAndreas Gohr if ($usercount - $pagesize <= 0) $btn->attr('disabled', 'disabled'); 205*bbe22a6aSAndreas Gohr if ($usercount - $pagesize == $start) $btn->attr('disabled', 'disabled'); 206*bbe22a6aSAndreas Gohr 207*bbe22a6aSAndreas Gohr $form->addTagClose('div'); 208*bbe22a6aSAndreas Gohr $form->addTagClose('td'); 209*bbe22a6aSAndreas Gohr $form->addTagClose('tr'); 210*bbe22a6aSAndreas Gohr 211*bbe22a6aSAndreas Gohr return $form; 212163ac707SMichael Wilmes } 213163ac707SMichael Wilmes 214163ac707SMichael Wilmes /** 215*bbe22a6aSAndreas Gohr * Get the filtered users that have a twofactor provider set 216163ac707SMichael Wilmes * 217*bbe22a6aSAndreas Gohr * @param array $filter 218163ac707SMichael Wilmes * @return array 219163ac707SMichael Wilmes */ 220*bbe22a6aSAndreas Gohr protected function getUserData($filter) 221d0a31016SAndreas Gohr { 222*bbe22a6aSAndreas Gohr $users = $this->attribute->enumerateUsers('twofactor'); 223*bbe22a6aSAndreas Gohr return $this->applyFilter($users, $filter); 224163ac707SMichael Wilmes } 225163ac707SMichael Wilmes 226163ac707SMichael Wilmes /** 227*bbe22a6aSAndreas Gohr * Apply the given filters and return user details 228163ac707SMichael Wilmes * 229*bbe22a6aSAndreas Gohr * @param string[] $users simple list of user names 230*bbe22a6aSAndreas Gohr * @param array $filter 231*bbe22a6aSAndreas Gohr * @return array (user => userdata) 232163ac707SMichael Wilmes */ 233*bbe22a6aSAndreas Gohr protected function applyFilter($users, $filter) 234d0a31016SAndreas Gohr { 235*bbe22a6aSAndreas Gohr global $auth; 236*bbe22a6aSAndreas Gohr $filtered = []; 237163ac707SMichael Wilmes 238*bbe22a6aSAndreas Gohr $hasFilter = (bool)array_filter(array_values($filter)); 239*bbe22a6aSAndreas Gohr foreach ($users as $user) { 240*bbe22a6aSAndreas Gohr $userdata = $auth->getUserData($user); 241*bbe22a6aSAndreas Gohr if (!$userdata) continue; 242*bbe22a6aSAndreas Gohr $userdata['user'] = $user; 243*bbe22a6aSAndreas Gohr if ($hasFilter) { 244*bbe22a6aSAndreas Gohr foreach ($filter as $key => $value) { 245*bbe22a6aSAndreas Gohr if ($value && strstr($userdata[$key], $value)) { 246*bbe22a6aSAndreas Gohr $filtered[$user] = $userdata; 247*bbe22a6aSAndreas Gohr continue 2; 248*bbe22a6aSAndreas Gohr } 249*bbe22a6aSAndreas Gohr } 250163ac707SMichael Wilmes } else { 251*bbe22a6aSAndreas Gohr $filtered[$user] = $userdata; 252*bbe22a6aSAndreas Gohr } 253*bbe22a6aSAndreas Gohr } 254*bbe22a6aSAndreas Gohr return $filtered; 255163ac707SMichael Wilmes } 256163ac707SMichael Wilmes 257*bbe22a6aSAndreas Gohr /** 258*bbe22a6aSAndreas Gohr * Get the current page of users 259*bbe22a6aSAndreas Gohr * 260*bbe22a6aSAndreas Gohr * @param array $users 261*bbe22a6aSAndreas Gohr * @param int $start 262*bbe22a6aSAndreas Gohr * @param int $pagesize 263*bbe22a6aSAndreas Gohr * @return array 264*bbe22a6aSAndreas Gohr */ 265*bbe22a6aSAndreas Gohr protected function applyPagination($users, $start, $pagesize) 266*bbe22a6aSAndreas Gohr { 267*bbe22a6aSAndreas Gohr return array_slice($users, $start, $pagesize, true); 268163ac707SMichael Wilmes } 269163ac707SMichael Wilmes 270163ac707SMichael Wilmes} 271