xref: /plugin/twofactor/admin.php (revision 6ce592efc487b451f073a2775985dd87b8e37f13)
1163ac707SMichael Wilmes<?php
2f62d0e33SAndreas Gohr
3f62d0e33SAndreas Gohruse dokuwiki\Form\Form;
4f62d0e33SAndreas Gohruse dokuwiki\plugin\twofactor\Manager;
5f62d0e33SAndreas Gohr
6f62d0e33SAndreas Gohr/**
7163ac707SMichael Wilmes *  Twofactor Manager
8163ac707SMichael Wilmes *
9bbe22a6aSAndreas Gohr *  Allows to reset a user's twofactor data
10163ac707SMichael Wilmes */
11d0a31016SAndreas Gohrclass admin_plugin_twofactor extends DokuWiki_Admin_Plugin
12d0a31016SAndreas Gohr{
13f62d0e33SAndreas Gohr    protected $userList = array();     // list of users with attributes
14f62d0e33SAndreas Gohr    protected $filter = array();   // user selection filter(s)
15f62d0e33SAndreas Gohr    protected $start = 0;          // index of first user to be displayed
16f62d0e33SAndreas Gohr    protected $last = 0;           // index of the last user to be displayed
17f62d0e33SAndreas Gohr    protected $pagesize = 20;      // number of users to list on one page
18f62d0e33SAndreas Gohr    protected $disabled = '';      // if disabled set to explanatory string
19f62d0e33SAndreas Gohr
20f62d0e33SAndreas Gohr    /** @var helper_plugin_attribute */
21f62d0e33SAndreas Gohr    protected $attribute;
22163ac707SMichael Wilmes
23bbe22a6aSAndreas Gohr    protected $manager;
24bbe22a6aSAndreas Gohr
25163ac707SMichael Wilmes    /**
26163ac707SMichael Wilmes     * Constructor
27163ac707SMichael Wilmes     */
28d0a31016SAndreas Gohr    public function __construct()
29d0a31016SAndreas Gohr    {
30bbe22a6aSAndreas Gohr        $this->manager = Manager::getInstance();
31bbe22a6aSAndreas Gohr        if (!$this->manager->isReady()) return;
32f62d0e33SAndreas Gohr        $this->attribute = plugin_load('helper', 'attribute');
33bbe22a6aSAndreas Gohr
34bbe22a6aSAndreas Gohr        global $INPUT;
35bbe22a6aSAndreas Gohr
36bbe22a6aSAndreas Gohr        $this->filter = $INPUT->arr('filter');
37bbe22a6aSAndreas Gohr        $this->start = $INPUT->int('start');
38163ac707SMichael Wilmes    }
392cc41bddSMichael Wilmes
40f62d0e33SAndreas Gohr    /** @inheritdoc */
41d0a31016SAndreas Gohr    public function handle()
42d0a31016SAndreas Gohr    {
43bbe22a6aSAndreas Gohr        global $INPUT;
44bbe22a6aSAndreas Gohr
45bbe22a6aSAndreas Gohr        if ($INPUT->has('reset') && checkSecurityToken()) {
46bbe22a6aSAndreas Gohr            $userdel = $INPUT->extract('reset')->str('reset');
47bbe22a6aSAndreas Gohr            if ($userdel == $INPUT->server->str('REMOTE_USER')) {
48bbe22a6aSAndreas Gohr                msg($this->lang['reset_not_self'], -1);
49bbe22a6aSAndreas Gohr                return;
50b71db9c8SMichael Wilmes            }
51bbe22a6aSAndreas Gohr            foreach ($this->manager->getAllProviders() as $providerID => $provider) {
52bbe22a6aSAndreas Gohr                $this->attribute->purge($providerID, $userdel);
53163ac707SMichael Wilmes            }
54bbe22a6aSAndreas Gohr            $this->attribute->purge('twofactor', $userdel);
55163ac707SMichael Wilmes        }
56163ac707SMichael Wilmes    }
57163ac707SMichael Wilmes
58163ac707SMichael Wilmes    /**
59163ac707SMichael Wilmes     * Output appropriate html
60163ac707SMichael Wilmes     *
61163ac707SMichael Wilmes     * @return bool
62163ac707SMichael Wilmes     */
63d0a31016SAndreas Gohr    public function html()
64d0a31016SAndreas Gohr    {
65f62d0e33SAndreas Gohr        echo $this->locale_xhtml('admin');
66bbe22a6aSAndreas Gohr        if (!$this->manager->isReady()) {
67bbe22a6aSAndreas Gohr            return true;
68bbe22a6aSAndreas Gohr        }
69f62d0e33SAndreas Gohr
70*6ce592efSAndreas Gohr        $users = $this->getUserData($this->filter);
71*6ce592efSAndreas Gohr        $usercount = count($users);
72*6ce592efSAndreas Gohr        $users = $this->applyPagination($users, $this->start, $this->pagesize);
73*6ce592efSAndreas Gohr
74bbe22a6aSAndreas Gohr        $form = new Form(['method' => 'POST', 'class' => 'plugin_twofactor_admin']);
75f62d0e33SAndreas Gohr        $form->setHiddenField('do', 'admin');
76f62d0e33SAndreas Gohr        $form->setHiddenField('page', 'twofactor');
77f62d0e33SAndreas Gohr        $form->setHiddenField('start', $this->start);
78f62d0e33SAndreas Gohr
79f62d0e33SAndreas Gohr        $form->addTagOpen('div')->addClass('table');
80f62d0e33SAndreas Gohr        $form->addTagOpen('table')->addClass('inline');
81f62d0e33SAndreas Gohr        $form = $this->addTableHead($form);
82f62d0e33SAndreas Gohr
83f62d0e33SAndreas Gohr        $form->addTagOpen('tbody');
84f62d0e33SAndreas Gohr        foreach ($users as $user => $userinfo) {
85f62d0e33SAndreas Gohr            $form = $this->addTableUser($form, $user, $userinfo);
86f62d0e33SAndreas Gohr        }
87f62d0e33SAndreas Gohr        $form->addTagClose('tbody');
88f62d0e33SAndreas Gohr
89bbe22a6aSAndreas Gohr        $form->addTagOpen('tfooter');
90bbe22a6aSAndreas Gohr        $form = $this->addTablePagination($form, $usercount, $this->start, $this->pagesize);
91bbe22a6aSAndreas Gohr        $form->addTagClose('tfooter');
92bbe22a6aSAndreas Gohr
93f62d0e33SAndreas Gohr        $form->addTagClose('table');
94f62d0e33SAndreas Gohr        $form->addTagClose('div');
95f62d0e33SAndreas Gohr
96f62d0e33SAndreas Gohr        echo $form->toHTML();
97f62d0e33SAndreas Gohr
98b71db9c8SMichael Wilmes        return true;
99b71db9c8SMichael Wilmes    }
100b71db9c8SMichael Wilmes
101163ac707SMichael Wilmes    /**
102f62d0e33SAndreas Gohr     * Add the table headers to the table in the given form
103f62d0e33SAndreas Gohr     * @param Form $form
104f62d0e33SAndreas Gohr     * @return Form
105163ac707SMichael Wilmes     */
106f62d0e33SAndreas Gohr    protected function addTableHead(Form $form)
107f62d0e33SAndreas Gohr    {
108f62d0e33SAndreas Gohr        $form->addTagOpen('thead');
109f62d0e33SAndreas Gohr
110f62d0e33SAndreas Gohr        // header
111f62d0e33SAndreas Gohr        $form->addTagOpen('tr');
112f62d0e33SAndreas Gohr        $form->addTagOpen('th');
113f62d0e33SAndreas Gohr        $form->addHTML($this->getLang('user_id'));
114f62d0e33SAndreas Gohr        $form->addTagClose('th');
115f62d0e33SAndreas Gohr        $form->addTagOpen('th');
116f62d0e33SAndreas Gohr        $form->addHTML($this->getLang('user_name'));
117f62d0e33SAndreas Gohr        $form->addTagClose('th');
118f62d0e33SAndreas Gohr        $form->addTagOpen('th');
119f62d0e33SAndreas Gohr        $form->addHTML($this->getLang('user_mail'));
120f62d0e33SAndreas Gohr        $form->addTagClose('th');
121f62d0e33SAndreas Gohr        $form->addTagOpen('th');
122f62d0e33SAndreas Gohr        $form->addHTML($this->getLang('action'));
123f62d0e33SAndreas Gohr        $form->addTagClose('th');
124f62d0e33SAndreas Gohr        $form->addTagClose('tr');
125f62d0e33SAndreas Gohr
126f62d0e33SAndreas Gohr        // filter
127f62d0e33SAndreas Gohr        $form->addTagOpen('tr');
128f62d0e33SAndreas Gohr        $form->addTagOpen('th');
129bbe22a6aSAndreas Gohr        $form->addTextInput('filter[user]');
130f62d0e33SAndreas Gohr        $form->addTagClose('th');
131f62d0e33SAndreas Gohr        $form->addTagOpen('th');
132bbe22a6aSAndreas Gohr        $form->addTextInput('filter[name]');
133f62d0e33SAndreas Gohr        $form->addTagClose('th');
134f62d0e33SAndreas Gohr        $form->addTagOpen('th');
135bbe22a6aSAndreas Gohr        $form->addTextInput('filter[mail]');
136f62d0e33SAndreas Gohr        $form->addTagClose('th');
137f62d0e33SAndreas Gohr        $form->addTagOpen('th');
138f62d0e33SAndreas Gohr        $form->addButton('', $this->getLang('search'))->attr('type', 'submit');
139f62d0e33SAndreas Gohr        $form->addTagClose('th');
140f62d0e33SAndreas Gohr        $form->addTagClose('tr');
141f62d0e33SAndreas Gohr
142f62d0e33SAndreas Gohr        $form->addTagClose('thead');
143f62d0e33SAndreas Gohr        return $form;
144163ac707SMichael Wilmes    }
145163ac707SMichael Wilmes
146f62d0e33SAndreas Gohr    /**
147f62d0e33SAndreas Gohr     * Add
148f62d0e33SAndreas Gohr     *
149f62d0e33SAndreas Gohr     * @param Form $form
150f62d0e33SAndreas Gohr     * @param $user
151f62d0e33SAndreas Gohr     * @param $userinfo
152f62d0e33SAndreas Gohr     * @return Form
153f62d0e33SAndreas Gohr     */
154f62d0e33SAndreas Gohr    protected function addTableUser(Form $form, $user, $userinfo)
155f62d0e33SAndreas Gohr    {
156f62d0e33SAndreas Gohr        $form->addTagOpen('tr');
157f62d0e33SAndreas Gohr        $form->addTagOpen('td');
158f62d0e33SAndreas Gohr        $form->addHTML(hsc($user));
159f62d0e33SAndreas Gohr        $form->addTagClose('td');
160f62d0e33SAndreas Gohr        $form->addTagOpen('td');
161f62d0e33SAndreas Gohr        $form->addHTML(hsc($userinfo['name']));
162f62d0e33SAndreas Gohr        $form->addTagClose('td');
163f62d0e33SAndreas Gohr        $form->addTagOpen('td');
164f62d0e33SAndreas Gohr        $form->addHTML(hsc($userinfo['mail']));
165f62d0e33SAndreas Gohr        $form->addTagClose('td');
166f62d0e33SAndreas Gohr        $form->addTagOpen('td');
167bbe22a6aSAndreas Gohr        $form->addButton('reset[' . $user . ']', $this->getLang('reset'))
168bbe22a6aSAndreas Gohr             ->attr('type', 'submit')
169bbe22a6aSAndreas Gohr             ->addClass('twofactor_resetconfirm');
170f62d0e33SAndreas Gohr        $form->addTagClose('td');
171f62d0e33SAndreas Gohr        $form->addTagClose('tr');
172f62d0e33SAndreas Gohr        return $form;
173163ac707SMichael Wilmes    }
174163ac707SMichael Wilmes
175f62d0e33SAndreas Gohr    /**
176bbe22a6aSAndreas Gohr     * Add the pagination buttons to the form
177163ac707SMichael Wilmes     *
178bbe22a6aSAndreas Gohr     * @param Form $form
179bbe22a6aSAndreas Gohr     * @param int $usercount
180bbe22a6aSAndreas Gohr     * @param int $start
181bbe22a6aSAndreas Gohr     * @param int $pagesize
182bbe22a6aSAndreas Gohr     * @return Form
183163ac707SMichael Wilmes     */
184bbe22a6aSAndreas Gohr    protected function addTablePagination(Form $form, $usercount, $start, $pagesize)
185d0a31016SAndreas Gohr    {
186bbe22a6aSAndreas Gohr        $form->addTagOpen('tr');
187bbe22a6aSAndreas Gohr        $form->addTagOpen('td')->attr('colspan', '4');
188bbe22a6aSAndreas Gohr        $form->addTagOpen('div')->addClass('pagination');
189163ac707SMichael Wilmes
190bbe22a6aSAndreas Gohr        // start
191bbe22a6aSAndreas Gohr        $btn = $form->addButton('start', $this->getLang('start'))->val('0');
192bbe22a6aSAndreas Gohr        if ($start <= 0) $btn->attr('disabled', 'disabled');
193163ac707SMichael Wilmes
194bbe22a6aSAndreas Gohr        // prev
195bbe22a6aSAndreas Gohr        $btn = $form->addButton('start', $this->getLang('prev'))->val($start - $pagesize);
196bbe22a6aSAndreas Gohr        if ($start - $pagesize < 0) $btn->attr('disabled', 'disabled');
197bbe22a6aSAndreas Gohr
198bbe22a6aSAndreas Gohr        // next
199bbe22a6aSAndreas Gohr        $btn = $form->addButton('start', $this->getLang('next'))->val($start + $pagesize);
200bbe22a6aSAndreas Gohr        if ($start + $pagesize >= $usercount) $btn->attr('disabled', 'disabled');
201bbe22a6aSAndreas Gohr
202bbe22a6aSAndreas Gohr        // last
203bbe22a6aSAndreas Gohr        $btn = $form->addButton('start', $this->getLang('last'))->val($usercount - $pagesize);
204bbe22a6aSAndreas Gohr        if ($usercount - $pagesize <= 0) $btn->attr('disabled', 'disabled');
205bbe22a6aSAndreas Gohr        if ($usercount - $pagesize == $start) $btn->attr('disabled', 'disabled');
206bbe22a6aSAndreas Gohr
207bbe22a6aSAndreas Gohr        $form->addTagClose('div');
208bbe22a6aSAndreas Gohr        $form->addTagClose('td');
209bbe22a6aSAndreas Gohr        $form->addTagClose('tr');
210bbe22a6aSAndreas Gohr
211bbe22a6aSAndreas Gohr        return $form;
212163ac707SMichael Wilmes    }
213163ac707SMichael Wilmes
214163ac707SMichael Wilmes    /**
215bbe22a6aSAndreas Gohr     * Get the filtered users that have a twofactor provider set
216163ac707SMichael Wilmes     *
217bbe22a6aSAndreas Gohr     * @param array $filter
218163ac707SMichael Wilmes     * @return array
219163ac707SMichael Wilmes     */
220bbe22a6aSAndreas Gohr    protected function getUserData($filter)
221d0a31016SAndreas Gohr    {
222bbe22a6aSAndreas Gohr        $users = $this->attribute->enumerateUsers('twofactor');
223bbe22a6aSAndreas Gohr        return $this->applyFilter($users, $filter);
224163ac707SMichael Wilmes    }
225163ac707SMichael Wilmes
226163ac707SMichael Wilmes    /**
227bbe22a6aSAndreas Gohr     * Apply the given filters and return user details
228163ac707SMichael Wilmes     *
229bbe22a6aSAndreas Gohr     * @param string[] $users simple list of user names
230bbe22a6aSAndreas Gohr     * @param array $filter
231bbe22a6aSAndreas Gohr     * @return array (user => userdata)
232163ac707SMichael Wilmes     */
233bbe22a6aSAndreas Gohr    protected function applyFilter($users, $filter)
234d0a31016SAndreas Gohr    {
235bbe22a6aSAndreas Gohr        global $auth;
236bbe22a6aSAndreas Gohr        $filtered = [];
237163ac707SMichael Wilmes
238bbe22a6aSAndreas Gohr        $hasFilter = (bool)array_filter(array_values($filter));
239bbe22a6aSAndreas Gohr        foreach ($users as $user) {
240bbe22a6aSAndreas Gohr            $userdata = $auth->getUserData($user);
241bbe22a6aSAndreas Gohr            if (!$userdata) continue;
242bbe22a6aSAndreas Gohr            $userdata['user'] = $user;
243bbe22a6aSAndreas Gohr            if ($hasFilter) {
244bbe22a6aSAndreas Gohr                foreach ($filter as $key => $value) {
245bbe22a6aSAndreas Gohr                    if ($value && strstr($userdata[$key], $value)) {
246bbe22a6aSAndreas Gohr                        $filtered[$user] = $userdata;
247bbe22a6aSAndreas Gohr                        continue 2;
248bbe22a6aSAndreas Gohr                    }
249bbe22a6aSAndreas Gohr                }
250163ac707SMichael Wilmes            } else {
251bbe22a6aSAndreas Gohr                $filtered[$user] = $userdata;
252bbe22a6aSAndreas Gohr            }
253bbe22a6aSAndreas Gohr        }
254bbe22a6aSAndreas Gohr        return $filtered;
255163ac707SMichael Wilmes    }
256163ac707SMichael Wilmes
257bbe22a6aSAndreas Gohr    /**
258bbe22a6aSAndreas Gohr     * Get the current page of users
259bbe22a6aSAndreas Gohr     *
260bbe22a6aSAndreas Gohr     * @param array $users
261bbe22a6aSAndreas Gohr     * @param int $start
262bbe22a6aSAndreas Gohr     * @param int $pagesize
263bbe22a6aSAndreas Gohr     * @return array
264bbe22a6aSAndreas Gohr     */
265bbe22a6aSAndreas Gohr    protected function applyPagination($users, $start, $pagesize)
266bbe22a6aSAndreas Gohr    {
267bbe22a6aSAndreas Gohr        return array_slice($users, $start, $pagesize, true);
268163ac707SMichael Wilmes    }
269163ac707SMichael Wilmes
270163ac707SMichael Wilmes}
271