xref: /plugin/twofactor/admin.php (revision b71db9c87c646b691cfbd8e0f56ef3c10c5d4a53)
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;
34163ac707SMichael Wilmes        if (!isset($auth)) {
35163ac707SMichael Wilmes            $this->_disabled = $this->lang['noauth'];
36163ac707SMichael Wilmes        } else if (!$auth->canDo('getUsers')) {
37163ac707SMichael Wilmes            $this->_disabled = $this->lang['nosupport'];
38163ac707SMichael Wilmes        } else {
39163ac707SMichael Wilmes            // we're good to go
40163ac707SMichael Wilmes            $this->_auth = & $auth;
41163ac707SMichael Wilmes        }
42163ac707SMichael Wilmes		$this->setupLocale();
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',
63*b71db9c8SMichael 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;
134*b71db9c8SMichael Wilmes        if ($this->_disabled) {
135*b71db9c8SMichael Wilmes            // If disabled, don't process anything.
136*b71db9c8SMichael Wilmes            return true;
137*b71db9c8SMichael 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
189*b71db9c8SMichael Wilmes        if ($this->disabled !== '') {
190*b71db9c8SMichael Wilmes            msg($this->_disabled, -1);
191*b71db9c8SMichael Wilmes            return true;
192*b71db9c8SMichael Wilmes        }
193*b71db9c8SMichael 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>&#160;</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