1163ac707SMichael Wilmes<?php 2f62d0e33SAndreas Gohr 3f62d0e33SAndreas Gohruse dokuwiki\Form\Form; 4f62d0e33SAndreas Gohruse dokuwiki\plugin\twofactor\Manager; 56d69ca71SAndreas Gohruse dokuwiki\plugin\twofactor\Settings; 6f62d0e33SAndreas Gohr 7f62d0e33SAndreas Gohr/** 8163ac707SMichael Wilmes * Twofactor Manager 9163ac707SMichael Wilmes * 10bbe22a6aSAndreas Gohr * Allows to reset a user's twofactor data 11163ac707SMichael Wilmes */ 12d0a31016SAndreas Gohrclass admin_plugin_twofactor extends DokuWiki_Admin_Plugin 13d0a31016SAndreas Gohr{ 14f62d0e33SAndreas Gohr protected $userList = array(); // list of users with attributes 15f62d0e33SAndreas Gohr protected $filter = array(); // user selection filter(s) 16f62d0e33SAndreas Gohr protected $start = 0; // index of first user to be displayed 17f62d0e33SAndreas Gohr protected $last = 0; // index of the last user to be displayed 18f62d0e33SAndreas Gohr protected $pagesize = 20; // number of users to list on one page 19f62d0e33SAndreas Gohr protected $disabled = ''; // if disabled set to explanatory string 20f62d0e33SAndreas Gohr 21bbe22a6aSAndreas Gohr protected $manager; 22bbe22a6aSAndreas Gohr 23163ac707SMichael Wilmes /** 24163ac707SMichael Wilmes * Constructor 25163ac707SMichael Wilmes */ 26d0a31016SAndreas Gohr public function __construct() 27d0a31016SAndreas Gohr { 28bbe22a6aSAndreas Gohr $this->manager = Manager::getInstance(); 29bbe22a6aSAndreas Gohr if (!$this->manager->isReady()) return; 30bbe22a6aSAndreas Gohr 31bbe22a6aSAndreas Gohr global $INPUT; 32bbe22a6aSAndreas Gohr 33bbe22a6aSAndreas Gohr $this->filter = $INPUT->arr('filter'); 34bbe22a6aSAndreas Gohr $this->start = $INPUT->int('start'); 35163ac707SMichael Wilmes } 362cc41bddSMichael Wilmes 37f62d0e33SAndreas Gohr /** @inheritdoc */ 38d0a31016SAndreas Gohr public function handle() 39d0a31016SAndreas Gohr { 40bbe22a6aSAndreas Gohr global $INPUT; 41bbe22a6aSAndreas Gohr 42bbe22a6aSAndreas Gohr if ($INPUT->has('reset') && checkSecurityToken()) { 43bbe22a6aSAndreas Gohr $userdel = $INPUT->extract('reset')->str('reset'); 44bbe22a6aSAndreas Gohr if ($userdel == $INPUT->server->str('REMOTE_USER')) { 45bbe22a6aSAndreas Gohr msg($this->lang['reset_not_self'], -1); 46bbe22a6aSAndreas Gohr return; 47b71db9c8SMichael Wilmes } 48bbe22a6aSAndreas Gohr foreach ($this->manager->getAllProviders() as $providerID => $provider) { 496d69ca71SAndreas Gohr (new Settings($providerID, $userdel))->purge(); 50163ac707SMichael Wilmes } 516d69ca71SAndreas Gohr (new Settings('twofactor', $userdel))->purge(); 52163ac707SMichael Wilmes } 53163ac707SMichael Wilmes } 54163ac707SMichael Wilmes 55163ac707SMichael Wilmes /** 56163ac707SMichael Wilmes * Output appropriate html 57163ac707SMichael Wilmes * 58163ac707SMichael Wilmes * @return bool 59163ac707SMichael Wilmes */ 60d0a31016SAndreas Gohr public function html() 61d0a31016SAndreas Gohr { 62f62d0e33SAndreas Gohr echo $this->locale_xhtml('admin'); 63bbe22a6aSAndreas Gohr if (!$this->manager->isReady()) { 64bbe22a6aSAndreas Gohr return true; 65bbe22a6aSAndreas Gohr } 66f62d0e33SAndreas Gohr 676ce592efSAndreas Gohr $users = $this->getUserData($this->filter); 686ce592efSAndreas Gohr $usercount = count($users); 696ce592efSAndreas Gohr $users = $this->applyPagination($users, $this->start, $this->pagesize); 706ce592efSAndreas Gohr 71bbe22a6aSAndreas Gohr $form = new Form(['method' => 'POST', 'class' => 'plugin_twofactor_admin']); 72f62d0e33SAndreas Gohr $form->setHiddenField('do', 'admin'); 73f62d0e33SAndreas Gohr $form->setHiddenField('page', 'twofactor'); 74f62d0e33SAndreas Gohr $form->setHiddenField('start', $this->start); 75f62d0e33SAndreas Gohr 76f62d0e33SAndreas Gohr $form->addTagOpen('div')->addClass('table'); 77f62d0e33SAndreas Gohr $form->addTagOpen('table')->addClass('inline'); 78f62d0e33SAndreas Gohr $form = $this->addTableHead($form); 79f62d0e33SAndreas Gohr 80f62d0e33SAndreas Gohr $form->addTagOpen('tbody'); 81f62d0e33SAndreas Gohr foreach ($users as $user => $userinfo) { 82f62d0e33SAndreas Gohr $form = $this->addTableUser($form, $user, $userinfo); 83f62d0e33SAndreas Gohr } 84f62d0e33SAndreas Gohr $form->addTagClose('tbody'); 85f62d0e33SAndreas Gohr 86bbe22a6aSAndreas Gohr $form->addTagOpen('tfooter'); 87bbe22a6aSAndreas Gohr $form = $this->addTablePagination($form, $usercount, $this->start, $this->pagesize); 88bbe22a6aSAndreas Gohr $form->addTagClose('tfooter'); 89bbe22a6aSAndreas Gohr 90f62d0e33SAndreas Gohr $form->addTagClose('table'); 91f62d0e33SAndreas Gohr $form->addTagClose('div'); 92f62d0e33SAndreas Gohr 93f62d0e33SAndreas Gohr echo $form->toHTML(); 94f62d0e33SAndreas Gohr 95b71db9c8SMichael Wilmes return true; 96b71db9c8SMichael Wilmes } 97b71db9c8SMichael Wilmes 98163ac707SMichael Wilmes /** 99f62d0e33SAndreas Gohr * Add the table headers to the table in the given form 100f62d0e33SAndreas Gohr * @param Form $form 101f62d0e33SAndreas Gohr * @return Form 102163ac707SMichael Wilmes */ 103f62d0e33SAndreas Gohr protected function addTableHead(Form $form) 104f62d0e33SAndreas Gohr { 105f62d0e33SAndreas Gohr $form->addTagOpen('thead'); 106f62d0e33SAndreas Gohr 107f62d0e33SAndreas Gohr // header 108f62d0e33SAndreas Gohr $form->addTagOpen('tr'); 109f62d0e33SAndreas Gohr $form->addTagOpen('th'); 110f62d0e33SAndreas Gohr $form->addHTML($this->getLang('user_id')); 111f62d0e33SAndreas Gohr $form->addTagClose('th'); 112f62d0e33SAndreas Gohr $form->addTagOpen('th'); 113f62d0e33SAndreas Gohr $form->addHTML($this->getLang('user_name')); 114f62d0e33SAndreas Gohr $form->addTagClose('th'); 115f62d0e33SAndreas Gohr $form->addTagOpen('th'); 116f62d0e33SAndreas Gohr $form->addHTML($this->getLang('user_mail')); 117f62d0e33SAndreas Gohr $form->addTagClose('th'); 118f62d0e33SAndreas Gohr $form->addTagOpen('th'); 119f62d0e33SAndreas Gohr $form->addHTML($this->getLang('action')); 120f62d0e33SAndreas Gohr $form->addTagClose('th'); 121f62d0e33SAndreas Gohr $form->addTagClose('tr'); 122f62d0e33SAndreas Gohr 123f62d0e33SAndreas Gohr // filter 124f62d0e33SAndreas Gohr $form->addTagOpen('tr'); 125f62d0e33SAndreas Gohr $form->addTagOpen('th'); 126bbe22a6aSAndreas Gohr $form->addTextInput('filter[user]'); 127f62d0e33SAndreas Gohr $form->addTagClose('th'); 128f62d0e33SAndreas Gohr $form->addTagOpen('th'); 129bbe22a6aSAndreas Gohr $form->addTextInput('filter[name]'); 130f62d0e33SAndreas Gohr $form->addTagClose('th'); 131f62d0e33SAndreas Gohr $form->addTagOpen('th'); 132bbe22a6aSAndreas Gohr $form->addTextInput('filter[mail]'); 133f62d0e33SAndreas Gohr $form->addTagClose('th'); 134f62d0e33SAndreas Gohr $form->addTagOpen('th'); 135f62d0e33SAndreas Gohr $form->addButton('', $this->getLang('search'))->attr('type', 'submit'); 136f62d0e33SAndreas Gohr $form->addTagClose('th'); 137f62d0e33SAndreas Gohr $form->addTagClose('tr'); 138f62d0e33SAndreas Gohr 139f62d0e33SAndreas Gohr $form->addTagClose('thead'); 140f62d0e33SAndreas Gohr return $form; 141163ac707SMichael Wilmes } 142163ac707SMichael Wilmes 143f62d0e33SAndreas Gohr /** 144f62d0e33SAndreas Gohr * Add 145f62d0e33SAndreas Gohr * 146f62d0e33SAndreas Gohr * @param Form $form 147f62d0e33SAndreas Gohr * @param $user 148f62d0e33SAndreas Gohr * @param $userinfo 149f62d0e33SAndreas Gohr * @return Form 150f62d0e33SAndreas Gohr */ 151f62d0e33SAndreas Gohr protected function addTableUser(Form $form, $user, $userinfo) 152f62d0e33SAndreas Gohr { 153f62d0e33SAndreas Gohr $form->addTagOpen('tr'); 154f62d0e33SAndreas Gohr $form->addTagOpen('td'); 155f62d0e33SAndreas Gohr $form->addHTML(hsc($user)); 156f62d0e33SAndreas Gohr $form->addTagClose('td'); 157f62d0e33SAndreas Gohr $form->addTagOpen('td'); 158f62d0e33SAndreas Gohr $form->addHTML(hsc($userinfo['name'])); 159f62d0e33SAndreas Gohr $form->addTagClose('td'); 160f62d0e33SAndreas Gohr $form->addTagOpen('td'); 161f62d0e33SAndreas Gohr $form->addHTML(hsc($userinfo['mail'])); 162f62d0e33SAndreas Gohr $form->addTagClose('td'); 163f62d0e33SAndreas Gohr $form->addTagOpen('td'); 164bbe22a6aSAndreas Gohr $form->addButton('reset[' . $user . ']', $this->getLang('reset')) 165bbe22a6aSAndreas Gohr ->attr('type', 'submit') 166bbe22a6aSAndreas Gohr ->addClass('twofactor_resetconfirm'); 167f62d0e33SAndreas Gohr $form->addTagClose('td'); 168f62d0e33SAndreas Gohr $form->addTagClose('tr'); 169f62d0e33SAndreas Gohr return $form; 170163ac707SMichael Wilmes } 171163ac707SMichael Wilmes 172f62d0e33SAndreas Gohr /** 173bbe22a6aSAndreas Gohr * Add the pagination buttons to the form 174163ac707SMichael Wilmes * 175bbe22a6aSAndreas Gohr * @param Form $form 176bbe22a6aSAndreas Gohr * @param int $usercount 177bbe22a6aSAndreas Gohr * @param int $start 178bbe22a6aSAndreas Gohr * @param int $pagesize 179bbe22a6aSAndreas Gohr * @return Form 180163ac707SMichael Wilmes */ 181bbe22a6aSAndreas Gohr protected function addTablePagination(Form $form, $usercount, $start, $pagesize) 182d0a31016SAndreas Gohr { 183bbe22a6aSAndreas Gohr $form->addTagOpen('tr'); 184bbe22a6aSAndreas Gohr $form->addTagOpen('td')->attr('colspan', '4'); 185bbe22a6aSAndreas Gohr $form->addTagOpen('div')->addClass('pagination'); 186163ac707SMichael Wilmes 187bbe22a6aSAndreas Gohr // start 188bbe22a6aSAndreas Gohr $btn = $form->addButton('start', $this->getLang('start'))->val('0'); 189bbe22a6aSAndreas Gohr if ($start <= 0) $btn->attr('disabled', 'disabled'); 190163ac707SMichael Wilmes 191bbe22a6aSAndreas Gohr // prev 192bbe22a6aSAndreas Gohr $btn = $form->addButton('start', $this->getLang('prev'))->val($start - $pagesize); 193bbe22a6aSAndreas Gohr if ($start - $pagesize < 0) $btn->attr('disabled', 'disabled'); 194bbe22a6aSAndreas Gohr 195bbe22a6aSAndreas Gohr // next 196bbe22a6aSAndreas Gohr $btn = $form->addButton('start', $this->getLang('next'))->val($start + $pagesize); 197bbe22a6aSAndreas Gohr if ($start + $pagesize >= $usercount) $btn->attr('disabled', 'disabled'); 198bbe22a6aSAndreas Gohr 199bbe22a6aSAndreas Gohr // last 200bbe22a6aSAndreas Gohr $btn = $form->addButton('start', $this->getLang('last'))->val($usercount - $pagesize); 201bbe22a6aSAndreas Gohr if ($usercount - $pagesize <= 0) $btn->attr('disabled', 'disabled'); 202bbe22a6aSAndreas Gohr if ($usercount - $pagesize == $start) $btn->attr('disabled', 'disabled'); 203bbe22a6aSAndreas Gohr 204bbe22a6aSAndreas Gohr $form->addTagClose('div'); 205bbe22a6aSAndreas Gohr $form->addTagClose('td'); 206bbe22a6aSAndreas Gohr $form->addTagClose('tr'); 207bbe22a6aSAndreas Gohr 208bbe22a6aSAndreas Gohr return $form; 209163ac707SMichael Wilmes } 210163ac707SMichael Wilmes 211163ac707SMichael Wilmes /** 212bbe22a6aSAndreas Gohr * Get the filtered users that have a twofactor provider set 213163ac707SMichael Wilmes * 214bbe22a6aSAndreas Gohr * @param array $filter 215163ac707SMichael Wilmes * @return array 216163ac707SMichael Wilmes */ 217bbe22a6aSAndreas Gohr protected function getUserData($filter) 218d0a31016SAndreas Gohr { 2196d69ca71SAndreas Gohr $users = Settings::findUsers('twofactor'); 220bbe22a6aSAndreas Gohr return $this->applyFilter($users, $filter); 221163ac707SMichael Wilmes } 222163ac707SMichael Wilmes 223163ac707SMichael Wilmes /** 224bbe22a6aSAndreas Gohr * Apply the given filters and return user details 225163ac707SMichael Wilmes * 226bbe22a6aSAndreas Gohr * @param string[] $users simple list of user names 227bbe22a6aSAndreas Gohr * @param array $filter 228bbe22a6aSAndreas Gohr * @return array (user => userdata) 229163ac707SMichael Wilmes */ 230bbe22a6aSAndreas Gohr protected function applyFilter($users, $filter) 231d0a31016SAndreas Gohr { 232bbe22a6aSAndreas Gohr global $auth; 233bbe22a6aSAndreas Gohr $filtered = []; 234163ac707SMichael Wilmes 235bbe22a6aSAndreas Gohr $hasFilter = (bool)array_filter(array_values($filter)); 236bbe22a6aSAndreas Gohr foreach ($users as $user) { 237bbe22a6aSAndreas Gohr $userdata = $auth->getUserData($user); 238bbe22a6aSAndreas Gohr if (!$userdata) continue; 239bbe22a6aSAndreas Gohr $userdata['user'] = $user; 240bbe22a6aSAndreas Gohr if ($hasFilter) { 241bbe22a6aSAndreas Gohr foreach ($filter as $key => $value) { 242*db15b76eSAndreas Gohr $q = preg_quote($value, '/'); 243*db15b76eSAndreas Gohr if ($value && preg_match("/$q/iu", $userdata[$key])) { 244bbe22a6aSAndreas Gohr $filtered[$user] = $userdata; 245bbe22a6aSAndreas Gohr continue 2; 246bbe22a6aSAndreas Gohr } 247bbe22a6aSAndreas Gohr } 248163ac707SMichael Wilmes } else { 249bbe22a6aSAndreas Gohr $filtered[$user] = $userdata; 250bbe22a6aSAndreas Gohr } 251bbe22a6aSAndreas Gohr } 252bbe22a6aSAndreas Gohr return $filtered; 253163ac707SMichael Wilmes } 254163ac707SMichael Wilmes 255bbe22a6aSAndreas Gohr /** 256bbe22a6aSAndreas Gohr * Get the current page of users 257bbe22a6aSAndreas Gohr * 258bbe22a6aSAndreas Gohr * @param array $users 259bbe22a6aSAndreas Gohr * @param int $start 260bbe22a6aSAndreas Gohr * @param int $pagesize 261bbe22a6aSAndreas Gohr * @return array 262bbe22a6aSAndreas Gohr */ 263bbe22a6aSAndreas Gohr protected function applyPagination($users, $start, $pagesize) 264bbe22a6aSAndreas Gohr { 265bbe22a6aSAndreas Gohr return array_slice($users, $start, $pagesize, true); 266163ac707SMichael Wilmes } 267163ac707SMichael Wilmes 268163ac707SMichael Wilmes} 269