xref: /dokuwiki/lib/plugins/usermanager/cli.php (revision 4c1ed9da814741b3dfa44d8b656e85cbd71ec064)
17faa86faSKarsten Kosmala<?php
27faa86faSKarsten Kosmala
38553d24dSAndreas Gohruse dokuwiki\Extension\CLIPlugin;
444c2bd91SAndreas Gohruse dokuwiki\Extension\AuthPlugin;
544c2bd91SAndreas Gohruse splitbrain\phpcli\Options;
67faa86faSKarsten Kosmalause splitbrain\phpcli\TableFormatter;
77faa86faSKarsten Kosmala
87faa86faSKarsten Kosmala/**
97faa86faSKarsten Kosmala * Class cli_plugin_usermanager
107faa86faSKarsten Kosmala *
117faa86faSKarsten Kosmala * Command Line component for the usermanager
127faa86faSKarsten Kosmala *
137faa86faSKarsten Kosmala * @license GPL2
147faa86faSKarsten Kosmala * @author Karsten Kosmala <karsten.kosmala@gmail.com>
157faa86faSKarsten Kosmala */
168553d24dSAndreas Gohrclass cli_plugin_usermanager extends CLIPlugin
177faa86faSKarsten Kosmala{
187faa86faSKarsten Kosmala
197faa86faSKarsten Kosmala    /** @inheritdoc */
2044c2bd91SAndreas Gohr    protected function setup(Options $options)
217faa86faSKarsten Kosmala    {
227faa86faSKarsten Kosmala        // general setup
237faa86faSKarsten Kosmala        $options->setHelp(
24ae26f74eSKarsten Kosmala            "Manage users for this DokuWiki instance\n"
257faa86faSKarsten Kosmala        );
267faa86faSKarsten Kosmala
277faa86faSKarsten Kosmala        // list
287faa86faSKarsten Kosmala        $options->registerCommand('list', 'List users');
297faa86faSKarsten Kosmala        $options->registerOption('verbose', 'Show detailed user information', 'v', false, 'list');
307faa86faSKarsten Kosmala
317faa86faSKarsten Kosmala        // add
327faa86faSKarsten Kosmala        $options->registerCommand('add', 'Add an user to auth backend');
334fe4fe89SAndreas Gohr        $options->registerArgument('login', 'Username', true, 'add');
342bf5aa0cSKarsten Kosmala        $options->registerArgument('mail', 'Email address', true, 'add');
354fe4fe89SAndreas Gohr        $options->registerArgument('name', 'Full name', false, 'add');
363dc79ed8SAndreas Gohr        $options->registerArgument('groups', 'Groups to be added, comma-seperated', false, 'add');
373dc79ed8SAndreas Gohr        $options->registerArgument('password', 'Password to set', false, 'add');
382bf5aa0cSKarsten Kosmala        $options->registerOption('notify', 'Notify user', 'n', false, 'add');
397faa86faSKarsten Kosmala
407faa86faSKarsten Kosmala        // delete
4144c2bd91SAndreas Gohr        $options->registerCommand('delete', 'Deletes user(s) from auth backend');
42ae26f74eSKarsten Kosmala        $options->registerArgument('name', 'Username(s), comma-seperated', true, 'delete');
43ae26f74eSKarsten Kosmala
44ae26f74eSKarsten Kosmala        // add to group
45ae26f74eSKarsten Kosmala        $options->registerCommand('addtogroup', 'Add user to group(s)');
462bf5aa0cSKarsten Kosmala        $options->registerArgument('name', 'Username', true, 'addtogroup');
47ae26f74eSKarsten Kosmala        $options->registerArgument('group', 'Group(s), comma-seperated', true, 'addtogroup');
48ae26f74eSKarsten Kosmala
49ae26f74eSKarsten Kosmala        // remove from group
50ae26f74eSKarsten Kosmala        $options->registerCommand('removefromgroup', 'Remove user from group(s)');
512bf5aa0cSKarsten Kosmala        $options->registerArgument('name', 'Username', true, 'removefromgroup');
5244c2bd91SAndreas Gohr        $options->registerArgument('group', 'Group(s), comma-separated', true, 'removefromgroup');
537faa86faSKarsten Kosmala    }
547faa86faSKarsten Kosmala
557faa86faSKarsten Kosmala    /** @inheritdoc */
5644c2bd91SAndreas Gohr    protected function main(Options $options)
577faa86faSKarsten Kosmala    {
58*4c1ed9daSAndreas Gohr        auth_setup();
59*4c1ed9daSAndreas Gohr
60e56df874SAndreas Gohr        /** @var AuthPlugin $auth */
61e56df874SAndreas Gohr        global $auth;
62e56df874SAndreas Gohr
636547cfc7SGerrit Uitslag        if (!$auth instanceof AuthPlugin) {
64e56df874SAndreas Gohr            $this->error($this->getLang('noauth'));
65e56df874SAndreas Gohr            return 1;
66e56df874SAndreas Gohr        }
67e56df874SAndreas Gohr
687faa86faSKarsten Kosmala        switch ($options->getCmd()) {
697faa86faSKarsten Kosmala            case 'list':
707faa86faSKarsten Kosmala                $ret = $this->cmdList($options->getOpt('verbose'));
717faa86faSKarsten Kosmala                break;
727faa86faSKarsten Kosmala            case 'add':
737faa86faSKarsten Kosmala                $ret = $this->cmdAdd($options->getOpt('notify'), $options->getArgs());
747faa86faSKarsten Kosmala                break;
757faa86faSKarsten Kosmala            case 'delete':
767faa86faSKarsten Kosmala                $ret = $this->cmdDelete($options->getArgs());
777faa86faSKarsten Kosmala                break;
78ae26f74eSKarsten Kosmala            case 'addtogroup':
79ae26f74eSKarsten Kosmala                $ret = $this->cmdAddToGroup($options->getArgs());
80ae26f74eSKarsten Kosmala                break;
81ae26f74eSKarsten Kosmala            case 'removefromgroup':
82ae26f74eSKarsten Kosmala                $ret = $this->cmdRemoveFromGroup($options->getArgs());
83ae26f74eSKarsten Kosmala                break;
847faa86faSKarsten Kosmala
857faa86faSKarsten Kosmala            default:
867faa86faSKarsten Kosmala                echo $options->help();
877faa86faSKarsten Kosmala                $ret = 0;
887faa86faSKarsten Kosmala        }
897faa86faSKarsten Kosmala
907faa86faSKarsten Kosmala        exit($ret);
917faa86faSKarsten Kosmala    }
927faa86faSKarsten Kosmala
937faa86faSKarsten Kosmala    /**
947faa86faSKarsten Kosmala     * @param bool $showdetails
957faa86faSKarsten Kosmala     * @return int
967faa86faSKarsten Kosmala     */
97ae26f74eSKarsten Kosmala    protected function cmdList(bool $showdetails)
987faa86faSKarsten Kosmala    {
9944c2bd91SAndreas Gohr        /** @var AuthPlugin $auth */
100ae26f74eSKarsten Kosmala        global $auth;
1017faa86faSKarsten Kosmala
102e56df874SAndreas Gohr        if (!$auth->canDo('getUsers')) {
103ae26f74eSKarsten Kosmala            $this->error($this->getLang('nosupport'));
104ae26f74eSKarsten Kosmala            return 1;
105ae26f74eSKarsten Kosmala        } else {
106ae26f74eSKarsten Kosmala            $this->listUsers($showdetails);
107ae26f74eSKarsten Kosmala        }
1087faa86faSKarsten Kosmala
1097faa86faSKarsten Kosmala        return 0;
1107faa86faSKarsten Kosmala    }
1117faa86faSKarsten Kosmala
1127faa86faSKarsten Kosmala    /**
1137faa86faSKarsten Kosmala     * List the given users
1147faa86faSKarsten Kosmala     *
1157faa86faSKarsten Kosmala     * @param bool $details display details
1167faa86faSKarsten Kosmala     */
11744c2bd91SAndreas Gohr    protected function listUsers(bool $details = false)
1187faa86faSKarsten Kosmala    {
11944c2bd91SAndreas Gohr        /** @var AuthPlugin $auth */
120ae26f74eSKarsten Kosmala        global $auth;
121ae26f74eSKarsten Kosmala        $list = $auth->retrieveUsers();
122ae26f74eSKarsten Kosmala
1237faa86faSKarsten Kosmala        $tr = new TableFormatter($this->colors);
1247faa86faSKarsten Kosmala
1257faa86faSKarsten Kosmala        foreach ($list as $username => $user) {
1267faa86faSKarsten Kosmala            $content = [$username];
1277faa86faSKarsten Kosmala            if ($details) {
12854cc7aa4SAndreas Gohr                $content[] = $user['name'];
12954cc7aa4SAndreas Gohr                $content[] = $user['mail'];
13054cc7aa4SAndreas Gohr                $content[] = implode(", ", $user['grps']);
1317faa86faSKarsten Kosmala            }
1327faa86faSKarsten Kosmala            echo $tr->format(
1337faa86faSKarsten Kosmala                [15, 25, 25, 15],
1347faa86faSKarsten Kosmala                $content
1357faa86faSKarsten Kosmala            );
1367faa86faSKarsten Kosmala        }
1377faa86faSKarsten Kosmala    }
1387faa86faSKarsten Kosmala
139ae26f74eSKarsten Kosmala    /**
140ae26f74eSKarsten Kosmala     * Adds an user
141ae26f74eSKarsten Kosmala     *
142ae26f74eSKarsten Kosmala     * @param bool $notify display details
143ae26f74eSKarsten Kosmala     * @param array $args
144ae26f74eSKarsten Kosmala     * @return int
145ae26f74eSKarsten Kosmala     */
1467faa86faSKarsten Kosmala    protected function cmdAdd(bool $notify, array $args)
1477faa86faSKarsten Kosmala    {
14844c2bd91SAndreas Gohr        /** @var AuthPlugin $auth */
149ae26f74eSKarsten Kosmala        global $auth;
1507faa86faSKarsten Kosmala
151ae26f74eSKarsten Kosmala        if (!$auth->canDo('addUser')) {
152ae26f74eSKarsten Kosmala            $this->error($this->getLang('nosupport'));
153ae26f74eSKarsten Kosmala            return 1;
154ae26f74eSKarsten Kosmala        }
1557faa86faSKarsten Kosmala
15654cc7aa4SAndreas Gohr        [$login, $mail, $name, $grps, $pass] = $args;
157ae26f74eSKarsten Kosmala        $grps = array_filter(array_map('trim', explode(',', $grps)));
158ae26f74eSKarsten Kosmala
159ae26f74eSKarsten Kosmala        if ($auth->canDo('modPass')) {
1607faa86faSKarsten Kosmala            if (empty($pass)) {
1617faa86faSKarsten Kosmala                if ($notify) {
1624fe4fe89SAndreas Gohr                    $pass = auth_pwgen($login);
1637faa86faSKarsten Kosmala                } else {
164ae26f74eSKarsten Kosmala                    $this->error($this->getLang('add_fail'));
165ae26f74eSKarsten Kosmala                    $this->error($this->getLang('addUser_error_missing_pass'));
166ae26f74eSKarsten Kosmala                    return 1;
1677faa86faSKarsten Kosmala                }
1687faa86faSKarsten Kosmala            }
16954cc7aa4SAndreas Gohr        } elseif (!empty($pass)) {
170ae26f74eSKarsten Kosmala            $this->error($this->getLang('add_fail'));
171ae26f74eSKarsten Kosmala            $this->error($this->getLang('addUser_error_modPass_disabled'));
172ae26f74eSKarsten Kosmala            return 1;
1737faa86faSKarsten Kosmala        }
1747faa86faSKarsten Kosmala
17554cc7aa4SAndreas Gohr        if ($auth->triggerUserMod('create', [$login, $pass, $name, $mail, $grps])) {
1761a88e283SAndreas Gohr            $this->success($this->getLang('add_ok'));
1771a88e283SAndreas Gohr        } else {
17880fb44d9SAndreas Gohr            $this->printErrorMessages();
179ae26f74eSKarsten Kosmala            $this->error($this->getLang('add_fail'));
180ae26f74eSKarsten Kosmala            $this->error($this->getLang('addUser_error_create_event_failed'));
181ae26f74eSKarsten Kosmala            return 1;
1827faa86faSKarsten Kosmala        }
1837faa86faSKarsten Kosmala
1847faa86faSKarsten Kosmala        return 0;
1857faa86faSKarsten Kosmala    }
1867faa86faSKarsten Kosmala
187ae26f74eSKarsten Kosmala    /**
188ae26f74eSKarsten Kosmala     * Deletes users
189ae26f74eSKarsten Kosmala     * @param array $args
190ae26f74eSKarsten Kosmala     * @return int
191ae26f74eSKarsten Kosmala     */
1927faa86faSKarsten Kosmala    protected function cmdDelete(array $args)
1937faa86faSKarsten Kosmala    {
19444c2bd91SAndreas Gohr        /** @var AuthPlugin $auth */
195ae26f74eSKarsten Kosmala        global $auth;
1967faa86faSKarsten Kosmala
197ae26f74eSKarsten Kosmala        if (!$auth->canDo('delUser')) {
198ae26f74eSKarsten Kosmala            $this->error($this->getLang('nosupport'));
199ae26f74eSKarsten Kosmala            return 1;
200ae26f74eSKarsten Kosmala        }
201ae26f74eSKarsten Kosmala
202ae26f74eSKarsten Kosmala        $users = explode(',', $args[0]);
20354cc7aa4SAndreas Gohr        $count = $auth->triggerUserMod('delete', [$users]);
2047faa86faSKarsten Kosmala
20554cc7aa4SAndreas Gohr        if ($count != count($users)) {
20680fb44d9SAndreas Gohr            $this->printErrorMessages();
207ae26f74eSKarsten Kosmala            $part1 = str_replace('%d', $count, $this->getLang('delete_ok'));
208ae26f74eSKarsten Kosmala            $part2 = str_replace('%d', (count($users) - $count), $this->getLang('delete_fail'));
2097faa86faSKarsten Kosmala            $this->error("$part1, $part2");
210ae26f74eSKarsten Kosmala            return 1;
211ae26f74eSKarsten Kosmala        }
212ae26f74eSKarsten Kosmala
213ae26f74eSKarsten Kosmala        return 0;
214ae26f74eSKarsten Kosmala    }
215ae26f74eSKarsten Kosmala
216ae26f74eSKarsten Kosmala    /**
217ae26f74eSKarsten Kosmala     * Adds an user to group(s)
218ae26f74eSKarsten Kosmala     *
219ae26f74eSKarsten Kosmala     * @param array $args
220ae26f74eSKarsten Kosmala     * @return int
221ae26f74eSKarsten Kosmala     */
222ae26f74eSKarsten Kosmala    protected function cmdAddToGroup(array $args)
223ae26f74eSKarsten Kosmala    {
22444c2bd91SAndreas Gohr        /** @var AuthPlugin $auth */
225ae26f74eSKarsten Kosmala        global $auth;
226ae26f74eSKarsten Kosmala
22754cc7aa4SAndreas Gohr        [$name, $newgrps] = $args;
228ae26f74eSKarsten Kosmala        $newgrps = array_filter(array_map('trim', explode(',', $newgrps)));
229ae26f74eSKarsten Kosmala        $oldinfo = $auth->getUserData($name);
23054cc7aa4SAndreas Gohr        $changes = [];
231ae26f74eSKarsten Kosmala
23254cc7aa4SAndreas Gohr        if ($newgrps !== [] && $auth->canDo('modGroups')) {
233ae26f74eSKarsten Kosmala            $changes['grps'] = $oldinfo['grps'];
234ae26f74eSKarsten Kosmala            foreach ($newgrps as $group) {
235ae26f74eSKarsten Kosmala                if (!in_array($group, $oldinfo['grps'])) {
23654cc7aa4SAndreas Gohr                    $changes['grps'][] = $group;
237ae26f74eSKarsten Kosmala                }
238ae26f74eSKarsten Kosmala            }
239ae26f74eSKarsten Kosmala        }
240ae26f74eSKarsten Kosmala
241ae26f74eSKarsten Kosmala        if (!empty(array_diff($changes['grps'], $oldinfo['grps']))) {
24254cc7aa4SAndreas Gohr            if ($auth->triggerUserMod('modify', [$name, $changes])) {
2431a88e283SAndreas Gohr                $this->success($this->getLang('update_ok'));
244ae26f74eSKarsten Kosmala            } else {
24580fb44d9SAndreas Gohr                $this->printErrorMessages();
246ae26f74eSKarsten Kosmala                $this->error($this->getLang('update_fail'));
247ae26f74eSKarsten Kosmala                return 1;
248ae26f74eSKarsten Kosmala            }
249ae26f74eSKarsten Kosmala        }
250ae26f74eSKarsten Kosmala
251ae26f74eSKarsten Kosmala        return 0;
252ae26f74eSKarsten Kosmala    }
253ae26f74eSKarsten Kosmala
254ae26f74eSKarsten Kosmala    /**
255ae26f74eSKarsten Kosmala     * Removes an user from group(s)
256ae26f74eSKarsten Kosmala     *
257ae26f74eSKarsten Kosmala     * @param array $args
258ae26f74eSKarsten Kosmala     * @return int
259ae26f74eSKarsten Kosmala     */
260ae26f74eSKarsten Kosmala    protected function cmdRemoveFromGroup(array $args)
261ae26f74eSKarsten Kosmala    {
26244c2bd91SAndreas Gohr        /** @var AuthPlugin $auth */
263ae26f74eSKarsten Kosmala        global $auth;
264ae26f74eSKarsten Kosmala
26554cc7aa4SAndreas Gohr        [$name, $grps] = $args;
266ae26f74eSKarsten Kosmala        $grps = array_filter(array_map('trim', explode(',', $grps)));
267ae26f74eSKarsten Kosmala        $oldinfo = $auth->getUserData($name);
26854cc7aa4SAndreas Gohr        $changes = [];
269ae26f74eSKarsten Kosmala
27054cc7aa4SAndreas Gohr        if ($grps !== [] && $auth->canDo('modGroups')) {
271ae26f74eSKarsten Kosmala            $changes['grps'] = $oldinfo['grps'];
272ae26f74eSKarsten Kosmala            foreach ($grps as $group) {
273ae26f74eSKarsten Kosmala                if (($pos = array_search($group, $changes['grps'])) == !false) {
274ae26f74eSKarsten Kosmala                    unset($changes['grps'][$pos]);
275ae26f74eSKarsten Kosmala                }
276ae26f74eSKarsten Kosmala            }
277ae26f74eSKarsten Kosmala        }
278ae26f74eSKarsten Kosmala
279ae26f74eSKarsten Kosmala        if (!empty(array_diff($oldinfo['grps'], $changes['grps']))) {
28054cc7aa4SAndreas Gohr            if ($auth->triggerUserMod('modify', [$name, $changes])) {
2811a88e283SAndreas Gohr                $this->success($this->getLang('update_ok'));
282ae26f74eSKarsten Kosmala            } else {
28380fb44d9SAndreas Gohr                $this->printErrorMessages();
284ae26f74eSKarsten Kosmala                $this->error($this->getLang('update_fail'));
285ae26f74eSKarsten Kosmala                return 1;
286ae26f74eSKarsten Kosmala            }
2877faa86faSKarsten Kosmala        }
2887faa86faSKarsten Kosmala
2897faa86faSKarsten Kosmala        return 0;
2907faa86faSKarsten Kosmala    }
29180fb44d9SAndreas Gohr
29280fb44d9SAndreas Gohr    /**
29380fb44d9SAndreas Gohr     * Plugins triggered during user modification may cause failures and output messages via
29480fb44d9SAndreas Gohr     * DokuWiki's msg() function
29580fb44d9SAndreas Gohr     */
2963dc79ed8SAndreas Gohr    protected function printErrorMessages()
2973dc79ed8SAndreas Gohr    {
29880fb44d9SAndreas Gohr        global $MSG;
2993dc79ed8SAndreas Gohr        if (isset($MSG)) {
3003dc79ed8SAndreas Gohr            foreach ($MSG as $msg) {
30180fb44d9SAndreas Gohr                if ($msg['lvl'] === 'error') $this->error($msg['msg']);
30280fb44d9SAndreas Gohr            }
30380fb44d9SAndreas Gohr        }
3047faa86faSKarsten Kosmala    }
3053dc79ed8SAndreas Gohr}
306