Completed
Push — master ( 59fb18...5459b9 )
by Andreas
03:39
created

cli_plugin_usermanager::main()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 7
nop 1
dl 0
loc 34
rs 8.4426
c 0
b 0
f 0
1
<?php
2
3
use dokuwiki\Extension\AuthPlugin;
4
use splitbrain\phpcli\Options;
5
use splitbrain\phpcli\TableFormatter;
6
7
/**
8
 * Class cli_plugin_usermanager
9
 *
10
 * Command Line component for the usermanager
11
 *
12
 * @license GPL2
13
 * @author Karsten Kosmala <[email protected]>
14
 */
15
class cli_plugin_usermanager extends DokuWiki_CLI_Plugin
16
{
17
    public function __construct()
18
    {
19
        parent::__construct();
20
        auth_setup();
21
    }
22
23
    /** @inheritdoc */
24
    protected function setup(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('login', 'Username', true, 'add');
38
        $options->registerArgument('mail', 'Email address', true, 'add');
39
        $options->registerArgument('name', 'Full name', false, 'add');
40
        $options->registerArgument('groups', 'Groups to be added, comma-seperated', false, 'add');
41
        $options->registerArgument('password', 'Password to set', false, 'add');
42
        $options->registerOption('notify', 'Notify user', 'n', false, 'add');
43
44
        // delete
45
        $options->registerCommand('delete', 'Deletes 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', 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', true, 'removefromgroup');
56
        $options->registerArgument('group', 'Group(s), comma-separated', true, 'removefromgroup');
57
    }
58
59
    /** @inheritdoc */
60
    protected function main(Options $options)
61
    {
62
        /** @var AuthPlugin $auth */
63
        global $auth;
64
65
        if (!isset($auth)) {
66
            $this->error($this->getLang('noauth'));
67
            return 1;
68
        }
69
70
        switch ($options->getCmd()) {
71
            case 'list':
72
                $ret = $this->cmdList($options->getOpt('verbose'));
73
                break;
74
            case 'add':
75
                $ret = $this->cmdAdd($options->getOpt('notify'), $options->getArgs());
76
                break;
77
            case 'delete':
78
                $ret = $this->cmdDelete($options->getArgs());
79
                break;
80
            case 'addtogroup':
81
                $ret = $this->cmdAddToGroup($options->getArgs());
82
                break;
83
            case 'removefromgroup':
84
                $ret = $this->cmdRemoveFromGroup($options->getArgs());
85
                break;
86
87
            default:
88
                echo $options->help();
89
                $ret = 0;
90
        }
91
92
        exit($ret);
93
    }
94
95
    /**
96
     * @param bool $showdetails
97
     * @return int
98
     */
99
    protected function cmdList(bool $showdetails)
100
    {
101
        /** @var AuthPlugin $auth */
102
        global $auth;
103
104
        if (!$auth->canDo('getUsers')) {
105
            $this->error($this->getLang('nosupport'));
106
            return 1;
107
        } else {
108
            $this->listUsers($showdetails);
109
        }
110
111
        return 0;
112
    }
113
114
    /**
115
     * List the given users
116
     *
117
     * @param bool $details display details
118
     */
119
    protected function listUsers(bool $details = false)
120
    {
121
        /** @var AuthPlugin $auth */
122
        global $auth;
123
        $list = $auth->retrieveUsers();
124
125
        $tr = new TableFormatter($this->colors);
126
127
        foreach ($list as $username => $user) {
128
            $content = [$username];
129
            if ($details) {
130
                array_push($content, $user['name']);
131
                array_push($content, $user['mail']);
132
                array_push($content, implode(", ", $user['grps']));
133
            }
134
            echo $tr->format(
135
                [15, 25, 25, 15],
136
                $content
137
            );
138
        }
139
    }
140
141
    /**
142
     * Adds an user
143
     *
144
     * @param bool $notify display details
145
     * @param array $args
146
     * @return int
147
     */
148
    protected function cmdAdd(bool $notify, array $args)
149
    {
150
        /** @var AuthPlugin $auth */
151
        global $auth;
152
153
        if (!$auth->canDo('addUser')) {
154
            $this->error($this->getLang('nosupport'));
155
            return 1;
156
        }
157
158
        list($login, $mail, $name, $grps, $pass) = $args;
159
        $grps = array_filter(array_map('trim', explode(',', $grps)));
160
161
        if ($auth->canDo('modPass')) {
162
            if (empty($pass)) {
163
                if ($notify) {
164
                    $pass = auth_pwgen($login);
165
                } else {
166
                    $this->error($this->getLang('add_fail'));
167
                    $this->error($this->getLang('addUser_error_missing_pass'));
168
                    return 1;
169
                }
170
            }
171
        } else {
172
            if (!empty($pass)) {
173
                $this->error($this->getLang('add_fail'));
174
                $this->error($this->getLang('addUser_error_modPass_disabled'));
175
                return 1;
176
            }
177
        }
178
179
        if ($auth->triggerUserMod('create', array($login, $pass, $name, $mail, $grps))) {
180
            $this->success($this->getLang('add_ok'));
181
        } else {
182
            $this->printErrorMessages();
183
            $this->error($this->getLang('add_fail'));
184
            $this->error($this->getLang('addUser_error_create_event_failed'));
185
            return 1;
186
        }
187
188
        return 0;
189
    }
190
191
    /**
192
     * Deletes users
193
     * @param array $args
194
     * @return int
195
     */
196
    protected function cmdDelete(array $args)
197
    {
198
        /** @var AuthPlugin $auth */
199
        global $auth;
200
201
        if (!$auth->canDo('delUser')) {
202
            $this->error($this->getLang('nosupport'));
203
            return 1;
204
        }
205
206
        $users = explode(',', $args[0]);
207
        $count = $auth->triggerUserMod('delete', array($users));
208
209
        if (!($count == count($users))) {
210
            $this->printErrorMessages();
211
            $part1 = str_replace('%d', $count, $this->getLang('delete_ok'));
212
            $part2 = str_replace('%d', (count($users) - $count), $this->getLang('delete_fail'));
213
            $this->error("$part1, $part2");
214
            return 1;
215
        }
216
217
        return 0;
218
    }
219
220
    /**
221
     * Adds an user to group(s)
222
     *
223
     * @param array $args
224
     * @return int
225
     */
226
    protected function cmdAddToGroup(array $args)
227
    {
228
        /** @var AuthPlugin $auth */
229
        global $auth;
230
231
        list($name, $newgrps) = $args;
232
        $newgrps = array_filter(array_map('trim', explode(',', $newgrps)));
233
        $oldinfo = $auth->getUserData($name);
234
        $changes = array();
235
236
        if (!empty($newgrps) && $auth->canDo('modGroups')) {
237
            $changes['grps'] = $oldinfo['grps'];
238
            foreach ($newgrps as $group) {
239
                if (!in_array($group, $oldinfo['grps'])) {
240
                    array_push($changes['grps'], $group);
241
                }
242
            }
243
        }
244
245
        if (!empty(array_diff($changes['grps'], $oldinfo['grps']))) {
246
            if ($auth->triggerUserMod('modify', array($name, $changes))) {
247
                $this->success($this->getLang('update_ok'));
248
            } else {
249
                $this->printErrorMessages();
250
                $this->error($this->getLang('update_fail'));
251
                return 1;
252
            }
253
        }
254
255
        return 0;
256
    }
257
258
    /**
259
     * Removes an user from group(s)
260
     *
261
     * @param array $args
262
     * @return int
263
     */
264
    protected function cmdRemoveFromGroup(array $args)
265
    {
266
        /** @var AuthPlugin $auth */
267
        global $auth;
268
269
        list($name, $grps) = $args;
270
        $grps = array_filter(array_map('trim', explode(',', $grps)));
271
        $oldinfo = $auth->getUserData($name);
272
        $changes = array();
273
274
        if (!empty($grps) && $auth->canDo('modGroups')) {
275
            $changes['grps'] = $oldinfo['grps'];
276
            foreach ($grps as $group) {
277
                if (($pos = array_search($group, $changes['grps'])) == !false) {
278
                    unset($changes['grps'][$pos]);
279
                }
280
            }
281
        }
282
283
        if (!empty(array_diff($oldinfo['grps'], $changes['grps']))) {
284
            if ($auth->triggerUserMod('modify', array($name, $changes))) {
285
                $this->success($this->getLang('update_ok'));
286
            } else {
287
                $this->printErrorMessages();
288
                $this->error($this->getLang('update_fail'));
289
                return 1;
290
            }
291
        }
292
293
        return 0;
294
    }
295
296
    /**
297
     * Plugins triggered during user modification may cause failures and output messages via
298
     * DokuWiki's msg() function
299
     */
300
    protected function printErrorMessages()
301
    {
302
        global $MSG;
303
        if (isset($MSG)) {
304
            foreach ($MSG as $msg) {
305
                if ($msg['lvl'] === 'error') $this->error($msg['msg']);
306
            }
307
        }
308
    }
309
}
310