1<?php 2 3use dokuwiki\Extension\AuthPlugin; 4use splitbrain\phpcli\Options; 5use 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 <karsten.kosmala@gmail.com> 14 */ 15class 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('name', 'Username', true, 'add'); 38 $options->registerArgument('mail', 'Email 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', '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 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 /** @var AuthPlugin $auth */ 94 global $auth; 95 96 if (!isset($auth)) { 97 $this->error($this->getLang('noauth')); 98 return 1; 99 } elseif (!$auth->canDo('getUsers')) { 100 $this->error($this->getLang('nosupport')); 101 return 1; 102 } else { 103 $this->listUsers($showdetails); 104 } 105 106 return 0; 107 } 108 109 /** 110 * List the given users 111 * 112 * @param bool $details display details 113 */ 114 protected function listUsers(bool $details = false) 115 { 116 /** @var AuthPlugin $auth */ 117 global $auth; 118 $list = $auth->retrieveUsers(); 119 120 $tr = new TableFormatter($this->colors); 121 122 foreach ($list as $username => $user) { 123 $content = [$username]; 124 if ($details) { 125 array_push($content, $user['name']); 126 array_push($content, $user['mail']); 127 array_push($content, implode(", ", $user['grps'])); 128 } 129 echo $tr->format( 130 [15, 25, 25, 15], 131 $content 132 ); 133 } 134 } 135 136 /** 137 * Adds an user 138 * 139 * @param bool $notify display details 140 * @param array $args 141 * @return int 142 */ 143 protected function cmdAdd(bool $notify, array $args) 144 { 145 /** @var AuthPlugin $auth */ 146 global $auth; 147 148 if (!$auth->canDo('addUser')) { 149 $this->error($this->getLang('nosupport')); 150 return 1; 151 } 152 153 list($user, $name, $mail, $grps, $pass) = $args; 154 $grps = array_filter(array_map('trim', explode(',', $grps))); 155 156 if ($auth->canDo('modPass')) { 157 if (empty($pass)) { 158 if ($notify) { 159 $pass = auth_pwgen($user); 160 } else { 161 $this->error($this->getLang('add_fail')); 162 $this->error($this->getLang('addUser_error_missing_pass')); 163 return 1; 164 } 165 } 166 } else { 167 if (!empty($pass)) { 168 $this->error($this->getLang('add_fail')); 169 $this->error($this->getLang('addUser_error_modPass_disabled')); 170 return 1; 171 } 172 } 173 174 if (!$auth->triggerUserMod('create', array($user, $pass, $name, $mail, $grps))) { 175 $this->error($this->getLang('add_fail')); 176 $this->error($this->getLang('addUser_error_create_event_failed')); 177 return 1; 178 } 179 180 return 0; 181 } 182 183 /** 184 * Deletes users 185 * @param array $args 186 * @return int 187 */ 188 protected function cmdDelete(array $args) 189 { 190 /** @var AuthPlugin $auth */ 191 global $auth; 192 193 if (!$auth->canDo('delUser')) { 194 $this->error($this->getLang('nosupport')); 195 return 1; 196 } 197 198 $users = explode(',', $args[0]); 199 $count = $auth->triggerUserMod('delete', array($users)); 200 201 if (!($count == count($users))) { 202 $part1 = str_replace('%d', $count, $this->getLang('delete_ok')); 203 $part2 = str_replace('%d', (count($users) - $count), $this->getLang('delete_fail')); 204 $this->error("$part1, $part2"); 205 206 return 1; 207 } 208 209 return 0; 210 } 211 212 /** 213 * Adds an user to group(s) 214 * 215 * @param array $args 216 * @return int 217 */ 218 protected function cmdAddToGroup(array $args) 219 { 220 /** @var AuthPlugin $auth */ 221 global $auth; 222 223 list($name, $newgrps) = $args; 224 $newgrps = array_filter(array_map('trim', explode(',', $newgrps))); 225 $oldinfo = $auth->getUserData($name); 226 $changes = array(); 227 228 if (!empty($newgrps) && $auth->canDo('modGroups')) { 229 $changes['grps'] = $oldinfo['grps']; 230 foreach ($newgrps as $group) { 231 if (!in_array($group, $oldinfo['grps'])) { 232 array_push($changes['grps'], $group); 233 } 234 } 235 } 236 237 if (!empty(array_diff($changes['grps'], $oldinfo['grps']))) { 238 if ($auth->triggerUserMod('modify', array($name, $changes))) { 239 $this->info($this->getLang('update_ok')); 240 } else { 241 $this->error($this->getLang('update_fail')); 242 return 1; 243 } 244 } 245 246 return 0; 247 } 248 249 /** 250 * Removes an user from group(s) 251 * 252 * @param array $args 253 * @return int 254 */ 255 protected function cmdRemoveFromGroup(array $args) 256 { 257 /** @var AuthPlugin $auth */ 258 global $auth; 259 260 list($name, $grps) = $args; 261 $grps = array_filter(array_map('trim', explode(',', $grps))); 262 $oldinfo = $auth->getUserData($name); 263 $changes = array(); 264 265 if (!empty($grps) && $auth->canDo('modGroups')) { 266 $changes['grps'] = $oldinfo['grps']; 267 foreach ($grps as $group) { 268 if (($pos = array_search($group, $changes['grps'])) == !false) { 269 unset($changes['grps'][$pos]); 270 } 271 } 272 } 273 274 if (!empty(array_diff($oldinfo['grps'], $changes['grps']))) { 275 if ($auth->triggerUserMod('modify', array($name, $changes))) { 276 $this->info($this->getLang('update_ok')); 277 } else { 278 $this->error($this->getLang('update_fail')); 279 return 1; 280 } 281 } 282 283 return 0; 284 } 285} 286