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