xref: /dokuwiki/lib/plugins/usermanager/cli.php (revision 3dc79ed87223d967a63e85c2d1adfb35a81d8457)
17faa86faSKarsten Kosmala<?php
27faa86faSKarsten Kosmala
344c2bd91SAndreas Gohruse dokuwiki\Extension\AuthPlugin;
444c2bd91SAndreas Gohruse splitbrain\phpcli\Options;
57faa86faSKarsten Kosmalause splitbrain\phpcli\TableFormatter;
67faa86faSKarsten Kosmala
77faa86faSKarsten Kosmala/**
87faa86faSKarsten Kosmala * Class cli_plugin_usermanager
97faa86faSKarsten Kosmala *
107faa86faSKarsten Kosmala * Command Line component for the usermanager
117faa86faSKarsten Kosmala *
127faa86faSKarsten Kosmala * @license GPL2
137faa86faSKarsten Kosmala * @author Karsten Kosmala <karsten.kosmala@gmail.com>
147faa86faSKarsten Kosmala */
157faa86faSKarsten Kosmalaclass cli_plugin_usermanager extends DokuWiki_CLI_Plugin
167faa86faSKarsten Kosmala{
177faa86faSKarsten Kosmala    public function __construct()
187faa86faSKarsten Kosmala    {
197faa86faSKarsten Kosmala        parent::__construct();
207faa86faSKarsten Kosmala        auth_setup();
217faa86faSKarsten Kosmala    }
227faa86faSKarsten Kosmala
237faa86faSKarsten Kosmala    /** @inheritdoc */
2444c2bd91SAndreas Gohr    protected function setup(Options $options)
257faa86faSKarsten Kosmala    {
267faa86faSKarsten Kosmala        // general setup
277faa86faSKarsten Kosmala        $options->setHelp(
28ae26f74eSKarsten Kosmala            "Manage users for this DokuWiki instance\n"
297faa86faSKarsten Kosmala        );
307faa86faSKarsten Kosmala
317faa86faSKarsten Kosmala        // list
327faa86faSKarsten Kosmala        $options->registerCommand('list', 'List users');
337faa86faSKarsten Kosmala        $options->registerOption('verbose', 'Show detailed user information', 'v', false, 'list');
347faa86faSKarsten Kosmala
357faa86faSKarsten Kosmala        // add
367faa86faSKarsten Kosmala        $options->registerCommand('add', 'Add an user to auth backend');
374fe4fe89SAndreas Gohr        $options->registerArgument('login', 'Username', true, 'add');
382bf5aa0cSKarsten Kosmala        $options->registerArgument('mail', 'Email address', true, 'add');
394fe4fe89SAndreas Gohr        $options->registerArgument('name', 'Full name', false, 'add');
40*3dc79ed8SAndreas Gohr        $options->registerArgument('groups', 'Groups to be added, comma-seperated', false, 'add');
41*3dc79ed8SAndreas Gohr        $options->registerArgument('password', 'Password to set', false, 'add');
422bf5aa0cSKarsten Kosmala        $options->registerOption('notify', 'Notify user', 'n', false, 'add');
437faa86faSKarsten Kosmala
447faa86faSKarsten Kosmala        // delete
4544c2bd91SAndreas Gohr        $options->registerCommand('delete', 'Deletes user(s) from auth backend');
46ae26f74eSKarsten Kosmala        $options->registerArgument('name', 'Username(s), comma-seperated', true, 'delete');
47ae26f74eSKarsten Kosmala
48ae26f74eSKarsten Kosmala        // add to group
49ae26f74eSKarsten Kosmala        $options->registerCommand('addtogroup', 'Add user to group(s)');
502bf5aa0cSKarsten Kosmala        $options->registerArgument('name', 'Username', true, 'addtogroup');
51ae26f74eSKarsten Kosmala        $options->registerArgument('group', 'Group(s), comma-seperated', true, 'addtogroup');
52ae26f74eSKarsten Kosmala
53ae26f74eSKarsten Kosmala        // remove from group
54ae26f74eSKarsten Kosmala        $options->registerCommand('removefromgroup', 'Remove user from group(s)');
552bf5aa0cSKarsten Kosmala        $options->registerArgument('name', 'Username', true, 'removefromgroup');
5644c2bd91SAndreas Gohr        $options->registerArgument('group', 'Group(s), comma-separated', true, 'removefromgroup');
577faa86faSKarsten Kosmala    }
587faa86faSKarsten Kosmala
597faa86faSKarsten Kosmala    /** @inheritdoc */
6044c2bd91SAndreas Gohr    protected function main(Options $options)
617faa86faSKarsten Kosmala    {
62e56df874SAndreas Gohr        /** @var AuthPlugin $auth */
63e56df874SAndreas Gohr        global $auth;
64e56df874SAndreas Gohr
65e56df874SAndreas Gohr        if (!isset($auth)) {
66e56df874SAndreas Gohr            $this->error($this->getLang('noauth'));
67e56df874SAndreas Gohr            return 1;
68e56df874SAndreas Gohr        }
69e56df874SAndreas Gohr
707faa86faSKarsten Kosmala        switch ($options->getCmd()) {
717faa86faSKarsten Kosmala            case 'list':
727faa86faSKarsten Kosmala                $ret = $this->cmdList($options->getOpt('verbose'));
737faa86faSKarsten Kosmala                break;
747faa86faSKarsten Kosmala            case 'add':
757faa86faSKarsten Kosmala                $ret = $this->cmdAdd($options->getOpt('notify'), $options->getArgs());
767faa86faSKarsten Kosmala                break;
777faa86faSKarsten Kosmala            case 'delete':
787faa86faSKarsten Kosmala                $ret = $this->cmdDelete($options->getArgs());
797faa86faSKarsten Kosmala                break;
80ae26f74eSKarsten Kosmala            case 'addtogroup':
81ae26f74eSKarsten Kosmala                $ret = $this->cmdAddToGroup($options->getArgs());
82ae26f74eSKarsten Kosmala                break;
83ae26f74eSKarsten Kosmala            case 'removefromgroup':
84ae26f74eSKarsten Kosmala                $ret = $this->cmdRemoveFromGroup($options->getArgs());
85ae26f74eSKarsten Kosmala                break;
867faa86faSKarsten Kosmala
877faa86faSKarsten Kosmala            default:
887faa86faSKarsten Kosmala                echo $options->help();
897faa86faSKarsten Kosmala                $ret = 0;
907faa86faSKarsten Kosmala        }
917faa86faSKarsten Kosmala
927faa86faSKarsten Kosmala        exit($ret);
937faa86faSKarsten Kosmala    }
947faa86faSKarsten Kosmala
957faa86faSKarsten Kosmala    /**
967faa86faSKarsten Kosmala     * @param bool $showdetails
977faa86faSKarsten Kosmala     * @return int
987faa86faSKarsten Kosmala     */
99ae26f74eSKarsten Kosmala    protected function cmdList(bool $showdetails)
1007faa86faSKarsten Kosmala    {
10144c2bd91SAndreas Gohr        /** @var AuthPlugin $auth */
102ae26f74eSKarsten Kosmala        global $auth;
1037faa86faSKarsten Kosmala
104e56df874SAndreas Gohr        if (!$auth->canDo('getUsers')) {
105ae26f74eSKarsten Kosmala            $this->error($this->getLang('nosupport'));
106ae26f74eSKarsten Kosmala            return 1;
107ae26f74eSKarsten Kosmala        } else {
108ae26f74eSKarsten Kosmala            $this->listUsers($showdetails);
109ae26f74eSKarsten Kosmala        }
1107faa86faSKarsten Kosmala
1117faa86faSKarsten Kosmala        return 0;
1127faa86faSKarsten Kosmala    }
1137faa86faSKarsten Kosmala
1147faa86faSKarsten Kosmala    /**
1157faa86faSKarsten Kosmala     * List the given users
1167faa86faSKarsten Kosmala     *
1177faa86faSKarsten Kosmala     * @param bool $details display details
1187faa86faSKarsten Kosmala     */
11944c2bd91SAndreas Gohr    protected function listUsers(bool $details = false)
1207faa86faSKarsten Kosmala    {
12144c2bd91SAndreas Gohr        /** @var AuthPlugin $auth */
122ae26f74eSKarsten Kosmala        global $auth;
123ae26f74eSKarsten Kosmala        $list = $auth->retrieveUsers();
124ae26f74eSKarsten Kosmala
1257faa86faSKarsten Kosmala        $tr = new TableFormatter($this->colors);
1267faa86faSKarsten Kosmala
1277faa86faSKarsten Kosmala        foreach ($list as $username => $user) {
1287faa86faSKarsten Kosmala            $content = [$username];
1297faa86faSKarsten Kosmala            if ($details) {
1307faa86faSKarsten Kosmala                array_push($content, $user['name']);
1317faa86faSKarsten Kosmala                array_push($content, $user['mail']);
1327faa86faSKarsten Kosmala                array_push($content, implode(", ", $user['grps']));
1337faa86faSKarsten Kosmala            }
1347faa86faSKarsten Kosmala            echo $tr->format(
1357faa86faSKarsten Kosmala                [15, 25, 25, 15],
1367faa86faSKarsten Kosmala                $content
1377faa86faSKarsten Kosmala            );
1387faa86faSKarsten Kosmala        }
1397faa86faSKarsten Kosmala    }
1407faa86faSKarsten Kosmala
141ae26f74eSKarsten Kosmala    /**
142ae26f74eSKarsten Kosmala     * Adds an user
143ae26f74eSKarsten Kosmala     *
144ae26f74eSKarsten Kosmala     * @param bool $notify display details
145ae26f74eSKarsten Kosmala     * @param array $args
146ae26f74eSKarsten Kosmala     * @return int
147ae26f74eSKarsten Kosmala     */
1487faa86faSKarsten Kosmala    protected function cmdAdd(bool $notify, array $args)
1497faa86faSKarsten Kosmala    {
15044c2bd91SAndreas Gohr        /** @var AuthPlugin $auth */
151ae26f74eSKarsten Kosmala        global $auth;
1527faa86faSKarsten Kosmala
153ae26f74eSKarsten Kosmala        if (!$auth->canDo('addUser')) {
154ae26f74eSKarsten Kosmala            $this->error($this->getLang('nosupport'));
155ae26f74eSKarsten Kosmala            return 1;
156ae26f74eSKarsten Kosmala        }
1577faa86faSKarsten Kosmala
1584fe4fe89SAndreas Gohr        list($login, $mail, $name, $grps, $pass) = $args;
159ae26f74eSKarsten Kosmala        $grps = array_filter(array_map('trim', explode(',', $grps)));
160ae26f74eSKarsten Kosmala
161ae26f74eSKarsten Kosmala        if ($auth->canDo('modPass')) {
1627faa86faSKarsten Kosmala            if (empty($pass)) {
1637faa86faSKarsten Kosmala                if ($notify) {
1644fe4fe89SAndreas Gohr                    $pass = auth_pwgen($login);
1657faa86faSKarsten Kosmala                } else {
166ae26f74eSKarsten Kosmala                    $this->error($this->getLang('add_fail'));
167ae26f74eSKarsten Kosmala                    $this->error($this->getLang('addUser_error_missing_pass'));
168ae26f74eSKarsten Kosmala                    return 1;
1697faa86faSKarsten Kosmala                }
1707faa86faSKarsten Kosmala            }
1717faa86faSKarsten Kosmala        } else {
1727faa86faSKarsten Kosmala            if (!empty($pass)) {
173ae26f74eSKarsten Kosmala                $this->error($this->getLang('add_fail'));
174ae26f74eSKarsten Kosmala                $this->error($this->getLang('addUser_error_modPass_disabled'));
175ae26f74eSKarsten Kosmala                return 1;
1767faa86faSKarsten Kosmala            }
1777faa86faSKarsten Kosmala        }
1787faa86faSKarsten Kosmala
1791a88e283SAndreas Gohr        if ($auth->triggerUserMod('create', array($login, $pass, $name, $mail, $grps))) {
1801a88e283SAndreas Gohr            $this->success($this->getLang('add_ok'));
1811a88e283SAndreas Gohr        } else {
18280fb44d9SAndreas Gohr            $this->printErrorMessages();
183ae26f74eSKarsten Kosmala            $this->error($this->getLang('add_fail'));
184ae26f74eSKarsten Kosmala            $this->error($this->getLang('addUser_error_create_event_failed'));
185ae26f74eSKarsten Kosmala            return 1;
1867faa86faSKarsten Kosmala        }
1877faa86faSKarsten Kosmala
1887faa86faSKarsten Kosmala        return 0;
1897faa86faSKarsten Kosmala    }
1907faa86faSKarsten Kosmala
191ae26f74eSKarsten Kosmala    /**
192ae26f74eSKarsten Kosmala     * Deletes users
193ae26f74eSKarsten Kosmala     * @param array $args
194ae26f74eSKarsten Kosmala     * @return int
195ae26f74eSKarsten Kosmala     */
1967faa86faSKarsten Kosmala    protected function cmdDelete(array $args)
1977faa86faSKarsten Kosmala    {
19844c2bd91SAndreas Gohr        /** @var AuthPlugin $auth */
199ae26f74eSKarsten Kosmala        global $auth;
2007faa86faSKarsten Kosmala
201ae26f74eSKarsten Kosmala        if (!$auth->canDo('delUser')) {
202ae26f74eSKarsten Kosmala            $this->error($this->getLang('nosupport'));
203ae26f74eSKarsten Kosmala            return 1;
204ae26f74eSKarsten Kosmala        }
205ae26f74eSKarsten Kosmala
206ae26f74eSKarsten Kosmala        $users = explode(',', $args[0]);
207ae26f74eSKarsten Kosmala        $count = $auth->triggerUserMod('delete', array($users));
2087faa86faSKarsten Kosmala
2097faa86faSKarsten Kosmala        if (!($count == count($users))) {
21080fb44d9SAndreas Gohr            $this->printErrorMessages();
211ae26f74eSKarsten Kosmala            $part1 = str_replace('%d', $count, $this->getLang('delete_ok'));
212ae26f74eSKarsten Kosmala            $part2 = str_replace('%d', (count($users) - $count), $this->getLang('delete_fail'));
2137faa86faSKarsten Kosmala            $this->error("$part1, $part2");
214ae26f74eSKarsten Kosmala            return 1;
215ae26f74eSKarsten Kosmala        }
216ae26f74eSKarsten Kosmala
217ae26f74eSKarsten Kosmala        return 0;
218ae26f74eSKarsten Kosmala    }
219ae26f74eSKarsten Kosmala
220ae26f74eSKarsten Kosmala    /**
221ae26f74eSKarsten Kosmala     * Adds an user to group(s)
222ae26f74eSKarsten Kosmala     *
223ae26f74eSKarsten Kosmala     * @param array $args
224ae26f74eSKarsten Kosmala     * @return int
225ae26f74eSKarsten Kosmala     */
226ae26f74eSKarsten Kosmala    protected function cmdAddToGroup(array $args)
227ae26f74eSKarsten Kosmala    {
22844c2bd91SAndreas Gohr        /** @var AuthPlugin $auth */
229ae26f74eSKarsten Kosmala        global $auth;
230ae26f74eSKarsten Kosmala
231ae26f74eSKarsten Kosmala        list($name, $newgrps) = $args;
232ae26f74eSKarsten Kosmala        $newgrps = array_filter(array_map('trim', explode(',', $newgrps)));
233ae26f74eSKarsten Kosmala        $oldinfo = $auth->getUserData($name);
234ae26f74eSKarsten Kosmala        $changes = array();
235ae26f74eSKarsten Kosmala
236ae26f74eSKarsten Kosmala        if (!empty($newgrps) && $auth->canDo('modGroups')) {
237ae26f74eSKarsten Kosmala            $changes['grps'] = $oldinfo['grps'];
238ae26f74eSKarsten Kosmala            foreach ($newgrps as $group) {
239ae26f74eSKarsten Kosmala                if (!in_array($group, $oldinfo['grps'])) {
240ae26f74eSKarsten Kosmala                    array_push($changes['grps'], $group);
241ae26f74eSKarsten Kosmala                }
242ae26f74eSKarsten Kosmala            }
243ae26f74eSKarsten Kosmala        }
244ae26f74eSKarsten Kosmala
245ae26f74eSKarsten Kosmala        if (!empty(array_diff($changes['grps'], $oldinfo['grps']))) {
246c93d7d34SKarsten Kosmala            if ($auth->triggerUserMod('modify', array($name, $changes))) {
2471a88e283SAndreas Gohr                $this->success($this->getLang('update_ok'));
248ae26f74eSKarsten Kosmala            } else {
24980fb44d9SAndreas Gohr                $this->printErrorMessages();
250ae26f74eSKarsten Kosmala                $this->error($this->getLang('update_fail'));
251ae26f74eSKarsten Kosmala                return 1;
252ae26f74eSKarsten Kosmala            }
253ae26f74eSKarsten Kosmala        }
254ae26f74eSKarsten Kosmala
255ae26f74eSKarsten Kosmala        return 0;
256ae26f74eSKarsten Kosmala    }
257ae26f74eSKarsten Kosmala
258ae26f74eSKarsten Kosmala    /**
259ae26f74eSKarsten Kosmala     * Removes an user from group(s)
260ae26f74eSKarsten Kosmala     *
261ae26f74eSKarsten Kosmala     * @param array $args
262ae26f74eSKarsten Kosmala     * @return int
263ae26f74eSKarsten Kosmala     */
264ae26f74eSKarsten Kosmala    protected function cmdRemoveFromGroup(array $args)
265ae26f74eSKarsten Kosmala    {
26644c2bd91SAndreas Gohr        /** @var AuthPlugin $auth */
267ae26f74eSKarsten Kosmala        global $auth;
268ae26f74eSKarsten Kosmala
269ae26f74eSKarsten Kosmala        list($name, $grps) = $args;
270ae26f74eSKarsten Kosmala        $grps = array_filter(array_map('trim', explode(',', $grps)));
271ae26f74eSKarsten Kosmala        $oldinfo = $auth->getUserData($name);
272ae26f74eSKarsten Kosmala        $changes = array();
273ae26f74eSKarsten Kosmala
274ae26f74eSKarsten Kosmala        if (!empty($grps) && $auth->canDo('modGroups')) {
275ae26f74eSKarsten Kosmala            $changes['grps'] = $oldinfo['grps'];
276ae26f74eSKarsten Kosmala            foreach ($grps as $group) {
277ae26f74eSKarsten Kosmala                if (($pos = array_search($group, $changes['grps'])) == !false) {
278ae26f74eSKarsten Kosmala                    unset($changes['grps'][$pos]);
279ae26f74eSKarsten Kosmala                }
280ae26f74eSKarsten Kosmala            }
281ae26f74eSKarsten Kosmala        }
282ae26f74eSKarsten Kosmala
283ae26f74eSKarsten Kosmala        if (!empty(array_diff($oldinfo['grps'], $changes['grps']))) {
284c93d7d34SKarsten Kosmala            if ($auth->triggerUserMod('modify', array($name, $changes))) {
2851a88e283SAndreas Gohr                $this->success($this->getLang('update_ok'));
286ae26f74eSKarsten Kosmala            } else {
28780fb44d9SAndreas Gohr                $this->printErrorMessages();
288ae26f74eSKarsten Kosmala                $this->error($this->getLang('update_fail'));
289ae26f74eSKarsten Kosmala                return 1;
290ae26f74eSKarsten Kosmala            }
2917faa86faSKarsten Kosmala        }
2927faa86faSKarsten Kosmala
2937faa86faSKarsten Kosmala        return 0;
2947faa86faSKarsten Kosmala    }
29580fb44d9SAndreas Gohr
29680fb44d9SAndreas Gohr    /**
29780fb44d9SAndreas Gohr     * Plugins triggered during user modification may cause failures and output messages via
29880fb44d9SAndreas Gohr     * DokuWiki's msg() function
29980fb44d9SAndreas Gohr     */
300*3dc79ed8SAndreas Gohr    protected function printErrorMessages()
301*3dc79ed8SAndreas Gohr    {
30280fb44d9SAndreas Gohr        global $MSG;
303*3dc79ed8SAndreas Gohr        if (isset($MSG)) {
304*3dc79ed8SAndreas Gohr            foreach ($MSG as $msg) {
30580fb44d9SAndreas Gohr                if ($msg['lvl'] === 'error') $this->error($msg['msg']);
30680fb44d9SAndreas Gohr            }
30780fb44d9SAndreas Gohr        }
3087faa86faSKarsten Kosmala    }
309*3dc79ed8SAndreas Gohr}
310