1163ac707SMichael Wilmes<?php 2163ac707SMichael Wilmes/* 3163ac707SMichael Wilmes * Twofactor Manager 4163ac707SMichael Wilmes * 5163ac707SMichael Wilmes * Dokuwiki Admin Plugin 6163ac707SMichael Wilmes * Special thanks to the useradmin extension as a starting point for this class 7163ac707SMichael Wilmes * 8163ac707SMichael Wilmes * @author Mike Wilmes <mwilmes@avc.edu> 9163ac707SMichael Wilmes */ 10163ac707SMichael Wilmes// must be run within Dokuwiki 11163ac707SMichael Wilmesif (!defined('DOKU_INC')) die(); 12163ac707SMichael Wilmes 13*d0a31016SAndreas Gohrif (!defined('DOKU_TWOFACTOR_PLUGIN_IMAGES')) define('DOKU_TWOFACTOR_PLUGIN_IMAGES', 14*d0a31016SAndreas Gohr DOKU_BASE . 'lib/plugins/twofactor/images/'); 15163ac707SMichael Wilmes 16163ac707SMichael Wilmes/** 17163ac707SMichael Wilmes * All DokuWiki plugins to extend the admin function 18163ac707SMichael Wilmes * need to inherit from this class 19163ac707SMichael Wilmes */ 20*d0a31016SAndreas Gohrclass admin_plugin_twofactor extends DokuWiki_Admin_Plugin 21*d0a31016SAndreas Gohr{ 222cc41bddSMichael Wilmes protected $_user_list = array(); // list of users with attributes 23163ac707SMichael Wilmes protected $_filter = array(); // user selection filter(s) 24163ac707SMichael Wilmes protected $_start = 0; // index of first user to be displayed 25163ac707SMichael Wilmes protected $_last = 0; // index of the last user to be displayed 26163ac707SMichael Wilmes protected $_pagesize = 20; // number of users to list on one page 27163ac707SMichael Wilmes protected $_disabled = ''; // if disabled set to explanatory string 28163ac707SMichael Wilmes protected $_lastdisabled = false; // set to true if last user is unknown and last button is hence buggy 29163ac707SMichael Wilmes 30163ac707SMichael Wilmes /** 31163ac707SMichael Wilmes * Constructor 32163ac707SMichael Wilmes */ 33*d0a31016SAndreas Gohr public function __construct() 34*d0a31016SAndreas Gohr { 35163ac707SMichael Wilmes global $auth; 362cc41bddSMichael Wilmes 37a675b66fSMichael Wilmes $this->setupLocale(); 382cc41bddSMichael Wilmes 39163ac707SMichael Wilmes if (!isset($auth)) { 40163ac707SMichael Wilmes $this->_disabled = $this->lang['noauth']; 41163ac707SMichael Wilmes } 422cc41bddSMichael Wilmes 43890553cfSMichael Wilmes $requireAttribute = $this->getConf("enable") === 1; 44*d0a31016SAndreas Gohr $this->attribute = $requireAttribute ? $this->loadHelper('attribute', 45*d0a31016SAndreas Gohr 'TwoFactor depends on the Attribute plugin, but the Attribute plugin is not installed!') : null; 46185a84e4SMichael Wilmes 47185a84e4SMichael Wilmes $available = Twofactor_Auth_Module::_listModules(); 48185a84e4SMichael Wilmes $allmodules = Twofactor_Auth_Module::_loadModules($available); 49185a84e4SMichael Wilmes $failed = array_diff($available, array_keys($allmodules)); 50185a84e4SMichael Wilmes if (count($failed) > 0) { 51185a84e4SMichael Wilmes msg('At least one loaded module did not have a properly named class.' . ' ' . implode(', ', $failed), -1); 52185a84e4SMichael Wilmes } 53185a84e4SMichael Wilmes $this->modules = &$allmodules; 54163ac707SMichael Wilmes $this->_getUsers(); 55163ac707SMichael Wilmes } 5661ed09c1SMichael Wilmes 57*d0a31016SAndreas Gohr protected function _getUsers() 58*d0a31016SAndreas Gohr { 594a341b06SMichael Wilmes if ($this->getConf("enable") === 1) { 60163ac707SMichael Wilmes if (!is_null($this->attribute)) { 61163ac707SMichael Wilmes $attr = $this->attribute; 62163ac707SMichael Wilmes $this->_user_list = $this->attribute->enumerateUsers('twofactor'); 63*d0a31016SAndreas Gohr } else { 64163ac707SMichael Wilmes msg($this->lang['no_purpose'], -1); 65163ac707SMichael Wilmes } 66163ac707SMichael Wilmes } 674a341b06SMichael Wilmes } 68163ac707SMichael Wilmes 69163ac707SMichael Wilmes /** 70163ac707SMichael Wilmes * Return prompt for admin menu 71163ac707SMichael Wilmes * 72163ac707SMichael Wilmes * @param string $language 73163ac707SMichael Wilmes * @return string 74163ac707SMichael Wilmes */ 75*d0a31016SAndreas Gohr public function getMenuText($language) 76*d0a31016SAndreas Gohr { 77163ac707SMichael Wilmes global $INFO; 78*d0a31016SAndreas Gohr if (!$INFO['isadmin']) { 79163ac707SMichael Wilmes return parent::getMenuText($language); 80*d0a31016SAndreas Gohr } 81163ac707SMichael Wilmes 82163ac707SMichael Wilmes return $this->getLang('menu') . ' ' . $this->_disabled; 83163ac707SMichael Wilmes } 84163ac707SMichael Wilmes 85163ac707SMichael Wilmes /** 86163ac707SMichael Wilmes * return sort order for position in admin menu 87163ac707SMichael Wilmes * 88163ac707SMichael Wilmes * @return int 89163ac707SMichael Wilmes */ 90*d0a31016SAndreas Gohr public function getMenuSort() 91*d0a31016SAndreas Gohr { 92163ac707SMichael Wilmes return 2; 93163ac707SMichael Wilmes } 94163ac707SMichael Wilmes 95163ac707SMichael Wilmes /** 96163ac707SMichael Wilmes * @return int current start value for pageination 97163ac707SMichael Wilmes */ 98*d0a31016SAndreas Gohr public function getStart() 99*d0a31016SAndreas Gohr { 100163ac707SMichael Wilmes return $this->_start; 101163ac707SMichael Wilmes } 102163ac707SMichael Wilmes 103163ac707SMichael Wilmes /** 104163ac707SMichael Wilmes * @return int number of users per page 105163ac707SMichael Wilmes */ 106*d0a31016SAndreas Gohr public function getPagesize() 107*d0a31016SAndreas Gohr { 108163ac707SMichael Wilmes return $this->_pagesize; 109163ac707SMichael Wilmes } 110163ac707SMichael Wilmes 111163ac707SMichael Wilmes /** 112163ac707SMichael Wilmes * @param boolean $lastdisabled 113163ac707SMichael Wilmes */ 114*d0a31016SAndreas Gohr public function setLastdisabled($lastdisabled) 115*d0a31016SAndreas Gohr { 116163ac707SMichael Wilmes $this->_lastdisabled = $lastdisabled; 117163ac707SMichael Wilmes } 118163ac707SMichael Wilmes 119163ac707SMichael Wilmes /** 120163ac707SMichael Wilmes * Handle user request 121163ac707SMichael Wilmes * 122163ac707SMichael Wilmes * @return bool 123163ac707SMichael Wilmes */ 124*d0a31016SAndreas Gohr public function handle() 125*d0a31016SAndreas Gohr { 126163ac707SMichael Wilmes global $INPUT, $INFO; 127163ac707SMichael Wilmes if (!$INFO['isadmin']) return false; 128b71db9c8SMichael Wilmes if ($this->_disabled) { 129b71db9c8SMichael Wilmes // If disabled, don't process anything. 130b71db9c8SMichael Wilmes return true; 131b71db9c8SMichael Wilmes } 132163ac707SMichael Wilmes 133163ac707SMichael Wilmes // extract the command and any specific parameters 134163ac707SMichael Wilmes // submit button name is of the form - fn[cmd][param(s)] 135163ac707SMichael Wilmes $fn = $INPUT->param('fn'); 136163ac707SMichael Wilmes 137163ac707SMichael Wilmes if (is_array($fn)) { 138163ac707SMichael Wilmes $cmd = key($fn); 139163ac707SMichael Wilmes $param = is_array($fn[$cmd]) ? key($fn[$cmd]) : null; 140163ac707SMichael Wilmes } else { 141163ac707SMichael Wilmes $cmd = $fn; 142163ac707SMichael Wilmes $param = null; 143163ac707SMichael Wilmes } 144163ac707SMichael Wilmes 145163ac707SMichael Wilmes if ($cmd != "search") { 146163ac707SMichael Wilmes $this->_start = $INPUT->int('start', 0); 147163ac707SMichael Wilmes $this->_filter = $this->_retrieveFilter(); 148163ac707SMichael Wilmes } 149163ac707SMichael Wilmes 150163ac707SMichael Wilmes switch ($cmd) { 151*d0a31016SAndreas Gohr case "reset" : 152*d0a31016SAndreas Gohr $this->_resetUser(); 153*d0a31016SAndreas Gohr break; 154*d0a31016SAndreas Gohr case "search" : 155*d0a31016SAndreas Gohr $this->_setFilter($param); 156163ac707SMichael Wilmes $this->_start = 0; 157163ac707SMichael Wilmes break; 158163ac707SMichael Wilmes } 159163ac707SMichael Wilmes 160163ac707SMichael Wilmes $this->_user_total = count($this->_user_list) > 0 ? $this->_getUserCount($this->_filter) : -1; 161163ac707SMichael Wilmes 162163ac707SMichael Wilmes // page handling 163163ac707SMichael Wilmes switch ($cmd) { 164*d0a31016SAndreas Gohr case 'start' : 165*d0a31016SAndreas Gohr $this->_start = 0; 166*d0a31016SAndreas Gohr break; 167*d0a31016SAndreas Gohr case 'prev' : 168*d0a31016SAndreas Gohr $this->_start -= $this->_pagesize; 169*d0a31016SAndreas Gohr break; 170*d0a31016SAndreas Gohr case 'next' : 171*d0a31016SAndreas Gohr $this->_start += $this->_pagesize; 172*d0a31016SAndreas Gohr break; 173*d0a31016SAndreas Gohr case 'last' : 174*d0a31016SAndreas Gohr $this->_start = $this->_user_total; 175*d0a31016SAndreas Gohr break; 176163ac707SMichael Wilmes } 177163ac707SMichael Wilmes $this->_validatePagination(); 178163ac707SMichael Wilmes return true; 179163ac707SMichael Wilmes } 180163ac707SMichael Wilmes 181163ac707SMichael Wilmes /** 182163ac707SMichael Wilmes * Output appropriate html 183163ac707SMichael Wilmes * 184163ac707SMichael Wilmes * @return bool 185163ac707SMichael Wilmes */ 186*d0a31016SAndreas Gohr public function html() 187*d0a31016SAndreas Gohr { 188163ac707SMichael Wilmes global $ID, $INFO; 189163ac707SMichael Wilmes 190163ac707SMichael Wilmes if (!$INFO['isadmin']) { 191163ac707SMichael Wilmes print $this->lang['badauth']; 192163ac707SMichael Wilmes return false; 193163ac707SMichael Wilmes } 194163ac707SMichael Wilmes 1952cc41bddSMichael Wilmes if ($this->disabled) { 196b71db9c8SMichael Wilmes msg($this->_disabled, -1); 197b71db9c8SMichael Wilmes return true; 198b71db9c8SMichael Wilmes } 199b71db9c8SMichael Wilmes 200163ac707SMichael Wilmes $user_list = $this->_retrieveUsers($this->_start, $this->_pagesize, $this->_filter); 201163ac707SMichael Wilmes 202163ac707SMichael Wilmes $page_buttons = $this->_pagination(); 203163ac707SMichael Wilmes 204163ac707SMichael Wilmes print $this->locale_xhtml('intro'); 205163ac707SMichael Wilmes print $this->locale_xhtml('list'); 206163ac707SMichael Wilmes 207163ac707SMichael Wilmes ptln("<div id=\"user__manager\">"); 208163ac707SMichael Wilmes ptln("<div class=\"level2\">"); 209163ac707SMichael Wilmes 210163ac707SMichael Wilmes if (count($this->_user_list) > 0) { 211*d0a31016SAndreas Gohr ptln("<p>" . sprintf($this->lang['summary'], $this->_start + 1, $this->_last, 212*d0a31016SAndreas Gohr $this->_getUserCount($this->_filter), count($this->_user_list)) . "</p>"); 213163ac707SMichael Wilmes } else { 214163ac707SMichael Wilmes if (count($this->_user_list) < 0) { 215163ac707SMichael Wilmes $allUserTotal = 0; 216163ac707SMichael Wilmes } else { 217163ac707SMichael Wilmes $allUserTotal = count($this->_user_list); 218163ac707SMichael Wilmes } 219163ac707SMichael Wilmes ptln("<p>" . sprintf($this->lang['nonefound'], $allUserTotal) . "</p>"); 220163ac707SMichael Wilmes } 221163ac707SMichael Wilmes ptln("<form action=\"" . wl($ID) . "\" method=\"post\">"); 222163ac707SMichael Wilmes formSecurityToken(); 223163ac707SMichael Wilmes ptln(" <div class=\"table\">"); 224163ac707SMichael Wilmes ptln(" <table class=\"inline\">"); 225163ac707SMichael Wilmes ptln(" <thead>"); 226163ac707SMichael Wilmes ptln(" <tr>"); 227163ac707SMichael Wilmes ptln(" <th> </th><th>" . $this->lang["user_id"] . "</th><th>" . $this->lang["user_name"] . "</th><th>" . $this->lang["user_mail"] . "</th>"); 228163ac707SMichael Wilmes ptln(" </tr>"); 229163ac707SMichael Wilmes 230163ac707SMichael Wilmes ptln(" <tr>"); 231163ac707SMichael Wilmes ptln(" <td class=\"rightalign\"><input type=\"image\" src=\"" . DOKU_TWOFACTOR_PLUGIN_IMAGES . "search.png\" name=\"fn[search][new]\" title=\"" . $this->lang['search_prompt'] . "\" alt=\"" . $this->lang['search'] . "\" class=\"button\" /></td>"); 232163ac707SMichael Wilmes ptln(" <td><input type=\"text\" name=\"userid\" class=\"edit\" value=\"" . $this->_htmlFilter('user') . "\" /></td>"); 233163ac707SMichael Wilmes ptln(" <td><input type=\"text\" name=\"username\" class=\"edit\" value=\"" . $this->_htmlFilter('name') . "\" /></td>"); 234163ac707SMichael Wilmes ptln(" <td><input type=\"text\" name=\"usermail\" class=\"edit\" value=\"" . $this->_htmlFilter('mail') . "\" /></td>"); 235163ac707SMichael Wilmes ptln(" </tr>"); 236163ac707SMichael Wilmes ptln(" </thead>"); 237163ac707SMichael Wilmes 238163ac707SMichael Wilmes if ($this->_user_total) { 239163ac707SMichael Wilmes ptln(" <tbody>"); 240163ac707SMichael Wilmes foreach ($user_list as $user => $userinfo) { 241163ac707SMichael Wilmes extract($userinfo); 242163ac707SMichael Wilmes /** 243163ac707SMichael Wilmes * @var string $name 244163ac707SMichael Wilmes * @var string $pass 245163ac707SMichael Wilmes * @var string $mail 246163ac707SMichael Wilmes * @var array $grps 247163ac707SMichael Wilmes */ 248163ac707SMichael Wilmes ptln(" <tr class=\"user_info\">"); 249163ac707SMichael Wilmes ptln(" <td class=\"centeralign\"><input type=\"checkbox\" name=\"delete[" . hsc($user) . "]\" " . $delete_disable . " /></td>"); 250163ac707SMichael Wilmes if ($editable) { 251*d0a31016SAndreas Gohr ptln(" <td><a href=\"" . wl($ID, array( 252*d0a31016SAndreas Gohr 'fn[edit][' . $user . ']' => 1, 253163ac707SMichael Wilmes 'do' => 'admin', 254163ac707SMichael Wilmes 'page' => 'usermanager', 255*d0a31016SAndreas Gohr 'sectok' => getSecurityToken(), 256*d0a31016SAndreas Gohr )) . 257163ac707SMichael Wilmes "\" title=\"" . $this->lang['edit_prompt'] . "\">" . hsc($user) . "</a></td>"); 258163ac707SMichael Wilmes } else { 259163ac707SMichael Wilmes ptln(" <td>" . hsc($user) . "</td>"); 260163ac707SMichael Wilmes } 261163ac707SMichael Wilmes ptln(" <td>" . hsc($name) . "</td><td>" . hsc($mail) . "</td>"); 262163ac707SMichael Wilmes ptln(" </tr>"); 263163ac707SMichael Wilmes } 264163ac707SMichael Wilmes ptln(" </tbody>"); 265163ac707SMichael Wilmes } 266163ac707SMichael Wilmes 267163ac707SMichael Wilmes ptln(" <tbody>"); 268163ac707SMichael Wilmes ptln(" <tr><td colspan=\"5\" class=\"centeralign\">"); 269163ac707SMichael Wilmes ptln(" <span class=\"medialeft\">"); 270163ac707SMichael Wilmes ptln(" <button type=\"submit\" name=\"fn[reset]\" id=\"usrmgr__reset\" >" . $this->lang['reset_selected'] . "</button>"); 271163ac707SMichael Wilmes ptln(" "); 272163ac707SMichael Wilmes if (!empty($this->_filter)) { 273163ac707SMichael Wilmes ptln(" <button type=\"submit\" name=\"fn[search][clear]\">" . $this->lang['clear'] . "</button>"); 274163ac707SMichael Wilmes } 275163ac707SMichael Wilmes ptln(" <input type=\"hidden\" name=\"do\" value=\"admin\" />"); 276163ac707SMichael Wilmes ptln(" <input type=\"hidden\" name=\"page\" value=\"twofactor\" />"); 277163ac707SMichael Wilmes 278163ac707SMichael Wilmes $this->_htmlFilterSettings(2); 279163ac707SMichael Wilmes ptln(" </span>"); 280163ac707SMichael Wilmes ptln(" <span class=\"mediaright\">"); 281163ac707SMichael Wilmes ptln(" <button type=\"submit\" name=\"fn[start]\" " . $page_buttons['start'] . ">" . $this->lang['start'] . "</button>"); 282163ac707SMichael Wilmes ptln(" <button type=\"submit\" name=\"fn[prev]\" " . $page_buttons['prev'] . ">" . $this->lang['prev'] . "</button>"); 283163ac707SMichael Wilmes ptln(" <button type=\"submit\" name=\"fn[next]\" " . $page_buttons['next'] . ">" . $this->lang['next'] . "</button>"); 284163ac707SMichael Wilmes ptln(" <button type=\"submit\" name=\"fn[last]\" " . $page_buttons['last'] . ">" . $this->lang['last'] . "</button>"); 285163ac707SMichael Wilmes ptln(" </span>"); 286163ac707SMichael Wilmes 287163ac707SMichael Wilmes ptln(" </td></tr>"); 288163ac707SMichael Wilmes ptln(" </tbody>"); 289163ac707SMichael Wilmes ptln(" </table>"); 290163ac707SMichael Wilmes ptln(" </div>"); 291163ac707SMichael Wilmes 292163ac707SMichael Wilmes ptln("</form>"); 293163ac707SMichael Wilmes ptln("</div>"); 294163ac707SMichael Wilmes 295163ac707SMichael Wilmes ptln("</div>"); 296163ac707SMichael Wilmes return true; 297163ac707SMichael Wilmes } 298163ac707SMichael Wilmes 299163ac707SMichael Wilmes /** 300163ac707SMichael Wilmes * Prints a inputfield 301163ac707SMichael Wilmes * 302163ac707SMichael Wilmes * @param string $id 303163ac707SMichael Wilmes * @param string $name 304163ac707SMichael Wilmes * @param string $label 305163ac707SMichael Wilmes * @param string $value 306163ac707SMichael Wilmes * @param bool $cando whether auth backend is capable to do this action 307163ac707SMichael Wilmes * @param int $indent 308163ac707SMichael Wilmes */ 309*d0a31016SAndreas Gohr protected function _htmlInputField($id, $name, $label, $value, $cando, $indent = 0) 310*d0a31016SAndreas Gohr { 311163ac707SMichael Wilmes $class = $cando ? '' : ' class="disabled"'; 312163ac707SMichael Wilmes echo str_pad('', $indent); 313163ac707SMichael Wilmes 314163ac707SMichael Wilmes if ($name == 'userpass' || $name == 'userpass2') { 315163ac707SMichael Wilmes $fieldtype = 'password'; 316163ac707SMichael Wilmes $autocomp = 'autocomplete="off"'; 317163ac707SMichael Wilmes } elseif ($name == 'usermail') { 318163ac707SMichael Wilmes $fieldtype = 'email'; 319163ac707SMichael Wilmes $autocomp = ''; 320163ac707SMichael Wilmes } else { 321163ac707SMichael Wilmes $fieldtype = 'text'; 322163ac707SMichael Wilmes $autocomp = ''; 323163ac707SMichael Wilmes } 324163ac707SMichael Wilmes $value = hsc($value); 325163ac707SMichael Wilmes 326163ac707SMichael Wilmes echo "<tr $class>"; 327163ac707SMichael Wilmes echo "<td><label for=\"$id\" >$label: </label></td>"; 328163ac707SMichael Wilmes echo "<td>"; 329163ac707SMichael Wilmes if ($cando) { 330163ac707SMichael Wilmes echo "<input type=\"$fieldtype\" id=\"$id\" name=\"$name\" value=\"$value\" class=\"edit\" $autocomp />"; 331163ac707SMichael Wilmes } else { 332163ac707SMichael Wilmes echo "<input type=\"hidden\" name=\"$name\" value=\"$value\" />"; 333163ac707SMichael Wilmes echo "<input type=\"$fieldtype\" id=\"$id\" name=\"$name\" value=\"$value\" class=\"edit disabled\" disabled=\"disabled\" />"; 334163ac707SMichael Wilmes } 335163ac707SMichael Wilmes echo "</td>"; 336163ac707SMichael Wilmes echo "</tr>"; 337163ac707SMichael Wilmes } 338163ac707SMichael Wilmes 339163ac707SMichael Wilmes /** 340163ac707SMichael Wilmes * Returns htmlescaped filter value 341163ac707SMichael Wilmes * 342163ac707SMichael Wilmes * @param string $key name of search field 343163ac707SMichael Wilmes * @return string html escaped value 344163ac707SMichael Wilmes */ 345*d0a31016SAndreas Gohr protected function _htmlFilter($key) 346*d0a31016SAndreas Gohr { 347163ac707SMichael Wilmes if (empty($this->_filter)) return ''; 348163ac707SMichael Wilmes return (isset($this->_filter[$key]) ? hsc($this->_filter[$key]) : ''); 349163ac707SMichael Wilmes } 350163ac707SMichael Wilmes 351163ac707SMichael Wilmes /** 352163ac707SMichael Wilmes * Print hidden inputs with the current filter values 353163ac707SMichael Wilmes * 354163ac707SMichael Wilmes * @param int $indent 355163ac707SMichael Wilmes */ 356*d0a31016SAndreas Gohr protected function _htmlFilterSettings($indent = 0) 357*d0a31016SAndreas Gohr { 358163ac707SMichael Wilmes 359163ac707SMichael Wilmes ptln("<input type=\"hidden\" name=\"start\" value=\"" . $this->_start . "\" />", $indent); 360163ac707SMichael Wilmes 361163ac707SMichael Wilmes foreach ($this->_filter as $key => $filter) { 362163ac707SMichael Wilmes ptln("<input type=\"hidden\" name=\"filter[" . $key . "]\" value=\"" . hsc($filter) . "\" />", $indent); 363163ac707SMichael Wilmes } 364163ac707SMichael Wilmes } 365163ac707SMichael Wilmes 366163ac707SMichael Wilmes /** 367163ac707SMichael Wilmes * Reset user (a user has been selected to remove two factor authentication) 368163ac707SMichael Wilmes * 369163ac707SMichael Wilmes * @param string $param id of the user 370163ac707SMichael Wilmes * @return bool whether succesful 371163ac707SMichael Wilmes */ 372*d0a31016SAndreas Gohr protected function _resetUser() 373*d0a31016SAndreas Gohr { 374163ac707SMichael Wilmes global $INPUT; 375163ac707SMichael Wilmes if (!checkSecurityToken()) return false; 376163ac707SMichael Wilmes 377163ac707SMichael Wilmes $selected = $INPUT->arr('delete'); 378163ac707SMichael Wilmes if (empty($selected)) return false; 379163ac707SMichael Wilmes $selected = array_keys($selected); 380163ac707SMichael Wilmes 381163ac707SMichael Wilmes if (in_array($_SERVER['REMOTE_USER'], $selected)) { 382163ac707SMichael Wilmes msg($this->lang['reset_not_self'], -1); 383163ac707SMichael Wilmes return false; 384163ac707SMichael Wilmes } 385163ac707SMichael Wilmes 386163ac707SMichael Wilmes $count = 0; 387163ac707SMichael Wilmes foreach ($selected as $user) { 388163ac707SMichael Wilmes // All users here have a attribute namespace file. Purge them. 389185a84e4SMichael Wilmes $purged = $this->attribute->purge('twofactor', $user); 390185a84e4SMichael Wilmes foreach ($this->modules as $mod) { 391185a84e4SMichael Wilmes $purged |= $this->attribute->purge($mod->moduleName, $user); 392185a84e4SMichael Wilmes } 393185a84e4SMichael Wilmes $count += $purged ? 1 : 0; 394163ac707SMichael Wilmes } 395163ac707SMichael Wilmes 396163ac707SMichael Wilmes if ($count == count($selected)) { 397163ac707SMichael Wilmes $text = str_replace('%d', $count, $this->lang['reset_ok']); 398163ac707SMichael Wilmes msg("$text.", 1); 399163ac707SMichael Wilmes } else { 400163ac707SMichael Wilmes $part1 = str_replace('%d', $count, $this->lang['reset_ok']); 401163ac707SMichael Wilmes $part2 = str_replace('%d', (count($selected) - $count), $this->lang['reset_fail']); 4022cc41bddSMichael Wilmes // Output results. 403163ac707SMichael Wilmes msg("$part1, $part2", -1); 404163ac707SMichael Wilmes } 405163ac707SMichael Wilmes 406163ac707SMichael Wilmes // Now refresh the user list. 407163ac707SMichael Wilmes $this->_getUsers(); 408163ac707SMichael Wilmes 409163ac707SMichael Wilmes return true; 410163ac707SMichael Wilmes } 411163ac707SMichael Wilmes 412*d0a31016SAndreas Gohr protected function _retrieveFilteredUsers($filter = array()) 413*d0a31016SAndreas Gohr { 4142cc41bddSMichael Wilmes global $auth; 415163ac707SMichael Wilmes $users = array(); 4162cc41bddSMichael Wilmes $noUsers = is_null($auth) || !$auth->canDo('getUsers'); 417163ac707SMichael Wilmes foreach ($this->_user_list as $user) { 4182cc41bddSMichael Wilmes if ($noUsers) { 4192cc41bddSMichael Wilmes $userdata = array('user' => $user, 'name' => $user, 'mail' => null); 4202cc41bddSMichael Wilmes } else { 4212cc41bddSMichael Wilmes $userdata = $auth->getUserData($user); 42291cdada2SMichael Wilmes if (!is_array($userdata)) { 42391cdada2SMichael Wilmes $userdata = array('user' => $user, 'name' => null, 'mail' => null); 42491cdada2SMichael Wilmes } 4252cc41bddSMichael Wilmes } 426163ac707SMichael Wilmes $include = true; 427163ac707SMichael Wilmes foreach ($filter as $key => $value) { 428163ac707SMichael Wilmes $include &= strstr($userdata[$key], $value); 429163ac707SMichael Wilmes } 430*d0a31016SAndreas Gohr if ($include) { 431*d0a31016SAndreas Gohr $users[$user] = $userdata; 432*d0a31016SAndreas Gohr } 433163ac707SMichael Wilmes } 434163ac707SMichael Wilmes return $users; 435163ac707SMichael Wilmes } 436163ac707SMichael Wilmes 437*d0a31016SAndreas Gohr protected function _getUserCount($filter) 438*d0a31016SAndreas Gohr { 439163ac707SMichael Wilmes return count($this->_retrieveFilteredUsers($filter)); 440163ac707SMichael Wilmes } 441163ac707SMichael Wilmes 442*d0a31016SAndreas Gohr protected function _retrieveUsers($start, $pagesize, $filter) 443*d0a31016SAndreas Gohr { 444163ac707SMichael Wilmes $users = $this->_retrieveFilteredUsers($filter); 445163ac707SMichael Wilmes return $users; 446163ac707SMichael Wilmes } 447163ac707SMichael Wilmes 448163ac707SMichael Wilmes /** 449163ac707SMichael Wilmes * Retrieve & clean user data from the form 450163ac707SMichael Wilmes * 451163ac707SMichael Wilmes * @param bool $clean whether the cleanUser method of the authentication backend is applied 452163ac707SMichael Wilmes * @return array (user, password, full name, email, array(groups)) 453163ac707SMichael Wilmes */ 454*d0a31016SAndreas Gohr protected function _retrieveUser($clean = true) 455*d0a31016SAndreas Gohr { 456163ac707SMichael Wilmes /** @var DokuWiki_Auth_Plugin $auth */ 457163ac707SMichael Wilmes global $auth; 458163ac707SMichael Wilmes global $INPUT; 459163ac707SMichael Wilmes 460163ac707SMichael Wilmes $user = array(); 4612cc41bddSMichael Wilmes $user[] = $INPUT->str('userid'); 4622cc41bddSMichael Wilmes $user[] = $INPUT->str('username'); 4632cc41bddSMichael Wilmes $user[] = $INPUT->str('usermail'); 464163ac707SMichael Wilmes 465163ac707SMichael Wilmes return $user; 466163ac707SMichael Wilmes } 467163ac707SMichael Wilmes 468163ac707SMichael Wilmes /** 469163ac707SMichael Wilmes * Set the filter with the current search terms or clear the filter 470163ac707SMichael Wilmes * 471163ac707SMichael Wilmes * @param string $op 'new' or 'clear' 472163ac707SMichael Wilmes */ 473*d0a31016SAndreas Gohr protected function _setFilter($op) 474*d0a31016SAndreas Gohr { 475163ac707SMichael Wilmes 476163ac707SMichael Wilmes $this->_filter = array(); 477163ac707SMichael Wilmes 478163ac707SMichael Wilmes if ($op == 'new') { 4792cc41bddSMichael Wilmes list($user, $name, $mail) = $this->_retrieveUser(); 480163ac707SMichael Wilmes 481163ac707SMichael Wilmes if (!empty($user)) $this->_filter['user'] = $user; 482163ac707SMichael Wilmes if (!empty($name)) $this->_filter['name'] = $name; 483163ac707SMichael Wilmes if (!empty($mail)) $this->_filter['mail'] = $mail; 484163ac707SMichael Wilmes } 485163ac707SMichael Wilmes } 486163ac707SMichael Wilmes 487163ac707SMichael Wilmes /** 488163ac707SMichael Wilmes * Get the current search terms 489163ac707SMichael Wilmes * 490163ac707SMichael Wilmes * @return array 491163ac707SMichael Wilmes */ 492*d0a31016SAndreas Gohr protected function _retrieveFilter() 493*d0a31016SAndreas Gohr { 494163ac707SMichael Wilmes global $INPUT; 495163ac707SMichael Wilmes 496163ac707SMichael Wilmes $t_filter = $INPUT->arr('filter'); 497163ac707SMichael Wilmes 498163ac707SMichael Wilmes // messy, but this way we ensure we aren't getting any additional crap from malicious users 499163ac707SMichael Wilmes $filter = array(); 500163ac707SMichael Wilmes 501163ac707SMichael Wilmes if (isset($t_filter['user'])) $filter['user'] = $t_filter['user']; 502163ac707SMichael Wilmes if (isset($t_filter['name'])) $filter['name'] = $t_filter['name']; 503163ac707SMichael Wilmes if (isset($t_filter['mail'])) $filter['mail'] = $t_filter['mail']; 504163ac707SMichael Wilmes 505163ac707SMichael Wilmes return $filter; 506163ac707SMichael Wilmes } 507163ac707SMichael Wilmes 508163ac707SMichael Wilmes /** 509163ac707SMichael Wilmes * Validate and improve the pagination values 510163ac707SMichael Wilmes */ 511*d0a31016SAndreas Gohr protected function _validatePagination() 512*d0a31016SAndreas Gohr { 513163ac707SMichael Wilmes 514163ac707SMichael Wilmes if ($this->_start >= $this->_user_total) { 515163ac707SMichael Wilmes $this->_start = $this->_user_total - $this->_pagesize; 516163ac707SMichael Wilmes } 517163ac707SMichael Wilmes if ($this->_start < 0) $this->_start = 0; 518163ac707SMichael Wilmes 519163ac707SMichael Wilmes $this->_last = min($this->_user_total, $this->_start + $this->_pagesize); 520163ac707SMichael Wilmes } 521163ac707SMichael Wilmes 522163ac707SMichael Wilmes /** 523163ac707SMichael Wilmes * Return an array of strings to enable/disable pagination buttons 524163ac707SMichael Wilmes * 525163ac707SMichael Wilmes * @return array with enable/disable attributes 526163ac707SMichael Wilmes */ 527*d0a31016SAndreas Gohr protected function _pagination() 528*d0a31016SAndreas Gohr { 529163ac707SMichael Wilmes 530163ac707SMichael Wilmes $disabled = 'disabled="disabled"'; 531163ac707SMichael Wilmes 532163ac707SMichael Wilmes $buttons = array(); 533163ac707SMichael Wilmes $buttons['start'] = $buttons['prev'] = ($this->_start == 0) ? $disabled : ''; 534163ac707SMichael Wilmes 535163ac707SMichael Wilmes if ($this->_user_total == -1) { 536163ac707SMichael Wilmes $buttons['last'] = $disabled; 537163ac707SMichael Wilmes $buttons['next'] = ''; 538163ac707SMichael Wilmes } else { 539163ac707SMichael Wilmes $buttons['last'] = $buttons['next'] = (($this->_start + $this->_pagesize) >= $this->_user_total) ? $disabled : ''; 540163ac707SMichael Wilmes } 541163ac707SMichael Wilmes 542163ac707SMichael Wilmes if ($this->_lastdisabled) { 543163ac707SMichael Wilmes $buttons['last'] = $disabled; 544163ac707SMichael Wilmes } 545163ac707SMichael Wilmes 546163ac707SMichael Wilmes return $buttons; 547163ac707SMichael Wilmes } 548163ac707SMichael Wilmes 549163ac707SMichael Wilmes} 550