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
|
|
|
|