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 13163ac707SMichael Wilmesif(!defined('DOKU_TWOFACTOR_PLUGIN_IMAGES')) define('DOKU_TWOFACTOR_PLUGIN_IMAGES',DOKU_BASE.'lib/plugins/twofactor/images/'); 14163ac707SMichael Wilmes 15163ac707SMichael Wilmes/** 16163ac707SMichael Wilmes * All DokuWiki plugins to extend the admin function 17163ac707SMichael Wilmes * need to inherit from this class 18163ac707SMichael Wilmes */ 19163ac707SMichael Wilmesclass admin_plugin_twofactor extends DokuWiki_Admin_Plugin { 20163ac707SMichael Wilmes protected $_auth = null; // auth object 21163ac707SMichael Wilmes protected $_user_list = array(); // number of users with attributes 22163ac707SMichael Wilmes protected $_filter = array(); // user selection filter(s) 23163ac707SMichael Wilmes protected $_start = 0; // index of first user to be displayed 24163ac707SMichael Wilmes protected $_last = 0; // index of the last user to be displayed 25163ac707SMichael Wilmes protected $_pagesize = 20; // number of users to list on one page 26163ac707SMichael Wilmes protected $_disabled = ''; // if disabled set to explanatory string 27163ac707SMichael Wilmes protected $_lastdisabled = false; // set to true if last user is unknown and last button is hence buggy 28163ac707SMichael Wilmes 29163ac707SMichael Wilmes /** 30163ac707SMichael Wilmes * Constructor 31163ac707SMichael Wilmes */ 32163ac707SMichael Wilmes public function __construct(){ 33163ac707SMichael Wilmes global $auth; 34*a675b66fSMichael Wilmes $this->setupLocale(); 35163ac707SMichael Wilmes if (!isset($auth)) { 36163ac707SMichael Wilmes $this->_disabled = $this->lang['noauth']; 37163ac707SMichael Wilmes } else if (!$auth->canDo('getUsers')) { 38163ac707SMichael Wilmes $this->_disabled = $this->lang['nosupport']; 39163ac707SMichael Wilmes } else { 40163ac707SMichael Wilmes // we're good to go 41163ac707SMichael Wilmes $this->_auth = & $auth; 42163ac707SMichael Wilmes } 43890553cfSMichael Wilmes $requireAttribute = $this->getConf("enable") === 1; 447e44460aSMichael Wilmes $this->attribute = $requireAttribute ? $this->loadHelper('attribute', 'TwoFactor depends on the Attribute plugin, but the Attribute plugin is not installed!') : null; 45185a84e4SMichael Wilmes 46185a84e4SMichael Wilmes $available = Twofactor_Auth_Module::_listModules(); 47185a84e4SMichael Wilmes $allmodules = Twofactor_Auth_Module::_loadModules($available); 48185a84e4SMichael Wilmes $failed = array_diff($available, array_keys($allmodules)); 49185a84e4SMichael Wilmes if (count($failed) > 0) { 50185a84e4SMichael Wilmes msg('At least one loaded module did not have a properly named class.' . ' ' . implode(', ', $failed), -1); 51185a84e4SMichael Wilmes } 52185a84e4SMichael Wilmes $this->modules = &$allmodules; 53163ac707SMichael Wilmes $this->_getUsers(); 54163ac707SMichael Wilmes } 5561ed09c1SMichael Wilmes 5661ed09c1SMichael Wilmes /** 5761ed09c1SMichael Wilmes * return some info 5861ed09c1SMichael Wilmes */ 5961ed09c1SMichael Wilmes function getInfo(){ 6061ed09c1SMichael Wilmes return array( 6161ed09c1SMichael Wilmes 'author' => 'Mike Wilmes', 6261ed09c1SMichael Wilmes 'email' => 'mwilmes@wilminator.com', 63b71db9c8SMichael Wilmes 'date' => '2018-06-26', 6461ed09c1SMichael Wilmes 'name' => 'TwoFactor Plugin', 6561ed09c1SMichael Wilmes 'desc' => 'This plugin provides for two factor authentication using either Google Authenticator or one time passwords sent by email or SMS appliance.', 6661ed09c1SMichael Wilmes 'url' => 'http://www.dokuwiki.org/plugin:twofactor', 6761ed09c1SMichael Wilmes ); 6861ed09c1SMichael Wilmes } 69163ac707SMichael Wilmes 70163ac707SMichael Wilmes protected function _getUsers() { 714a341b06SMichael Wilmes if ($this->getConf("enable") === 1) { 72163ac707SMichael Wilmes if (!is_null($this->attribute)) { 73163ac707SMichael Wilmes $attr = $this->attribute; 74163ac707SMichael Wilmes $this->_user_list = $this->attribute->enumerateUsers('twofactor'); 75163ac707SMichael Wilmes } 76163ac707SMichael Wilmes else { 77163ac707SMichael Wilmes msg($this->lang['no_purpose'], -1); 78163ac707SMichael Wilmes } 79163ac707SMichael Wilmes } 804a341b06SMichael Wilmes } 81163ac707SMichael Wilmes 82163ac707SMichael Wilmes /** 83163ac707SMichael Wilmes * Return prompt for admin menu 84163ac707SMichael Wilmes * 85163ac707SMichael Wilmes * @param string $language 86163ac707SMichael Wilmes * @return string 87163ac707SMichael Wilmes */ 88163ac707SMichael Wilmes public function getMenuText($language) { 89163ac707SMichael Wilmes global $INFO; 90163ac707SMichael Wilmes if (!$INFO['isadmin']) 91163ac707SMichael Wilmes return parent::getMenuText($language); 92163ac707SMichael Wilmes 93163ac707SMichael Wilmes return $this->getLang('menu').' '.$this->_disabled; 94163ac707SMichael Wilmes } 95163ac707SMichael Wilmes 96163ac707SMichael Wilmes /** 97163ac707SMichael Wilmes * return sort order for position in admin menu 98163ac707SMichael Wilmes * 99163ac707SMichael Wilmes * @return int 100163ac707SMichael Wilmes */ 101163ac707SMichael Wilmes public function getMenuSort() { 102163ac707SMichael Wilmes return 2; 103163ac707SMichael Wilmes } 104163ac707SMichael Wilmes 105163ac707SMichael Wilmes /** 106163ac707SMichael Wilmes * @return int current start value for pageination 107163ac707SMichael Wilmes */ 108163ac707SMichael Wilmes public function getStart() { 109163ac707SMichael Wilmes return $this->_start; 110163ac707SMichael Wilmes } 111163ac707SMichael Wilmes 112163ac707SMichael Wilmes /** 113163ac707SMichael Wilmes * @return int number of users per page 114163ac707SMichael Wilmes */ 115163ac707SMichael Wilmes public function getPagesize() { 116163ac707SMichael Wilmes return $this->_pagesize; 117163ac707SMichael Wilmes } 118163ac707SMichael Wilmes 119163ac707SMichael Wilmes /** 120163ac707SMichael Wilmes * @param boolean $lastdisabled 121163ac707SMichael Wilmes */ 122163ac707SMichael Wilmes public function setLastdisabled($lastdisabled) { 123163ac707SMichael Wilmes $this->_lastdisabled = $lastdisabled; 124163ac707SMichael Wilmes } 125163ac707SMichael Wilmes 126163ac707SMichael Wilmes /** 127163ac707SMichael Wilmes * Handle user request 128163ac707SMichael Wilmes * 129163ac707SMichael Wilmes * @return bool 130163ac707SMichael Wilmes */ 131163ac707SMichael Wilmes public function handle() { 132163ac707SMichael Wilmes global $INPUT, $INFO; 133163ac707SMichael Wilmes if (!$INFO['isadmin']) return false; 134b71db9c8SMichael Wilmes if ($this->_disabled) { 135b71db9c8SMichael Wilmes // If disabled, don't process anything. 136b71db9c8SMichael Wilmes return true; 137b71db9c8SMichael Wilmes } 138163ac707SMichael Wilmes 139163ac707SMichael Wilmes // extract the command and any specific parameters 140163ac707SMichael Wilmes // submit button name is of the form - fn[cmd][param(s)] 141163ac707SMichael Wilmes $fn = $INPUT->param('fn'); 142163ac707SMichael Wilmes 143163ac707SMichael Wilmes if (is_array($fn)) { 144163ac707SMichael Wilmes $cmd = key($fn); 145163ac707SMichael Wilmes $param = is_array($fn[$cmd]) ? key($fn[$cmd]) : null; 146163ac707SMichael Wilmes } else { 147163ac707SMichael Wilmes $cmd = $fn; 148163ac707SMichael Wilmes $param = null; 149163ac707SMichael Wilmes } 150163ac707SMichael Wilmes 151163ac707SMichael Wilmes if ($cmd != "search") { 152163ac707SMichael Wilmes $this->_start = $INPUT->int('start', 0); 153163ac707SMichael Wilmes $this->_filter = $this->_retrieveFilter(); 154163ac707SMichael Wilmes } 155163ac707SMichael Wilmes 156163ac707SMichael Wilmes switch($cmd){ 157163ac707SMichael Wilmes case "reset" : $this->_resetUser(); break; 158163ac707SMichael Wilmes case "search" : $this->_setFilter($param); 159163ac707SMichael Wilmes $this->_start = 0; 160163ac707SMichael Wilmes break; 161163ac707SMichael Wilmes } 162163ac707SMichael Wilmes 163163ac707SMichael Wilmes $this->_user_total = count($this->_user_list) > 0 ? $this->_getUserCount($this->_filter) : -1; 164163ac707SMichael Wilmes 165163ac707SMichael Wilmes // page handling 166163ac707SMichael Wilmes switch($cmd){ 167163ac707SMichael Wilmes case 'start' : $this->_start = 0; break; 168163ac707SMichael Wilmes case 'prev' : $this->_start -= $this->_pagesize; break; 169163ac707SMichael Wilmes case 'next' : $this->_start += $this->_pagesize; break; 170163ac707SMichael Wilmes case 'last' : $this->_start = $this->_user_total; break; 171163ac707SMichael Wilmes } 172163ac707SMichael Wilmes $this->_validatePagination(); 173163ac707SMichael Wilmes return true; 174163ac707SMichael Wilmes } 175163ac707SMichael Wilmes 176163ac707SMichael Wilmes /** 177163ac707SMichael Wilmes * Output appropriate html 178163ac707SMichael Wilmes * 179163ac707SMichael Wilmes * @return bool 180163ac707SMichael Wilmes */ 181163ac707SMichael Wilmes public function html() { 182163ac707SMichael Wilmes global $ID, $INFO; 183163ac707SMichael Wilmes 184163ac707SMichael Wilmes if(!$INFO['isadmin']) { 185163ac707SMichael Wilmes print $this->lang['badauth']; 186163ac707SMichael Wilmes return false; 187163ac707SMichael Wilmes } 188163ac707SMichael Wilmes 189b71db9c8SMichael Wilmes if ($this->disabled !== '') { 190b71db9c8SMichael Wilmes msg($this->_disabled, -1); 191b71db9c8SMichael Wilmes return true; 192b71db9c8SMichael Wilmes } 193b71db9c8SMichael Wilmes 194163ac707SMichael Wilmes $user_list = $this->_retrieveUsers($this->_start, $this->_pagesize, $this->_filter); 195163ac707SMichael Wilmes 196163ac707SMichael Wilmes $page_buttons = $this->_pagination(); 197163ac707SMichael Wilmes 198163ac707SMichael Wilmes print $this->locale_xhtml('intro'); 199163ac707SMichael Wilmes print $this->locale_xhtml('list'); 200163ac707SMichael Wilmes 201163ac707SMichael Wilmes ptln("<div id=\"user__manager\">"); 202163ac707SMichael Wilmes ptln("<div class=\"level2\">"); 203163ac707SMichael Wilmes 204163ac707SMichael Wilmes if (count($this->_user_list) > 0) { 205163ac707SMichael Wilmes ptln("<p>".sprintf($this->lang['summary'],$this->_start+1,$this->_last,$this->_getUserCount($this->_filter),count($this->_user_list))."</p>"); 206163ac707SMichael Wilmes } else { 207163ac707SMichael Wilmes if(count($this->_user_list) < 0) { 208163ac707SMichael Wilmes $allUserTotal = 0; 209163ac707SMichael Wilmes } else { 210163ac707SMichael Wilmes $allUserTotal = count($this->_user_list); 211163ac707SMichael Wilmes } 212163ac707SMichael Wilmes ptln("<p>".sprintf($this->lang['nonefound'], $allUserTotal)."</p>"); 213163ac707SMichael Wilmes } 214163ac707SMichael Wilmes ptln("<form action=\"".wl($ID)."\" method=\"post\">"); 215163ac707SMichael Wilmes formSecurityToken(); 216163ac707SMichael Wilmes ptln(" <div class=\"table\">"); 217163ac707SMichael Wilmes ptln(" <table class=\"inline\">"); 218163ac707SMichael Wilmes ptln(" <thead>"); 219163ac707SMichael Wilmes ptln(" <tr>"); 220163ac707SMichael Wilmes ptln(" <th> </th><th>".$this->lang["user_id"]."</th><th>".$this->lang["user_name"]."</th><th>".$this->lang["user_mail"]."</th>"); 221163ac707SMichael Wilmes ptln(" </tr>"); 222163ac707SMichael Wilmes 223163ac707SMichael Wilmes ptln(" <tr>"); 224163ac707SMichael 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>"); 225163ac707SMichael Wilmes ptln(" <td><input type=\"text\" name=\"userid\" class=\"edit\" value=\"".$this->_htmlFilter('user')."\" /></td>"); 226163ac707SMichael Wilmes ptln(" <td><input type=\"text\" name=\"username\" class=\"edit\" value=\"".$this->_htmlFilter('name')."\" /></td>"); 227163ac707SMichael Wilmes ptln(" <td><input type=\"text\" name=\"usermail\" class=\"edit\" value=\"".$this->_htmlFilter('mail')."\" /></td>"); 228163ac707SMichael Wilmes ptln(" </tr>"); 229163ac707SMichael Wilmes ptln(" </thead>"); 230163ac707SMichael Wilmes 231163ac707SMichael Wilmes if ($this->_user_total) { 232163ac707SMichael Wilmes ptln(" <tbody>"); 233163ac707SMichael Wilmes foreach ($user_list as $user => $userinfo) { 234163ac707SMichael Wilmes extract($userinfo); 235163ac707SMichael Wilmes /** 236163ac707SMichael Wilmes * @var string $name 237163ac707SMichael Wilmes * @var string $pass 238163ac707SMichael Wilmes * @var string $mail 239163ac707SMichael Wilmes * @var array $grps 240163ac707SMichael Wilmes */ 241163ac707SMichael Wilmes $groups = join(', ',$grps); 242163ac707SMichael Wilmes ptln(" <tr class=\"user_info\">"); 243163ac707SMichael Wilmes ptln(" <td class=\"centeralign\"><input type=\"checkbox\" name=\"delete[".hsc($user)."]\" ".$delete_disable." /></td>"); 244163ac707SMichael Wilmes if ($editable) { 245163ac707SMichael Wilmes ptln(" <td><a href=\"".wl($ID,array('fn[edit]['.$user.']' => 1, 246163ac707SMichael Wilmes 'do' => 'admin', 247163ac707SMichael Wilmes 'page' => 'usermanager', 248163ac707SMichael Wilmes 'sectok' => getSecurityToken())). 249163ac707SMichael Wilmes "\" title=\"".$this->lang['edit_prompt']."\">".hsc($user)."</a></td>"); 250163ac707SMichael Wilmes } else { 251163ac707SMichael Wilmes ptln(" <td>".hsc($user)."</td>"); 252163ac707SMichael Wilmes } 253163ac707SMichael Wilmes ptln(" <td>".hsc($name)."</td><td>".hsc($mail)."</td>"); 254163ac707SMichael Wilmes ptln(" </tr>"); 255163ac707SMichael Wilmes } 256163ac707SMichael Wilmes ptln(" </tbody>"); 257163ac707SMichael Wilmes } 258163ac707SMichael Wilmes 259163ac707SMichael Wilmes ptln(" <tbody>"); 260163ac707SMichael Wilmes ptln(" <tr><td colspan=\"5\" class=\"centeralign\">"); 261163ac707SMichael Wilmes ptln(" <span class=\"medialeft\">"); 262163ac707SMichael Wilmes ptln(" <button type=\"submit\" name=\"fn[reset]\" id=\"usrmgr__reset\" >".$this->lang['reset_selected']."</button>"); 263163ac707SMichael Wilmes ptln(" "); 264163ac707SMichael Wilmes if (!empty($this->_filter)) { 265163ac707SMichael Wilmes ptln(" <button type=\"submit\" name=\"fn[search][clear]\">".$this->lang['clear']."</button>"); 266163ac707SMichael Wilmes } 267163ac707SMichael Wilmes ptln(" <input type=\"hidden\" name=\"do\" value=\"admin\" />"); 268163ac707SMichael Wilmes ptln(" <input type=\"hidden\" name=\"page\" value=\"twofactor\" />"); 269163ac707SMichael Wilmes 270163ac707SMichael Wilmes $this->_htmlFilterSettings(2); 271163ac707SMichael Wilmes ptln(" </span>"); 272163ac707SMichael Wilmes ptln(" <span class=\"mediaright\">"); 273163ac707SMichael Wilmes ptln(" <button type=\"submit\" name=\"fn[start]\" ".$page_buttons['start'].">".$this->lang['start']."</button>"); 274163ac707SMichael Wilmes ptln(" <button type=\"submit\" name=\"fn[prev]\" ".$page_buttons['prev'].">".$this->lang['prev']."</button>"); 275163ac707SMichael Wilmes ptln(" <button type=\"submit\" name=\"fn[next]\" ".$page_buttons['next'].">".$this->lang['next']."</button>"); 276163ac707SMichael Wilmes ptln(" <button type=\"submit\" name=\"fn[last]\" ".$page_buttons['last'].">".$this->lang['last']."</button>"); 277163ac707SMichael Wilmes ptln(" </span>"); 278163ac707SMichael Wilmes 279163ac707SMichael Wilmes ptln(" </td></tr>"); 280163ac707SMichael Wilmes ptln(" </tbody>"); 281163ac707SMichael Wilmes ptln(" </table>"); 282163ac707SMichael Wilmes ptln(" </div>"); 283163ac707SMichael Wilmes 284163ac707SMichael Wilmes ptln("</form>"); 285163ac707SMichael Wilmes ptln("</div>"); 286163ac707SMichael Wilmes 287163ac707SMichael Wilmes ptln("</div>"); 288163ac707SMichael Wilmes return true; 289163ac707SMichael Wilmes } 290163ac707SMichael Wilmes 291163ac707SMichael Wilmes 292163ac707SMichael Wilmes /** 293163ac707SMichael Wilmes * Prints a inputfield 294163ac707SMichael Wilmes * 295163ac707SMichael Wilmes * @param string $id 296163ac707SMichael Wilmes * @param string $name 297163ac707SMichael Wilmes * @param string $label 298163ac707SMichael Wilmes * @param string $value 299163ac707SMichael Wilmes * @param bool $cando whether auth backend is capable to do this action 300163ac707SMichael Wilmes * @param int $indent 301163ac707SMichael Wilmes */ 302163ac707SMichael Wilmes protected function _htmlInputField($id, $name, $label, $value, $cando, $indent=0) { 303163ac707SMichael Wilmes $class = $cando ? '' : ' class="disabled"'; 304163ac707SMichael Wilmes echo str_pad('',$indent); 305163ac707SMichael Wilmes 306163ac707SMichael Wilmes if($name == 'userpass' || $name == 'userpass2'){ 307163ac707SMichael Wilmes $fieldtype = 'password'; 308163ac707SMichael Wilmes $autocomp = 'autocomplete="off"'; 309163ac707SMichael Wilmes }elseif($name == 'usermail'){ 310163ac707SMichael Wilmes $fieldtype = 'email'; 311163ac707SMichael Wilmes $autocomp = ''; 312163ac707SMichael Wilmes }else{ 313163ac707SMichael Wilmes $fieldtype = 'text'; 314163ac707SMichael Wilmes $autocomp = ''; 315163ac707SMichael Wilmes } 316163ac707SMichael Wilmes $value = hsc($value); 317163ac707SMichael Wilmes 318163ac707SMichael Wilmes echo "<tr $class>"; 319163ac707SMichael Wilmes echo "<td><label for=\"$id\" >$label: </label></td>"; 320163ac707SMichael Wilmes echo "<td>"; 321163ac707SMichael Wilmes if($cando){ 322163ac707SMichael Wilmes echo "<input type=\"$fieldtype\" id=\"$id\" name=\"$name\" value=\"$value\" class=\"edit\" $autocomp />"; 323163ac707SMichael Wilmes }else{ 324163ac707SMichael Wilmes echo "<input type=\"hidden\" name=\"$name\" value=\"$value\" />"; 325163ac707SMichael Wilmes echo "<input type=\"$fieldtype\" id=\"$id\" name=\"$name\" value=\"$value\" class=\"edit disabled\" disabled=\"disabled\" />"; 326163ac707SMichael Wilmes } 327163ac707SMichael Wilmes echo "</td>"; 328163ac707SMichael Wilmes echo "</tr>"; 329163ac707SMichael Wilmes } 330163ac707SMichael Wilmes 331163ac707SMichael Wilmes /** 332163ac707SMichael Wilmes * Returns htmlescaped filter value 333163ac707SMichael Wilmes * 334163ac707SMichael Wilmes * @param string $key name of search field 335163ac707SMichael Wilmes * @return string html escaped value 336163ac707SMichael Wilmes */ 337163ac707SMichael Wilmes protected function _htmlFilter($key) { 338163ac707SMichael Wilmes if (empty($this->_filter)) return ''; 339163ac707SMichael Wilmes return (isset($this->_filter[$key]) ? hsc($this->_filter[$key]) : ''); 340163ac707SMichael Wilmes } 341163ac707SMichael Wilmes 342163ac707SMichael Wilmes /** 343163ac707SMichael Wilmes * Print hidden inputs with the current filter values 344163ac707SMichael Wilmes * 345163ac707SMichael Wilmes * @param int $indent 346163ac707SMichael Wilmes */ 347163ac707SMichael Wilmes protected function _htmlFilterSettings($indent=0) { 348163ac707SMichael Wilmes 349163ac707SMichael Wilmes ptln("<input type=\"hidden\" name=\"start\" value=\"".$this->_start."\" />",$indent); 350163ac707SMichael Wilmes 351163ac707SMichael Wilmes foreach ($this->_filter as $key => $filter) { 352163ac707SMichael Wilmes ptln("<input type=\"hidden\" name=\"filter[".$key."]\" value=\"".hsc($filter)."\" />",$indent); 353163ac707SMichael Wilmes } 354163ac707SMichael Wilmes } 355163ac707SMichael Wilmes 356163ac707SMichael Wilmes /** 357163ac707SMichael Wilmes * Reset user (a user has been selected to remove two factor authentication) 358163ac707SMichael Wilmes * 359163ac707SMichael Wilmes * @param string $param id of the user 360163ac707SMichael Wilmes * @return bool whether succesful 361163ac707SMichael Wilmes */ 362163ac707SMichael Wilmes protected function _resetUser() { 363163ac707SMichael Wilmes global $INPUT; 364163ac707SMichael Wilmes if (!checkSecurityToken()) return false; 365163ac707SMichael Wilmes 366163ac707SMichael Wilmes $selected = $INPUT->arr('delete'); 367163ac707SMichael Wilmes if (empty($selected)) return false; 368163ac707SMichael Wilmes $selected = array_keys($selected); 369163ac707SMichael Wilmes 370163ac707SMichael Wilmes if(in_array($_SERVER['REMOTE_USER'], $selected)) { 371163ac707SMichael Wilmes msg($this->lang['reset_not_self'], -1); 372163ac707SMichael Wilmes return false; 373163ac707SMichael Wilmes } 374163ac707SMichael Wilmes 375163ac707SMichael Wilmes $count = 0; 376163ac707SMichael Wilmes foreach($selected as $user) { 377163ac707SMichael Wilmes // All users here have a attribute namespace file. Purge them. 378185a84e4SMichael Wilmes $purged = $this->attribute->purge('twofactor', $user); 379185a84e4SMichael Wilmes foreach($this->modules as $mod) { 380185a84e4SMichael Wilmes $purged |= $this->attribute->purge($mod->moduleName, $user); 381185a84e4SMichael Wilmes } 382185a84e4SMichael Wilmes $count += $purged ? 1 : 0; 383163ac707SMichael Wilmes } 384163ac707SMichael Wilmes 385163ac707SMichael Wilmes if ($count == count($selected)) { 386163ac707SMichael Wilmes $text = str_replace('%d', $count, $this->lang['reset_ok']); 387163ac707SMichael Wilmes msg("$text.", 1); 388163ac707SMichael Wilmes } else { 389163ac707SMichael Wilmes $part1 = str_replace('%d', $count, $this->lang['reset_ok']); 390163ac707SMichael Wilmes $part2 = str_replace('%d', (count($selected)-$count), $this->lang['reset_fail']); 391163ac707SMichael Wilmes msg("$part1, $part2",-1); 392163ac707SMichael Wilmes } 393163ac707SMichael Wilmes 394163ac707SMichael Wilmes // Now refresh the user list. 395163ac707SMichael Wilmes $this->_getUsers(); 396163ac707SMichael Wilmes 397163ac707SMichael Wilmes return true; 398163ac707SMichael Wilmes } 399163ac707SMichael Wilmes 400163ac707SMichael Wilmes protected function _retrieveFilteredUsers($filter = array()) { 401163ac707SMichael Wilmes $users = array(); 402163ac707SMichael Wilmes foreach ($this->_user_list as $user) { 403163ac707SMichael Wilmes $userdata = $this->_auth->getUserData($user); 404163ac707SMichael Wilmes $include = true; 405163ac707SMichael Wilmes foreach ($filter as $key=>$value) { 406163ac707SMichael Wilmes $include &= strstr($userdata[$key], $value); 407163ac707SMichael Wilmes } 408163ac707SMichael Wilmes if ($include) { $users[$user] = $userdata; } 409163ac707SMichael Wilmes } 410163ac707SMichael Wilmes return $users; 411163ac707SMichael Wilmes } 412163ac707SMichael Wilmes 413163ac707SMichael Wilmes protected function _getUserCount($filter) { 414163ac707SMichael Wilmes return count($this->_retrieveFilteredUsers($filter)); 415163ac707SMichael Wilmes } 416163ac707SMichael Wilmes 417163ac707SMichael Wilmes protected function _retrieveUsers($start, $pagesize, $filter) { 418163ac707SMichael Wilmes $users = $this->_retrieveFilteredUsers($filter); 419163ac707SMichael Wilmes return $users; 420163ac707SMichael Wilmes } 421163ac707SMichael Wilmes 422163ac707SMichael Wilmes /** 423163ac707SMichael Wilmes * Retrieve & clean user data from the form 424163ac707SMichael Wilmes * 425163ac707SMichael Wilmes * @param bool $clean whether the cleanUser method of the authentication backend is applied 426163ac707SMichael Wilmes * @return array (user, password, full name, email, array(groups)) 427163ac707SMichael Wilmes */ 428163ac707SMichael Wilmes protected function _retrieveUser($clean=true) { 429163ac707SMichael Wilmes /** @var DokuWiki_Auth_Plugin $auth */ 430163ac707SMichael Wilmes global $auth; 431163ac707SMichael Wilmes global $INPUT; 432163ac707SMichael Wilmes 433163ac707SMichael Wilmes $user = array(); 434163ac707SMichael Wilmes $user[0] = ($clean) ? $auth->cleanUser($INPUT->str('userid')) : $INPUT->str('userid'); 435163ac707SMichael Wilmes $user[1] = $INPUT->str('userpass'); 436163ac707SMichael Wilmes $user[2] = $INPUT->str('username'); 437163ac707SMichael Wilmes $user[3] = $INPUT->str('usermail'); 438163ac707SMichael Wilmes $user[4] = explode(',',$INPUT->str('usergroups')); 439163ac707SMichael Wilmes $user[5] = $INPUT->str('userpass2'); // repeated password for confirmation 440163ac707SMichael Wilmes 441163ac707SMichael Wilmes $user[4] = array_map('trim',$user[4]); 442163ac707SMichael Wilmes if($clean) $user[4] = array_map(array($auth,'cleanGroup'),$user[4]); 443163ac707SMichael Wilmes $user[4] = array_filter($user[4]); 444163ac707SMichael Wilmes $user[4] = array_unique($user[4]); 445163ac707SMichael Wilmes if(!count($user[4])) $user[4] = null; 446163ac707SMichael Wilmes 447163ac707SMichael Wilmes return $user; 448163ac707SMichael Wilmes } 449163ac707SMichael Wilmes 450163ac707SMichael Wilmes /** 451163ac707SMichael Wilmes * Set the filter with the current search terms or clear the filter 452163ac707SMichael Wilmes * 453163ac707SMichael Wilmes * @param string $op 'new' or 'clear' 454163ac707SMichael Wilmes */ 455163ac707SMichael Wilmes protected function _setFilter($op) { 456163ac707SMichael Wilmes 457163ac707SMichael Wilmes $this->_filter = array(); 458163ac707SMichael Wilmes 459163ac707SMichael Wilmes if ($op == 'new') { 460163ac707SMichael Wilmes list($user,/* $pass */,$name,$mail,$grps) = $this->_retrieveUser(false); 461163ac707SMichael Wilmes 462163ac707SMichael Wilmes if (!empty($user)) $this->_filter['user'] = $user; 463163ac707SMichael Wilmes if (!empty($name)) $this->_filter['name'] = $name; 464163ac707SMichael Wilmes if (!empty($mail)) $this->_filter['mail'] = $mail; 465163ac707SMichael Wilmes } 466163ac707SMichael Wilmes } 467163ac707SMichael Wilmes 468163ac707SMichael Wilmes /** 469163ac707SMichael Wilmes * Get the current search terms 470163ac707SMichael Wilmes * 471163ac707SMichael Wilmes * @return array 472163ac707SMichael Wilmes */ 473163ac707SMichael Wilmes protected function _retrieveFilter() { 474163ac707SMichael Wilmes global $INPUT; 475163ac707SMichael Wilmes 476163ac707SMichael Wilmes $t_filter = $INPUT->arr('filter'); 477163ac707SMichael Wilmes 478163ac707SMichael Wilmes // messy, but this way we ensure we aren't getting any additional crap from malicious users 479163ac707SMichael Wilmes $filter = array(); 480163ac707SMichael Wilmes 481163ac707SMichael Wilmes if (isset($t_filter['user'])) $filter['user'] = $t_filter['user']; 482163ac707SMichael Wilmes if (isset($t_filter['name'])) $filter['name'] = $t_filter['name']; 483163ac707SMichael Wilmes if (isset($t_filter['mail'])) $filter['mail'] = $t_filter['mail']; 484163ac707SMichael Wilmes 485163ac707SMichael Wilmes return $filter; 486163ac707SMichael Wilmes } 487163ac707SMichael Wilmes 488163ac707SMichael Wilmes /** 489163ac707SMichael Wilmes * Validate and improve the pagination values 490163ac707SMichael Wilmes */ 491163ac707SMichael Wilmes protected function _validatePagination() { 492163ac707SMichael Wilmes 493163ac707SMichael Wilmes if ($this->_start >= $this->_user_total) { 494163ac707SMichael Wilmes $this->_start = $this->_user_total - $this->_pagesize; 495163ac707SMichael Wilmes } 496163ac707SMichael Wilmes if ($this->_start < 0) $this->_start = 0; 497163ac707SMichael Wilmes 498163ac707SMichael Wilmes $this->_last = min($this->_user_total, $this->_start + $this->_pagesize); 499163ac707SMichael Wilmes } 500163ac707SMichael Wilmes 501163ac707SMichael Wilmes /** 502163ac707SMichael Wilmes * Return an array of strings to enable/disable pagination buttons 503163ac707SMichael Wilmes * 504163ac707SMichael Wilmes * @return array with enable/disable attributes 505163ac707SMichael Wilmes */ 506163ac707SMichael Wilmes protected function _pagination() { 507163ac707SMichael Wilmes 508163ac707SMichael Wilmes $disabled = 'disabled="disabled"'; 509163ac707SMichael Wilmes 510163ac707SMichael Wilmes $buttons = array(); 511163ac707SMichael Wilmes $buttons['start'] = $buttons['prev'] = ($this->_start == 0) ? $disabled : ''; 512163ac707SMichael Wilmes 513163ac707SMichael Wilmes if ($this->_user_total == -1) { 514163ac707SMichael Wilmes $buttons['last'] = $disabled; 515163ac707SMichael Wilmes $buttons['next'] = ''; 516163ac707SMichael Wilmes } else { 517163ac707SMichael Wilmes $buttons['last'] = $buttons['next'] = (($this->_start + $this->_pagesize) >= $this->_user_total) ? $disabled : ''; 518163ac707SMichael Wilmes } 519163ac707SMichael Wilmes 520163ac707SMichael Wilmes if ($this->_lastdisabled) { 521163ac707SMichael Wilmes $buttons['last'] = $disabled; 522163ac707SMichael Wilmes } 523163ac707SMichael Wilmes 524163ac707SMichael Wilmes return $buttons; 525163ac707SMichael Wilmes } 526163ac707SMichael Wilmes 527163ac707SMichael Wilmes 528163ac707SMichael Wilmes} 529