xref: /plugin/twofactor/admin.php (revision d0a31016dd6ef844c1c5cd5481e6dc6c2e3315df)
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>&#160;</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