xref: /plugin/twofactor/admin.php (revision 163ac707d28a7cab09d4545eca233c5a5a0f9969)
1*163ac707SMichael Wilmes<?php
2*163ac707SMichael Wilmes/*
3*163ac707SMichael Wilmes *  Twofactor Manager
4*163ac707SMichael Wilmes *
5*163ac707SMichael Wilmes *  Dokuwiki Admin Plugin
6*163ac707SMichael Wilmes *  Special thanks to the useradmin extension as a starting point for this class
7*163ac707SMichael Wilmes *
8*163ac707SMichael Wilmes *  @author  Mike Wilmes <mwilmes@avc.edu>
9*163ac707SMichael Wilmes */
10*163ac707SMichael Wilmes// must be run within Dokuwiki
11*163ac707SMichael Wilmesif(!defined('DOKU_INC')) die();
12*163ac707SMichael Wilmes
13*163ac707SMichael Wilmesif(!defined('DOKU_TWOFACTOR_PLUGIN_IMAGES')) define('DOKU_TWOFACTOR_PLUGIN_IMAGES',DOKU_BASE.'lib/plugins/twofactor/images/');
14*163ac707SMichael Wilmes
15*163ac707SMichael Wilmes/**
16*163ac707SMichael Wilmes * All DokuWiki plugins to extend the admin function
17*163ac707SMichael Wilmes * need to inherit from this class
18*163ac707SMichael Wilmes */
19*163ac707SMichael Wilmesclass admin_plugin_twofactor extends DokuWiki_Admin_Plugin {
20*163ac707SMichael Wilmes    protected $_auth = null;        // auth object
21*163ac707SMichael Wilmes    protected $_user_list = array();     // number of users with attributes
22*163ac707SMichael Wilmes    protected $_filter = array();   // user selection filter(s)
23*163ac707SMichael Wilmes    protected $_start = 0;          // index of first user to be displayed
24*163ac707SMichael Wilmes    protected $_last = 0;           // index of the last user to be displayed
25*163ac707SMichael Wilmes    protected $_pagesize = 20;      // number of users to list on one page
26*163ac707SMichael Wilmes    protected $_disabled = '';      // if disabled set to explanatory string
27*163ac707SMichael Wilmes    protected $_lastdisabled = false; // set to true if last user is unknown and last button is hence buggy
28*163ac707SMichael Wilmes
29*163ac707SMichael Wilmes    /**
30*163ac707SMichael Wilmes     * Constructor
31*163ac707SMichael Wilmes     */
32*163ac707SMichael Wilmes    public function __construct(){
33*163ac707SMichael Wilmes		global $auth;
34*163ac707SMichael Wilmes        if (!isset($auth)) {
35*163ac707SMichael Wilmes            $this->_disabled = $this->lang['noauth'];
36*163ac707SMichael Wilmes        } else if (!$auth->canDo('getUsers')) {
37*163ac707SMichael Wilmes            $this->_disabled = $this->lang['nosupport'];
38*163ac707SMichael Wilmes        } else {
39*163ac707SMichael Wilmes            // we're good to go
40*163ac707SMichael Wilmes            $this->_auth = & $auth;
41*163ac707SMichael Wilmes        }
42*163ac707SMichael Wilmes		$this->setupLocale();
43*163ac707SMichael Wilmes		$requireAttribute = ($this->getConf("gaenable") === 1 || $this->getConf("gasecret") != '') || ($this->getConf("otpenable") === 1 || $this->getConf("otpmethod") != 'email');
44*163ac707SMichael Wilmes		$this->attribute = $requireAttribute ? $this->loadHelper('attribute', 'Attribute plugin required!') : null;
45*163ac707SMichael Wilmes		$this->_getUsers();
46*163ac707SMichael Wilmes    }
47*163ac707SMichael Wilmes
48*163ac707SMichael Wilmes	protected function _getUsers() {
49*163ac707SMichael Wilmes		if (!is_null($this->attribute)) {
50*163ac707SMichael Wilmes			$attr = $this->attribute;
51*163ac707SMichael Wilmes			$this->_user_list = $this->attribute->enumerateUsers('twofactor');
52*163ac707SMichael Wilmes		}
53*163ac707SMichael Wilmes		else {
54*163ac707SMichael Wilmes			msg($this->lang['no_purpose'], -1);
55*163ac707SMichael Wilmes		}
56*163ac707SMichael Wilmes	}
57*163ac707SMichael Wilmes
58*163ac707SMichael Wilmes    /**
59*163ac707SMichael Wilmes     * Return prompt for admin menu
60*163ac707SMichael Wilmes     *
61*163ac707SMichael Wilmes     * @param string $language
62*163ac707SMichael Wilmes     * @return string
63*163ac707SMichael Wilmes     */
64*163ac707SMichael Wilmes    public function getMenuText($language) {
65*163ac707SMichael Wilmes		global $INFO;
66*163ac707SMichael Wilmes        if (!$INFO['isadmin'])
67*163ac707SMichael Wilmes          return parent::getMenuText($language);
68*163ac707SMichael Wilmes
69*163ac707SMichael Wilmes        return $this->getLang('menu').' '.$this->_disabled;
70*163ac707SMichael Wilmes    }
71*163ac707SMichael Wilmes
72*163ac707SMichael Wilmes    /**
73*163ac707SMichael Wilmes     * return sort order for position in admin menu
74*163ac707SMichael Wilmes     *
75*163ac707SMichael Wilmes     * @return int
76*163ac707SMichael Wilmes     */
77*163ac707SMichael Wilmes    public function getMenuSort() {
78*163ac707SMichael Wilmes        return 2;
79*163ac707SMichael Wilmes    }
80*163ac707SMichael Wilmes
81*163ac707SMichael Wilmes    /**
82*163ac707SMichael Wilmes     * @return int current start value for pageination
83*163ac707SMichael Wilmes     */
84*163ac707SMichael Wilmes    public function getStart() {
85*163ac707SMichael Wilmes        return $this->_start;
86*163ac707SMichael Wilmes    }
87*163ac707SMichael Wilmes
88*163ac707SMichael Wilmes    /**
89*163ac707SMichael Wilmes     * @return int number of users per page
90*163ac707SMichael Wilmes     */
91*163ac707SMichael Wilmes    public function getPagesize() {
92*163ac707SMichael Wilmes        return $this->_pagesize;
93*163ac707SMichael Wilmes    }
94*163ac707SMichael Wilmes
95*163ac707SMichael Wilmes    /**
96*163ac707SMichael Wilmes     * @param boolean $lastdisabled
97*163ac707SMichael Wilmes     */
98*163ac707SMichael Wilmes    public function setLastdisabled($lastdisabled) {
99*163ac707SMichael Wilmes        $this->_lastdisabled = $lastdisabled;
100*163ac707SMichael Wilmes    }
101*163ac707SMichael Wilmes
102*163ac707SMichael Wilmes    /**
103*163ac707SMichael Wilmes     * Handle user request
104*163ac707SMichael Wilmes     *
105*163ac707SMichael Wilmes     * @return bool
106*163ac707SMichael Wilmes     */
107*163ac707SMichael Wilmes    public function handle() {
108*163ac707SMichael Wilmes        global $INPUT, $INFO;
109*163ac707SMichael Wilmes        if (!$INFO['isadmin']) return false;
110*163ac707SMichael Wilmes
111*163ac707SMichael Wilmes        // extract the command and any specific parameters
112*163ac707SMichael Wilmes        // submit button name is of the form - fn[cmd][param(s)]
113*163ac707SMichael Wilmes        $fn   = $INPUT->param('fn');
114*163ac707SMichael Wilmes
115*163ac707SMichael Wilmes        if (is_array($fn)) {
116*163ac707SMichael Wilmes            $cmd = key($fn);
117*163ac707SMichael Wilmes            $param = is_array($fn[$cmd]) ? key($fn[$cmd]) : null;
118*163ac707SMichael Wilmes        } else {
119*163ac707SMichael Wilmes            $cmd = $fn;
120*163ac707SMichael Wilmes            $param = null;
121*163ac707SMichael Wilmes        }
122*163ac707SMichael Wilmes
123*163ac707SMichael Wilmes        if ($cmd != "search") {
124*163ac707SMichael Wilmes            $this->_start = $INPUT->int('start', 0);
125*163ac707SMichael Wilmes            $this->_filter = $this->_retrieveFilter();
126*163ac707SMichael Wilmes        }
127*163ac707SMichael Wilmes
128*163ac707SMichael Wilmes        switch($cmd){
129*163ac707SMichael Wilmes            case "reset"  : $this->_resetUser(); break;
130*163ac707SMichael Wilmes            case "search" : $this->_setFilter($param);
131*163ac707SMichael Wilmes                            $this->_start = 0;
132*163ac707SMichael Wilmes                            break;
133*163ac707SMichael Wilmes        }
134*163ac707SMichael Wilmes
135*163ac707SMichael Wilmes        $this->_user_total = count($this->_user_list) > 0 ? $this->_getUserCount($this->_filter) : -1;
136*163ac707SMichael Wilmes
137*163ac707SMichael Wilmes        // page handling
138*163ac707SMichael Wilmes        switch($cmd){
139*163ac707SMichael Wilmes            case 'start' : $this->_start = 0; break;
140*163ac707SMichael Wilmes            case 'prev'  : $this->_start -= $this->_pagesize; break;
141*163ac707SMichael Wilmes            case 'next'  : $this->_start += $this->_pagesize; break;
142*163ac707SMichael Wilmes            case 'last'  : $this->_start = $this->_user_total; break;
143*163ac707SMichael Wilmes        }
144*163ac707SMichael Wilmes        $this->_validatePagination();
145*163ac707SMichael Wilmes        return true;
146*163ac707SMichael Wilmes    }
147*163ac707SMichael Wilmes
148*163ac707SMichael Wilmes    /**
149*163ac707SMichael Wilmes     * Output appropriate html
150*163ac707SMichael Wilmes     *
151*163ac707SMichael Wilmes     * @return bool
152*163ac707SMichael Wilmes     */
153*163ac707SMichael Wilmes    public function html() {
154*163ac707SMichael Wilmes        global $ID, $INFO;
155*163ac707SMichael Wilmes
156*163ac707SMichael Wilmes        if(!$INFO['isadmin']) {
157*163ac707SMichael Wilmes            print $this->lang['badauth'];
158*163ac707SMichael Wilmes            return false;
159*163ac707SMichael Wilmes        }
160*163ac707SMichael Wilmes
161*163ac707SMichael Wilmes        $user_list = $this->_retrieveUsers($this->_start, $this->_pagesize, $this->_filter);
162*163ac707SMichael Wilmes
163*163ac707SMichael Wilmes        $page_buttons = $this->_pagination();
164*163ac707SMichael Wilmes
165*163ac707SMichael Wilmes        print $this->locale_xhtml('intro');
166*163ac707SMichael Wilmes        print $this->locale_xhtml('list');
167*163ac707SMichael Wilmes
168*163ac707SMichael Wilmes        ptln("<div id=\"user__manager\">");
169*163ac707SMichael Wilmes        ptln("<div class=\"level2\">");
170*163ac707SMichael Wilmes
171*163ac707SMichael Wilmes        if (count($this->_user_list) > 0) {
172*163ac707SMichael Wilmes            ptln("<p>".sprintf($this->lang['summary'],$this->_start+1,$this->_last,$this->_getUserCount($this->_filter),count($this->_user_list))."</p>");
173*163ac707SMichael Wilmes        } else {
174*163ac707SMichael Wilmes            if(count($this->_user_list) < 0) {
175*163ac707SMichael Wilmes                $allUserTotal = 0;
176*163ac707SMichael Wilmes            } else {
177*163ac707SMichael Wilmes                $allUserTotal = count($this->_user_list);
178*163ac707SMichael Wilmes            }
179*163ac707SMichael Wilmes            ptln("<p>".sprintf($this->lang['nonefound'], $allUserTotal)."</p>");
180*163ac707SMichael Wilmes        }
181*163ac707SMichael Wilmes        ptln("<form action=\"".wl($ID)."\" method=\"post\">");
182*163ac707SMichael Wilmes        formSecurityToken();
183*163ac707SMichael Wilmes        ptln("  <div class=\"table\">");
184*163ac707SMichael Wilmes        ptln("  <table class=\"inline\">");
185*163ac707SMichael Wilmes        ptln("    <thead>");
186*163ac707SMichael Wilmes        ptln("      <tr>");
187*163ac707SMichael Wilmes        ptln("        <th>&#160;</th><th>".$this->lang["user_id"]."</th><th>".$this->lang["user_name"]."</th><th>".$this->lang["user_mail"]."</th>");
188*163ac707SMichael Wilmes        ptln("      </tr>");
189*163ac707SMichael Wilmes
190*163ac707SMichael Wilmes        ptln("      <tr>");
191*163ac707SMichael 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>");
192*163ac707SMichael Wilmes        ptln("        <td><input type=\"text\" name=\"userid\" class=\"edit\" value=\"".$this->_htmlFilter('user')."\" /></td>");
193*163ac707SMichael Wilmes        ptln("        <td><input type=\"text\" name=\"username\" class=\"edit\" value=\"".$this->_htmlFilter('name')."\" /></td>");
194*163ac707SMichael Wilmes        ptln("        <td><input type=\"text\" name=\"usermail\" class=\"edit\" value=\"".$this->_htmlFilter('mail')."\" /></td>");
195*163ac707SMichael Wilmes        ptln("      </tr>");
196*163ac707SMichael Wilmes        ptln("    </thead>");
197*163ac707SMichael Wilmes
198*163ac707SMichael Wilmes        if ($this->_user_total) {
199*163ac707SMichael Wilmes            ptln("    <tbody>");
200*163ac707SMichael Wilmes            foreach ($user_list as $user => $userinfo) {
201*163ac707SMichael Wilmes                extract($userinfo);
202*163ac707SMichael Wilmes                /**
203*163ac707SMichael Wilmes                 * @var string $name
204*163ac707SMichael Wilmes                 * @var string $pass
205*163ac707SMichael Wilmes                 * @var string $mail
206*163ac707SMichael Wilmes                 * @var array  $grps
207*163ac707SMichael Wilmes                 */
208*163ac707SMichael Wilmes                $groups = join(', ',$grps);
209*163ac707SMichael Wilmes                ptln("    <tr class=\"user_info\">");
210*163ac707SMichael Wilmes                ptln("      <td class=\"centeralign\"><input type=\"checkbox\" name=\"delete[".hsc($user)."]\" ".$delete_disable." /></td>");
211*163ac707SMichael Wilmes                if ($editable) {
212*163ac707SMichael Wilmes                    ptln("    <td><a href=\"".wl($ID,array('fn[edit]['.$user.']' => 1,
213*163ac707SMichael Wilmes                                                           'do' => 'admin',
214*163ac707SMichael Wilmes                                                           'page' => 'usermanager',
215*163ac707SMichael Wilmes                                                           'sectok' => getSecurityToken())).
216*163ac707SMichael Wilmes                         "\" title=\"".$this->lang['edit_prompt']."\">".hsc($user)."</a></td>");
217*163ac707SMichael Wilmes                } else {
218*163ac707SMichael Wilmes                    ptln("    <td>".hsc($user)."</td>");
219*163ac707SMichael Wilmes                }
220*163ac707SMichael Wilmes                ptln("      <td>".hsc($name)."</td><td>".hsc($mail)."</td>");
221*163ac707SMichael Wilmes                ptln("    </tr>");
222*163ac707SMichael Wilmes            }
223*163ac707SMichael Wilmes            ptln("    </tbody>");
224*163ac707SMichael Wilmes        }
225*163ac707SMichael Wilmes
226*163ac707SMichael Wilmes        ptln("    <tbody>");
227*163ac707SMichael Wilmes        ptln("      <tr><td colspan=\"5\" class=\"centeralign\">");
228*163ac707SMichael Wilmes        ptln("        <span class=\"medialeft\">");
229*163ac707SMichael Wilmes        ptln("          <button type=\"submit\" name=\"fn[reset]\" id=\"usrmgr__reset\" >".$this->lang['reset_selected']."</button>");
230*163ac707SMichael Wilmes        ptln("        ");
231*163ac707SMichael Wilmes        if (!empty($this->_filter)) {
232*163ac707SMichael Wilmes            ptln("    <button type=\"submit\" name=\"fn[search][clear]\">".$this->lang['clear']."</button>");
233*163ac707SMichael Wilmes        }
234*163ac707SMichael Wilmes        ptln("        <input type=\"hidden\" name=\"do\"    value=\"admin\" />");
235*163ac707SMichael Wilmes        ptln("        <input type=\"hidden\" name=\"page\"  value=\"twofactor\" />");
236*163ac707SMichael Wilmes
237*163ac707SMichael Wilmes        $this->_htmlFilterSettings(2);
238*163ac707SMichael Wilmes        ptln("        </span>");
239*163ac707SMichael Wilmes        ptln("        <span class=\"mediaright\">");
240*163ac707SMichael Wilmes        ptln("          <button type=\"submit\" name=\"fn[start]\" ".$page_buttons['start'].">".$this->lang['start']."</button>");
241*163ac707SMichael Wilmes        ptln("          <button type=\"submit\" name=\"fn[prev]\" ".$page_buttons['prev'].">".$this->lang['prev']."</button>");
242*163ac707SMichael Wilmes        ptln("          <button type=\"submit\" name=\"fn[next]\" ".$page_buttons['next'].">".$this->lang['next']."</button>");
243*163ac707SMichael Wilmes        ptln("          <button type=\"submit\" name=\"fn[last]\" ".$page_buttons['last'].">".$this->lang['last']."</button>");
244*163ac707SMichael Wilmes        ptln("        </span>");
245*163ac707SMichael Wilmes
246*163ac707SMichael Wilmes        ptln("      </td></tr>");
247*163ac707SMichael Wilmes        ptln("    </tbody>");
248*163ac707SMichael Wilmes        ptln("  </table>");
249*163ac707SMichael Wilmes        ptln("  </div>");
250*163ac707SMichael Wilmes
251*163ac707SMichael Wilmes        ptln("</form>");
252*163ac707SMichael Wilmes        ptln("</div>");
253*163ac707SMichael Wilmes
254*163ac707SMichael Wilmes        ptln("</div>");
255*163ac707SMichael Wilmes        return true;
256*163ac707SMichael Wilmes    }
257*163ac707SMichael Wilmes
258*163ac707SMichael Wilmes
259*163ac707SMichael Wilmes    /**
260*163ac707SMichael Wilmes     * Prints a inputfield
261*163ac707SMichael Wilmes     *
262*163ac707SMichael Wilmes     * @param string $id
263*163ac707SMichael Wilmes     * @param string $name
264*163ac707SMichael Wilmes     * @param string $label
265*163ac707SMichael Wilmes     * @param string $value
266*163ac707SMichael Wilmes     * @param bool   $cando whether auth backend is capable to do this action
267*163ac707SMichael Wilmes     * @param int $indent
268*163ac707SMichael Wilmes     */
269*163ac707SMichael Wilmes    protected function _htmlInputField($id, $name, $label, $value, $cando, $indent=0) {
270*163ac707SMichael Wilmes        $class = $cando ? '' : ' class="disabled"';
271*163ac707SMichael Wilmes        echo str_pad('',$indent);
272*163ac707SMichael Wilmes
273*163ac707SMichael Wilmes        if($name == 'userpass' || $name == 'userpass2'){
274*163ac707SMichael Wilmes            $fieldtype = 'password';
275*163ac707SMichael Wilmes            $autocomp  = 'autocomplete="off"';
276*163ac707SMichael Wilmes        }elseif($name == 'usermail'){
277*163ac707SMichael Wilmes            $fieldtype = 'email';
278*163ac707SMichael Wilmes            $autocomp  = '';
279*163ac707SMichael Wilmes        }else{
280*163ac707SMichael Wilmes            $fieldtype = 'text';
281*163ac707SMichael Wilmes            $autocomp  = '';
282*163ac707SMichael Wilmes        }
283*163ac707SMichael Wilmes        $value = hsc($value);
284*163ac707SMichael Wilmes
285*163ac707SMichael Wilmes        echo "<tr $class>";
286*163ac707SMichael Wilmes        echo "<td><label for=\"$id\" >$label: </label></td>";
287*163ac707SMichael Wilmes        echo "<td>";
288*163ac707SMichael Wilmes        if($cando){
289*163ac707SMichael Wilmes            echo "<input type=\"$fieldtype\" id=\"$id\" name=\"$name\" value=\"$value\" class=\"edit\" $autocomp />";
290*163ac707SMichael Wilmes        }else{
291*163ac707SMichael Wilmes            echo "<input type=\"hidden\" name=\"$name\" value=\"$value\" />";
292*163ac707SMichael Wilmes            echo "<input type=\"$fieldtype\" id=\"$id\" name=\"$name\" value=\"$value\" class=\"edit disabled\" disabled=\"disabled\" />";
293*163ac707SMichael Wilmes        }
294*163ac707SMichael Wilmes        echo "</td>";
295*163ac707SMichael Wilmes        echo "</tr>";
296*163ac707SMichael Wilmes    }
297*163ac707SMichael Wilmes
298*163ac707SMichael Wilmes    /**
299*163ac707SMichael Wilmes     * Returns htmlescaped filter value
300*163ac707SMichael Wilmes     *
301*163ac707SMichael Wilmes     * @param string $key name of search field
302*163ac707SMichael Wilmes     * @return string html escaped value
303*163ac707SMichael Wilmes     */
304*163ac707SMichael Wilmes    protected function _htmlFilter($key) {
305*163ac707SMichael Wilmes        if (empty($this->_filter)) return '';
306*163ac707SMichael Wilmes        return (isset($this->_filter[$key]) ? hsc($this->_filter[$key]) : '');
307*163ac707SMichael Wilmes    }
308*163ac707SMichael Wilmes
309*163ac707SMichael Wilmes    /**
310*163ac707SMichael Wilmes     * Print hidden inputs with the current filter values
311*163ac707SMichael Wilmes     *
312*163ac707SMichael Wilmes     * @param int $indent
313*163ac707SMichael Wilmes     */
314*163ac707SMichael Wilmes    protected function _htmlFilterSettings($indent=0) {
315*163ac707SMichael Wilmes
316*163ac707SMichael Wilmes        ptln("<input type=\"hidden\" name=\"start\" value=\"".$this->_start."\" />",$indent);
317*163ac707SMichael Wilmes
318*163ac707SMichael Wilmes        foreach ($this->_filter as $key => $filter) {
319*163ac707SMichael Wilmes            ptln("<input type=\"hidden\" name=\"filter[".$key."]\" value=\"".hsc($filter)."\" />",$indent);
320*163ac707SMichael Wilmes        }
321*163ac707SMichael Wilmes    }
322*163ac707SMichael Wilmes
323*163ac707SMichael Wilmes    /**
324*163ac707SMichael Wilmes     * Reset user (a user has been selected to remove two factor authentication)
325*163ac707SMichael Wilmes     *
326*163ac707SMichael Wilmes     * @param string $param id of the user
327*163ac707SMichael Wilmes     * @return bool whether succesful
328*163ac707SMichael Wilmes     */
329*163ac707SMichael Wilmes    protected function _resetUser() {
330*163ac707SMichael Wilmes        global $INPUT;
331*163ac707SMichael Wilmes		if (!checkSecurityToken()) return false;
332*163ac707SMichael Wilmes
333*163ac707SMichael Wilmes        $selected = $INPUT->arr('delete');
334*163ac707SMichael Wilmes        if (empty($selected)) return false;
335*163ac707SMichael Wilmes        $selected = array_keys($selected);
336*163ac707SMichael Wilmes
337*163ac707SMichael Wilmes        if(in_array($_SERVER['REMOTE_USER'], $selected)) {
338*163ac707SMichael Wilmes            msg($this->lang['reset_not_self'], -1);
339*163ac707SMichael Wilmes            return false;
340*163ac707SMichael Wilmes        }
341*163ac707SMichael Wilmes
342*163ac707SMichael Wilmes		$count = 0;
343*163ac707SMichael Wilmes		foreach($selected as $user) {
344*163ac707SMichael Wilmes			// All users here have a attribute namespace file. Purge them.
345*163ac707SMichael Wilmes			$count += $this->attribute->purge('twofactor', $user)? 1 : 0;
346*163ac707SMichael Wilmes		}
347*163ac707SMichael Wilmes
348*163ac707SMichael Wilmes        if ($count == count($selected)) {
349*163ac707SMichael Wilmes            $text = str_replace('%d', $count, $this->lang['reset_ok']);
350*163ac707SMichael Wilmes            msg("$text.", 1);
351*163ac707SMichael Wilmes        } else {
352*163ac707SMichael Wilmes            $part1 = str_replace('%d', $count, $this->lang['reset_ok']);
353*163ac707SMichael Wilmes            $part2 = str_replace('%d', (count($selected)-$count), $this->lang['reset_fail']);
354*163ac707SMichael Wilmes            msg("$part1, $part2",-1);
355*163ac707SMichael Wilmes        }
356*163ac707SMichael Wilmes
357*163ac707SMichael Wilmes		// Now refresh the user list.
358*163ac707SMichael Wilmes		$this->_getUsers();
359*163ac707SMichael Wilmes
360*163ac707SMichael Wilmes        return true;
361*163ac707SMichael Wilmes    }
362*163ac707SMichael Wilmes
363*163ac707SMichael Wilmes	protected function _retrieveFilteredUsers($filter = array()) {
364*163ac707SMichael Wilmes		$users = array();
365*163ac707SMichael Wilmes		foreach ($this->_user_list as $user) {
366*163ac707SMichael Wilmes			$userdata = $this->_auth->getUserData($user);
367*163ac707SMichael Wilmes			$include = true;
368*163ac707SMichael Wilmes			foreach ($filter as $key=>$value) {
369*163ac707SMichael Wilmes				$include &= strstr($userdata[$key], $value);
370*163ac707SMichael Wilmes			}
371*163ac707SMichael Wilmes			if ($include) { $users[$user] = $userdata; }
372*163ac707SMichael Wilmes		}
373*163ac707SMichael Wilmes		return $users;
374*163ac707SMichael Wilmes	}
375*163ac707SMichael Wilmes
376*163ac707SMichael Wilmes	protected function _getUserCount($filter) {
377*163ac707SMichael Wilmes		return count($this->_retrieveFilteredUsers($filter));
378*163ac707SMichael Wilmes	}
379*163ac707SMichael Wilmes
380*163ac707SMichael Wilmes	protected function _retrieveUsers($start, $pagesize, $filter) {
381*163ac707SMichael Wilmes		$users = $this->_retrieveFilteredUsers($filter);
382*163ac707SMichael Wilmes		return $users;
383*163ac707SMichael Wilmes	}
384*163ac707SMichael Wilmes
385*163ac707SMichael Wilmes    /**
386*163ac707SMichael Wilmes     * Retrieve & clean user data from the form
387*163ac707SMichael Wilmes     *
388*163ac707SMichael Wilmes     * @param bool $clean whether the cleanUser method of the authentication backend is applied
389*163ac707SMichael Wilmes     * @return array (user, password, full name, email, array(groups))
390*163ac707SMichael Wilmes     */
391*163ac707SMichael Wilmes    protected function _retrieveUser($clean=true) {
392*163ac707SMichael Wilmes        /** @var DokuWiki_Auth_Plugin $auth */
393*163ac707SMichael Wilmes        global $auth;
394*163ac707SMichael Wilmes        global $INPUT;
395*163ac707SMichael Wilmes
396*163ac707SMichael Wilmes        $user = array();
397*163ac707SMichael Wilmes        $user[0] = ($clean) ? $auth->cleanUser($INPUT->str('userid')) : $INPUT->str('userid');
398*163ac707SMichael Wilmes        $user[1] = $INPUT->str('userpass');
399*163ac707SMichael Wilmes        $user[2] = $INPUT->str('username');
400*163ac707SMichael Wilmes        $user[3] = $INPUT->str('usermail');
401*163ac707SMichael Wilmes        $user[4] = explode(',',$INPUT->str('usergroups'));
402*163ac707SMichael Wilmes        $user[5] = $INPUT->str('userpass2');                // repeated password for confirmation
403*163ac707SMichael Wilmes
404*163ac707SMichael Wilmes        $user[4] = array_map('trim',$user[4]);
405*163ac707SMichael Wilmes        if($clean) $user[4] = array_map(array($auth,'cleanGroup'),$user[4]);
406*163ac707SMichael Wilmes        $user[4] = array_filter($user[4]);
407*163ac707SMichael Wilmes        $user[4] = array_unique($user[4]);
408*163ac707SMichael Wilmes        if(!count($user[4])) $user[4] = null;
409*163ac707SMichael Wilmes
410*163ac707SMichael Wilmes        return $user;
411*163ac707SMichael Wilmes    }
412*163ac707SMichael Wilmes
413*163ac707SMichael Wilmes    /**
414*163ac707SMichael Wilmes     * Set the filter with the current search terms or clear the filter
415*163ac707SMichael Wilmes     *
416*163ac707SMichael Wilmes     * @param string $op 'new' or 'clear'
417*163ac707SMichael Wilmes     */
418*163ac707SMichael Wilmes    protected function _setFilter($op) {
419*163ac707SMichael Wilmes
420*163ac707SMichael Wilmes        $this->_filter = array();
421*163ac707SMichael Wilmes
422*163ac707SMichael Wilmes        if ($op == 'new') {
423*163ac707SMichael Wilmes            list($user,/* $pass */,$name,$mail,$grps) = $this->_retrieveUser(false);
424*163ac707SMichael Wilmes
425*163ac707SMichael Wilmes            if (!empty($user)) $this->_filter['user'] = $user;
426*163ac707SMichael Wilmes            if (!empty($name)) $this->_filter['name'] = $name;
427*163ac707SMichael Wilmes            if (!empty($mail)) $this->_filter['mail'] = $mail;
428*163ac707SMichael Wilmes        }
429*163ac707SMichael Wilmes    }
430*163ac707SMichael Wilmes
431*163ac707SMichael Wilmes    /**
432*163ac707SMichael Wilmes     * Get the current search terms
433*163ac707SMichael Wilmes     *
434*163ac707SMichael Wilmes     * @return array
435*163ac707SMichael Wilmes     */
436*163ac707SMichael Wilmes    protected function _retrieveFilter() {
437*163ac707SMichael Wilmes        global $INPUT;
438*163ac707SMichael Wilmes
439*163ac707SMichael Wilmes        $t_filter = $INPUT->arr('filter');
440*163ac707SMichael Wilmes
441*163ac707SMichael Wilmes        // messy, but this way we ensure we aren't getting any additional crap from malicious users
442*163ac707SMichael Wilmes        $filter = array();
443*163ac707SMichael Wilmes
444*163ac707SMichael Wilmes        if (isset($t_filter['user'])) $filter['user'] = $t_filter['user'];
445*163ac707SMichael Wilmes        if (isset($t_filter['name'])) $filter['name'] = $t_filter['name'];
446*163ac707SMichael Wilmes        if (isset($t_filter['mail'])) $filter['mail'] = $t_filter['mail'];
447*163ac707SMichael Wilmes
448*163ac707SMichael Wilmes        return $filter;
449*163ac707SMichael Wilmes    }
450*163ac707SMichael Wilmes
451*163ac707SMichael Wilmes    /**
452*163ac707SMichael Wilmes     * Validate and improve the pagination values
453*163ac707SMichael Wilmes     */
454*163ac707SMichael Wilmes    protected function _validatePagination() {
455*163ac707SMichael Wilmes
456*163ac707SMichael Wilmes        if ($this->_start >= $this->_user_total) {
457*163ac707SMichael Wilmes            $this->_start = $this->_user_total - $this->_pagesize;
458*163ac707SMichael Wilmes        }
459*163ac707SMichael Wilmes        if ($this->_start < 0) $this->_start = 0;
460*163ac707SMichael Wilmes
461*163ac707SMichael Wilmes        $this->_last = min($this->_user_total, $this->_start + $this->_pagesize);
462*163ac707SMichael Wilmes    }
463*163ac707SMichael Wilmes
464*163ac707SMichael Wilmes    /**
465*163ac707SMichael Wilmes     * Return an array of strings to enable/disable pagination buttons
466*163ac707SMichael Wilmes     *
467*163ac707SMichael Wilmes     * @return array with enable/disable attributes
468*163ac707SMichael Wilmes     */
469*163ac707SMichael Wilmes    protected function _pagination() {
470*163ac707SMichael Wilmes
471*163ac707SMichael Wilmes        $disabled = 'disabled="disabled"';
472*163ac707SMichael Wilmes
473*163ac707SMichael Wilmes        $buttons = array();
474*163ac707SMichael Wilmes        $buttons['start'] = $buttons['prev'] = ($this->_start == 0) ? $disabled : '';
475*163ac707SMichael Wilmes
476*163ac707SMichael Wilmes        if ($this->_user_total == -1) {
477*163ac707SMichael Wilmes            $buttons['last'] = $disabled;
478*163ac707SMichael Wilmes            $buttons['next'] = '';
479*163ac707SMichael Wilmes        } else {
480*163ac707SMichael Wilmes            $buttons['last'] = $buttons['next'] = (($this->_start + $this->_pagesize) >= $this->_user_total) ? $disabled : '';
481*163ac707SMichael Wilmes        }
482*163ac707SMichael Wilmes
483*163ac707SMichael Wilmes        if ($this->_lastdisabled) {
484*163ac707SMichael Wilmes            $buttons['last'] = $disabled;
485*163ac707SMichael Wilmes        }
486*163ac707SMichael Wilmes
487*163ac707SMichael Wilmes        return $buttons;
488*163ac707SMichael Wilmes    }
489*163ac707SMichael Wilmes
490*163ac707SMichael Wilmes
491*163ac707SMichael Wilmes}
492