xref: /plugin/twofactor/admin.php (revision bbe22a6a87dd9db724f864d111d35d715e39a4e1)
1<?php
2
3use dokuwiki\Form\Form;
4use dokuwiki\plugin\twofactor\Manager;
5
6/**
7 *  Twofactor Manager
8 *
9 *  Allows to reset a user's twofactor data
10 */
11class admin_plugin_twofactor extends DokuWiki_Admin_Plugin
12{
13    protected $userList = array();     // list of users with attributes
14    protected $filter = array();   // user selection filter(s)
15    protected $start = 0;          // index of first user to be displayed
16    protected $last = 0;           // index of the last user to be displayed
17    protected $pagesize = 20;      // number of users to list on one page
18    protected $disabled = '';      // if disabled set to explanatory string
19
20    /** @var helper_plugin_attribute */
21    protected $attribute;
22
23    protected $manager;
24
25    /**
26     * Constructor
27     */
28    public function __construct()
29    {
30        $this->manager = Manager::getInstance();
31        if (!$this->manager->isReady()) return;
32        $this->attribute = plugin_load('helper', 'attribute');
33
34        global $INPUT;
35
36        $this->filter = $INPUT->arr('filter');
37        $this->start = $INPUT->int('start');
38    }
39
40    /** @inheritdoc */
41    public function handle()
42    {
43        global $INPUT;
44
45        if ($INPUT->has('reset') && checkSecurityToken()) {
46            $userdel = $INPUT->extract('reset')->str('reset');
47            if ($userdel == $INPUT->server->str('REMOTE_USER')) {
48                msg($this->lang['reset_not_self'], -1);
49                return;
50            }
51            foreach ($this->manager->getAllProviders() as $providerID => $provider) {
52                $this->attribute->purge($providerID, $userdel);
53            }
54            $this->attribute->purge('twofactor', $userdel);
55        }
56    }
57
58    /**
59     * Output appropriate html
60     *
61     * @return bool
62     */
63    public function html()
64    {
65        $users = $this->getUserData($this->filter);
66        $usercount = count($users);
67        $users = $this->applyPagination($users, $this->start, $this->pagesize);
68
69        echo $this->locale_xhtml('admin');
70        if (!$this->manager->isReady()) {
71            return true;
72        }
73
74        $form = new Form(['method' => 'POST', 'class' => 'plugin_twofactor_admin']);
75        $form->setHiddenField('do', 'admin');
76        $form->setHiddenField('page', 'twofactor');
77        $form->setHiddenField('start', $this->start);
78
79        $form->addTagOpen('div')->addClass('table');
80        $form->addTagOpen('table')->addClass('inline');
81        $form = $this->addTableHead($form);
82
83        $form->addTagOpen('tbody');
84        foreach ($users as $user => $userinfo) {
85            $form = $this->addTableUser($form, $user, $userinfo);
86        }
87        $form->addTagClose('tbody');
88
89        $form->addTagOpen('tfooter');
90        $form = $this->addTablePagination($form, $usercount, $this->start, $this->pagesize);
91        $form->addTagClose('tfooter');
92
93        $form->addTagClose('table');
94        $form->addTagClose('div');
95
96        echo $form->toHTML();
97
98        return true;
99    }
100
101    /**
102     * Add the table headers to the table in the given form
103     * @param Form $form
104     * @return Form
105     */
106    protected function addTableHead(Form $form)
107    {
108        $form->addTagOpen('thead');
109
110        // header
111        $form->addTagOpen('tr');
112        $form->addTagOpen('th');
113        $form->addHTML($this->getLang('user_id'));
114        $form->addTagClose('th');
115        $form->addTagOpen('th');
116        $form->addHTML($this->getLang('user_name'));
117        $form->addTagClose('th');
118        $form->addTagOpen('th');
119        $form->addHTML($this->getLang('user_mail'));
120        $form->addTagClose('th');
121        $form->addTagOpen('th');
122        $form->addHTML($this->getLang('action'));
123        $form->addTagClose('th');
124        $form->addTagClose('tr');
125
126        // filter
127        $form->addTagOpen('tr');
128        $form->addTagOpen('th');
129        $form->addTextInput('filter[user]');
130        $form->addTagClose('th');
131        $form->addTagOpen('th');
132        $form->addTextInput('filter[name]');
133        $form->addTagClose('th');
134        $form->addTagOpen('th');
135        $form->addTextInput('filter[mail]');
136        $form->addTagClose('th');
137        $form->addTagOpen('th');
138        $form->addButton('', $this->getLang('search'))->attr('type', 'submit');
139        $form->addTagClose('th');
140        $form->addTagClose('tr');
141
142        $form->addTagClose('thead');
143        return $form;
144    }
145
146    /**
147     * Add
148     *
149     * @param Form $form
150     * @param $user
151     * @param $userinfo
152     * @return Form
153     */
154    protected function addTableUser(Form $form, $user, $userinfo)
155    {
156        $form->addTagOpen('tr');
157        $form->addTagOpen('td');
158        $form->addHTML(hsc($user));
159        $form->addTagClose('td');
160        $form->addTagOpen('td');
161        $form->addHTML(hsc($userinfo['name']));
162        $form->addTagClose('td');
163        $form->addTagOpen('td');
164        $form->addHTML(hsc($userinfo['mail']));
165        $form->addTagClose('td');
166        $form->addTagOpen('td');
167        $form->addButton('reset[' . $user . ']', $this->getLang('reset'))
168             ->attr('type', 'submit')
169             ->addClass('twofactor_resetconfirm');
170        $form->addTagClose('td');
171        $form->addTagClose('tr');
172        return $form;
173    }
174
175    /**
176     * Add the pagination buttons to the form
177     *
178     * @param Form $form
179     * @param int $usercount
180     * @param int $start
181     * @param int $pagesize
182     * @return Form
183     */
184    protected function addTablePagination(Form $form, $usercount, $start, $pagesize)
185    {
186        $form->addTagOpen('tr');
187        $form->addTagOpen('td')->attr('colspan', '4');
188        $form->addTagOpen('div')->addClass('pagination');
189
190        // start
191        $btn = $form->addButton('start', $this->getLang('start'))->val('0');
192        if ($start <= 0) $btn->attr('disabled', 'disabled');
193
194        // prev
195        $btn = $form->addButton('start', $this->getLang('prev'))->val($start - $pagesize);
196        if ($start - $pagesize < 0) $btn->attr('disabled', 'disabled');
197
198        // next
199        $btn = $form->addButton('start', $this->getLang('next'))->val($start + $pagesize);
200        if ($start + $pagesize >= $usercount) $btn->attr('disabled', 'disabled');
201
202        // last
203        $btn = $form->addButton('start', $this->getLang('last'))->val($usercount - $pagesize);
204        if ($usercount - $pagesize <= 0) $btn->attr('disabled', 'disabled');
205        if ($usercount - $pagesize == $start) $btn->attr('disabled', 'disabled');
206
207        $form->addTagClose('div');
208        $form->addTagClose('td');
209        $form->addTagClose('tr');
210
211        return $form;
212    }
213
214    /**
215     * Get the filtered users that have a twofactor provider set
216     *
217     * @param array $filter
218     * @return array
219     */
220    protected function getUserData($filter)
221    {
222        $users = $this->attribute->enumerateUsers('twofactor');
223        return $this->applyFilter($users, $filter);
224    }
225
226    /**
227     * Apply the given filters and return user details
228     *
229     * @param string[] $users simple list of user names
230     * @param array $filter
231     * @return array (user => userdata)
232     */
233    protected function applyFilter($users, $filter)
234    {
235        global $auth;
236        $filtered = [];
237
238        $hasFilter = (bool)array_filter(array_values($filter));
239        foreach ($users as $user) {
240            $userdata = $auth->getUserData($user);
241            if (!$userdata) continue;
242            $userdata['user'] = $user;
243            if ($hasFilter) {
244                foreach ($filter as $key => $value) {
245                    if ($value && strstr($userdata[$key], $value)) {
246                        $filtered[$user] = $userdata;
247                        continue 2;
248                    }
249                }
250            } else {
251                $filtered[$user] = $userdata;
252            }
253        }
254        return $filtered;
255    }
256
257    /**
258     * Get the current page of users
259     *
260     * @param array $users
261     * @param int $start
262     * @param int $pagesize
263     * @return array
264     */
265    protected function applyPagination($users, $start, $pagesize)
266    {
267        return array_slice($users, $start, $pagesize, true);
268    }
269
270}
271