xref: /dokuwiki/lib/plugins/usermanager/cli.php (revision c93d7d342d653b1bbc2efa57d3fb3cee79cfc128)
1<?php
2
3use splitbrain\phpcli\TableFormatter;
4
5/**
6 * Class cli_plugin_usermanager
7 *
8 * Command Line component for the usermanager
9 *
10 * @license GPL2
11 * @author Karsten Kosmala <karsten.kosmala@gmail.com>
12 */
13class cli_plugin_usermanager extends DokuWiki_CLI_Plugin
14{
15    public function __construct()
16    {
17        parent::__construct();
18
19        /** @var DokuWiki_Auth_Plugin $auth */
20        auth_setup();
21    }
22
23    /** @inheritdoc */
24    protected function setup(\splitbrain\phpcli\Options $options)
25    {
26        // general setup
27        $options->setHelp(
28            "Manage users for this DokuWiki instance\n"
29        );
30
31        // list
32        $options->registerCommand('list', 'List users');
33        $options->registerOption('verbose', 'Show detailed user information', 'v', false, 'list');
34
35        // add
36        $options->registerCommand('add', 'Add an user to auth backend');
37        $options->registerArgument('name', 'Username', true, 'add');
38        $options->registerArgument('mail', 'mail address', true, 'add');
39        $options->registerArgument('full_name', 'Full name', false, 'add');
40        $options->registerArgument('groups', 'groups to be added', false, 'add');
41        $options->registerArgument('password', 'password of user', false, 'add');
42        $options->registerOption('notify', 'notify user', 'n', false, 'add');
43
44        // delete
45        $options->registerCommand('delete', 'Delete user(s) from auth backend');
46        $options->registerArgument('name', 'Username(s), comma-seperated', true, 'delete');
47
48        // add to group
49        $options->registerCommand('addtogroup', 'Add user to group(s)');
50        $options->registerArgument('name', 'Username, comma-seperated', true, 'addtogroup');
51        $options->registerArgument('group', 'Group(s), comma-seperated', true, 'addtogroup');
52
53        // remove from group
54        $options->registerCommand('removefromgroup', 'Remove user from group(s)');
55        $options->registerArgument('name', 'Username, comma-seperated', true, 'removefromgroup');
56        $options->registerArgument('group', 'Group(s), comma-seperated', true, 'removefromgroup');
57    }
58
59    /** @inheritdoc */
60    protected function main(\splitbrain\phpcli\Options $options)
61    {
62        switch ($options->getCmd()) {
63            case 'list':
64                $ret = $this->cmdList($options->getOpt('verbose'));
65                break;
66            case 'add':
67                $ret = $this->cmdAdd($options->getOpt('notify'), $options->getArgs());
68                break;
69            case 'delete':
70                $ret = $this->cmdDelete($options->getArgs());
71                break;
72            case 'addtogroup':
73                $ret = $this->cmdAddToGroup($options->getArgs());
74                break;
75            case 'removefromgroup':
76                $ret = $this->cmdRemoveFromGroup($options->getArgs());
77                break;
78
79            default:
80                echo $options->help();
81                $ret = 0;
82        }
83
84        exit($ret);
85    }
86
87    /**
88     * @param bool $showdetails
89     * @return int
90     */
91    protected function cmdList(bool $showdetails)
92    {
93        global $auth;
94
95        if (!isset($auth)) {
96            $this->error($this->getLang('noauth'));
97            return 1;
98        } elseif (!$auth->canDo('getUsers')) {
99            $this->error($this->getLang('nosupport'));
100            return 1;
101        } else {
102            $this->listUsers($showdetails);
103        }
104
105        return 0;
106    }
107
108    /**
109     * List the given users
110     *
111     * @param bool $details display details
112     */
113    protected function listUsers(bool $details = False)
114    {
115        global $auth;
116        $list = $auth->retrieveUsers();
117
118        $tr = new TableFormatter($this->colors);
119
120        foreach ($list as $username => $user) {
121            $content = [$username];
122            if ($details) {
123                array_push($content, $user['name']);
124                array_push($content, $user['mail']);
125                array_push($content, implode(", ", $user['grps']));
126            }
127            echo $tr->format(
128                [15, 25, 25, 15],
129                $content
130            );
131        }
132    }
133
134    /**
135     * Adds an user
136     *
137     * @param bool $notify display details
138     * @param array $args
139     * @return int
140     */
141    protected function cmdAdd(bool $notify, array $args)
142    {
143        global $auth;
144
145        if (!$auth->canDo('addUser')) {
146            $this->error($this->getLang('nosupport'));
147            return 1;
148        }
149
150        list($user, $name, $mail, $grps, $pass) = $args;
151        $grps = array_filter(array_map('trim', explode(',', $grps)));
152
153        if ($auth->canDo('modPass')) {
154            if (empty($pass)) {
155                if ($notify) {
156                    $pass = auth_pwgen($user);
157                } else {
158                    $this->error($this->getLang('add_fail'));
159                    $this->error($this->getLang('addUser_error_missing_pass'));
160                    return 1;
161                }
162            }
163        } else {
164            if (!empty($pass)) {
165                $this->error($this->getLang('add_fail'));
166                $this->error($this->getLang('addUser_error_modPass_disabled'));
167                return 1;
168            }
169        }
170
171        if (!$auth->triggerUserMod('create', array($user, $pass, $name, $mail, $grps))) {
172            $this->error($this->getLang('add_fail'));
173            $this->error($this->getLang('addUser_error_create_event_failed'));
174            return 1;
175        }
176
177        return 0;
178    }
179
180    /**
181     * Deletes users
182     * @param array $args
183     * @return int
184     */
185    protected function cmdDelete(array $args)
186    {
187        global $auth;
188
189        if (!$auth->canDo('delUser')) {
190            $this->error($this->getLang('nosupport'));
191            return 1;
192        }
193
194        $users = explode(',', $args[0]);
195        $count = $auth->triggerUserMod('delete', array($users));
196
197        if (!($count == count($users))) {
198            $part1 = str_replace('%d', $count, $this->getLang('delete_ok'));
199            $part2 = str_replace('%d', (count($users) - $count), $this->getLang('delete_fail'));
200            $this->error("$part1, $part2");
201
202            return 1;
203        }
204
205        return 0;
206    }
207
208    /**
209     * Adds an user to group(s)
210     *
211     * @param array $args
212     * @return int
213     */
214    protected function cmdAddToGroup(array $args)
215    {
216        global $auth;
217
218        list($name, $newgrps) = $args;
219        $newgrps = array_filter(array_map('trim', explode(',', $newgrps)));
220        $oldinfo = $auth->getUserData($name);
221        $changes = array();
222
223        if (!empty($newgrps) && $auth->canDo('modGroups')) {
224            $changes['grps'] = $oldinfo['grps'];
225            foreach ($newgrps as $group) {
226                if (!in_array($group, $oldinfo['grps'])) {
227                    array_push($changes['grps'], $group);
228                }
229            }
230        }
231
232        if (!empty(array_diff($changes['grps'], $oldinfo['grps']))) {
233            if ($auth->triggerUserMod('modify', array($name, $changes))) {
234                $this->info($this->getLang('update_ok'));
235            } else {
236                $this->error($this->getLang('update_fail'));
237                return 1;
238            }
239        }
240
241        return 0;
242    }
243
244    /**
245     * Removes an user from group(s)
246     *
247     * @param array $args
248     * @return int
249     */
250    protected function cmdRemoveFromGroup(array $args)
251    {
252        global $auth;
253
254        list($name, $grps) = $args;
255        $grps = array_filter(array_map('trim', explode(',', $grps)));
256        $oldinfo = $auth->getUserData($name);
257        $changes = array();
258
259        if (!empty($grps) && $auth->canDo('modGroups')) {
260            $changes['grps'] = $oldinfo['grps'];
261            foreach ($grps as $group) {
262                if (($pos = array_search($group, $changes['grps'])) ==! false) {
263                    unset($changes['grps'][$pos]);
264                }
265            }
266        }
267
268        if (!empty(array_diff($oldinfo['grps'], $changes['grps']))) {
269            if ($auth->triggerUserMod('modify', array($name, $changes))) {
270                $this->info($this->getLang('update_ok'));
271            } else {
272                $this->error($this->getLang('update_fail'));
273                return 1;
274            }
275        }
276
277        return 0;
278    }
279}
280