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