1<?php 2/** 3 * Displays the user management frontend. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public License, 6 * v. 2.0. If a copy of the MPL was not distributed with this file, You can 7 * obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * @package phpMyFAQ 10 * @author Lars Tiedemann <php@larstiedemann.de> 11 * @author Uwe Pries <uwe.pries@digartis.de> 12 * @author Sarah Hermann <sayh@gmx.de> 13 * @author Thorsten Rinne <thorsten@phpmyfaq.de> 14 * @copyright 2005-2020 phpMyFAQ Team 15 * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0 16 * @link https://www.phpmyfaq.de 17 * @since 2005-12-15 18 */ 19 20use phpMyFAQ\Category; 21use phpMyFAQ\Filter; 22use phpMyFAQ\Mail; 23use phpMyFAQ\Pagination; 24use phpMyFAQ\Permission; 25use phpMyFAQ\User; 26use phpMyFAQ\User\CurrentUser; 27use phpMyFAQ\Utils; 28 29if (!defined('IS_VALID_PHPMYFAQ')) { 30 http_response_code(400); 31 exit(); 32} 33 34if ($user->perm->checkRight($user->getUserId(), 'edit_user') || 35 $user->perm->checkRight($user->getUserId(), 'delete_user') || 36 $user->perm->checkRight($user->getUserId(), 'add_user')) { 37 ?> 38 <script src="assets/js/user.js"></script> 39 <?php 40 41 // set some parameters 42 $selectSize = 10; 43 $defaultUserAction = 'list'; 44 $defaultUserStatus = 'active'; 45 $userActionList = [ 46 'udpate_rights', 47 'update_data', 48 'delete_confirm', 49 'delete', 50 'addsave', 51 'add', 52 'list', 53 'listallusers' 54 ]; 55 56 // what shall we do? 57 // actions defined by url: user_action= 58 $userAction = Filter::filterInput(INPUT_GET, 'user_action', FILTER_SANITIZE_STRING, $defaultUserAction); 59 $currentUser = new CurrentUser($faqConfig); 60 61 // actions defined by submit button 62 if (isset($_POST['user_action_deleteConfirm'])) { 63 $userAction = 'delete_confirm'; 64 } 65 if (isset($_POST['cancel'])) { 66 $userAction = $defaultUserAction; 67 } 68 69 // update user rights 70 if ($userAction == 'update_rights' && $user->perm->checkRight($user->getUserId(), 'edit_user')) { 71 $message = ''; 72 $userAction = $defaultUserAction; 73 $userId = Filter::filterInput(INPUT_POST, 'user_id', FILTER_VALIDATE_INT, 0); 74 $csrfOkay = true; 75 $csrfToken = Filter::filterInput(INPUT_POST, 'csrf', FILTER_SANITIZE_STRING); 76 if (!isset($_SESSION['phpmyfaq_csrf_token']) || $_SESSION['phpmyfaq_csrf_token'] !== $csrfToken) { 77 $csrfOkay = false; 78 } 79 if (0 === (int)$userId || !$csrfOkay) { 80 $message .= sprintf('<p class="alert alert-danger">%s</p>', $PMF_LANG['ad_user_error_noId']); 81 } else { 82 $user = new User($faqConfig); 83 $perm = $user->perm; 84 // @todo: Add Filter::filterInput[] 85 $userRights = isset($_POST['user_rights']) ? $_POST['user_rights'] : []; 86 if (!$perm->refuseAllUserRights($userId)) { 87 $message .= sprintf('<p class="alert alert-danger">%s</p>', $PMF_LANG['ad_msg_mysqlerr']); 88 } 89 foreach ($userRights as $rightId) { 90 $perm->grantUserRight($userId, $rightId); 91 } 92 $idUser = $user->getUserById($userId, true); 93 $message .= sprintf( 94 '<p class="alert alert-success">%s <strong>%s</strong> %s</p>', 95 $PMF_LANG['ad_msg_savedsuc_1'], 96 $user->getLogin(), 97 $PMF_LANG['ad_msg_savedsuc_2'] 98 ); 99 $message .= '<script>updateUser(' . $userId . ');</script>'; 100 $user = new CurrentUser($faqConfig); 101 } 102 } 103 104 // update user data 105 if ($userAction == 'update_data' && $user->perm->checkRight($user->getUserId(), 'edit_user')) { 106 $message = ''; 107 $userAction = $defaultUserAction; 108 $userId = Filter::filterInput(INPUT_POST, 'user_id', FILTER_VALIDATE_INT, 0); 109 if ($userId == 0) { 110 $message .= sprintf('<p class="alert alert-danger">%s</p>', $PMF_LANG['ad_user_error_noId']); 111 } else { 112 $userData = []; 113 $userData['display_name'] = Filter::filterInput(INPUT_POST, 'display_name', FILTER_SANITIZE_STRING, ''); 114 $userData['email'] = Filter::filterInput(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL, ''); 115 $userData['last_modified'] = Filter::filterInput(INPUT_POST, 'last_modified', FILTER_SANITIZE_STRING, ''); 116 $userStatus = Filter::filterInput(INPUT_POST, 'user_status', FILTER_SANITIZE_STRING, $defaultUserStatus); 117 $isSuperAdmin = Filter::filterInput(INPUT_POST, 'is_superadmin', FILTER_SANITIZE_STRING); 118 $isSuperAdmin = $isSuperAdmin === 'on' ? true : false; 119 120 $user = new User($faqConfig); 121 $user->getUserById($userId, true); 122 123 $stats = $user->getStatus(); 124 125 // set new password an send email if user is switched to active 126 if ($stats == 'blocked' && $userStatus == 'active') { 127 if (!$user->activateUser()) { 128 $userStatus = 'invalid_status'; 129 } 130 } 131 132 // Set super-admin flag 133 $user->setSuperAdmin($isSuperAdmin); 134 135 if (!$user->userdata->set(array_keys($userData), array_values($userData)) || 136 !$user->setStatus($userStatus)) { 137 $message .= sprintf('<p class="alert alert-danger">%s</p>', $PMF_LANG['ad_msg_mysqlerr']); 138 } else { 139 $message .= sprintf( 140 '<p class="alert alert-success">%s <strong>%s</strong> %s</p>', 141 $PMF_LANG['ad_msg_savedsuc_1'], 142 $user->getLogin(), 143 $PMF_LANG['ad_msg_savedsuc_2'] 144 ); 145 $message .= '<script>updateUser(' . $userId . ');</script>'; 146 } 147 } 148 } 149 150 // delete user confirmation 151 if ($userAction == 'delete_confirm' && $user->perm->checkRight($user->getUserId(), 'delete_user')) { 152 $message = ''; 153 $user = new CurrentUser($faqConfig); 154 155 $userId = Filter::filterInput(INPUT_GET, 'user_delete_id', FILTER_VALIDATE_INT, 0); 156 if ($userId == 0) { 157 $message .= sprintf('<p class="alert alert-danger">%s</p>', $PMF_LANG['ad_user_error_noId']); 158 $userAction = $defaultUserAction; 159 } else { 160 $user->getUserById($userId, true); 161 // account is protected 162 if ($user->getStatus() == 'protected' || $userId == 1) { 163 $message .= sprintf( 164 '<p class="alert alert-danger">%s</p>', 165 $PMF_LANG['ad_user_error_protectedAccount'] 166 ); 167 $userAction = $defaultUserAction; 168 } else { 169 ?> 170 171 <div 172 class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> 173 <h1 class="h2"> 174 <i aria-hidden="" class="fa fa-user"></i> 175 <?= $PMF_LANG['ad_user_deleteUser'] ?> <?= $user->getLogin() ?> 176 </h1> 177 </div> 178 179 <p class="alert alert-danger"> 180 <?= $PMF_LANG['ad_user_del_3'] . ' ' . $PMF_LANG['ad_user_del_1'] . ' ' . $PMF_LANG['ad_user_del_2'] ?> 181 </p> 182 <form action="?action=user&user_action=delete" method="post" accept-charset="utf-8"> 183 <input type="hidden" name="user_id" value="<?= $userId ?>"> 184 <input type="hidden" name="csrf" value="<?= $currentUser->getCsrfTokenFromSession() ?>"> 185 <p class="text-center"> 186 <button class="btn btn-danger" type="submit"> 187 <?= $PMF_LANG['ad_gen_yes'] ?> 188 </button> 189 <a class="btn btn-info" href="?action=user"> 190 <?= $PMF_LANG['ad_gen_no'] ?> 191 </a> 192 </p> 193 </form> 194 <?php 195 } 196 } 197 } 198 199 // delete user 200 if ($userAction == 'delete' && $user->perm->checkRight($user->getUserId(), 'delete_user')) { 201 $message = ''; 202 $user = new User($faqConfig); 203 $userId = Filter::filterInput(INPUT_POST, 'user_id', FILTER_VALIDATE_INT, 0); 204 $csrfOkay = true; 205 $csrfToken = Filter::filterInput(INPUT_POST, 'csrf', FILTER_SANITIZE_STRING); 206 $userAction = $defaultUserAction; 207 208 if (!isset($_SESSION['phpmyfaq_csrf_token']) || $_SESSION['phpmyfaq_csrf_token'] !== $csrfToken) { 209 $csrfOkay = false; 210 } 211 $userAction = $defaultUserAction; 212 if (0 === (int)$userId || !$csrfOkay) { 213 $message .= sprintf('<p class="alert alert-danger">%s</p>', $PMF_LANG['ad_user_error_noId']); 214 } else { 215 if (!$user->getUserById($userId, true)) { 216 $message .= sprintf('<p class="alert alert-danger">%s</p>', $PMF_LANG['ad_user_error_noId']); 217 } 218 if (!$user->deleteUser()) { 219 $message .= sprintf('<p class="alert alert-danger">%s</p>', $PMF_LANG['ad_user_error_delete']); 220 } else { 221 // Move the categories ownership to admin (id == 1) 222 $oCat = new Category($faqConfig, [], false); 223 $oCat->setUser($currentAdminUser); 224 $oCat->setGroups($currentAdminGroups); 225 $oCat->moveOwnership($userId, 1); 226 227 // Remove the user from groups 228 if ('basic' !== $faqConfig->get('security.permLevel')) { 229 $oPerm = Permission::selectPerm('medium', $faqConfig); 230 $oPerm->removeFromAllGroups($userId); 231 } 232 233 $message .= sprintf('<p class="alert alert-success">%s</p>', $PMF_LANG['ad_user_deleted']); 234 } 235 $userError = $user->error(); 236 if ($userError != '') { 237 $message .= sprintf('<p class="alert alert-danger">%s</p>', $userError); 238 } 239 } 240 } 241 242 // save new user 243 if ($userAction === 'addsave' && $user->perm->checkRight($user->getUserId(), 'add_user')) { 244 $newUser = new User($faqConfig); 245 $message = ''; 246 $messages = []; 247 $userName = Filter::filterInput(INPUT_POST, 'user_name', FILTER_SANITIZE_STRING, ''); 248 $userRealName = Filter::filterInput(INPUT_POST, 'user_realname', FILTER_SANITIZE_STRING, ''); 249 $userPassword = Filter::filterInput(INPUT_POST, 'user_password', FILTER_SANITIZE_STRING, ''); 250 $userEmail = Filter::filterInput(INPUT_POST, 'user_email', FILTER_VALIDATE_EMAIL); 251 $userPassword = Filter::filterInput(INPUT_POST, 'user_password', FILTER_SANITIZE_STRING, ''); 252 $userPasswordConfirm = Filter::filterInput(INPUT_POST, 'user_password_confirm', FILTER_SANITIZE_STRING, ''); 253 $userIsSuperAdmin = Filter::filterInput(INPUT_POST, 'user_is_superadmin', FILTER_SANITIZE_STRING); 254 $csrfToken = Filter::filterInput(INPUT_POST, 'csrf', FILTER_SANITIZE_STRING); 255 $csrfOkay = true; 256 257 if (!isset($_SESSION['phpmyfaq_csrf_token']) || $_SESSION['phpmyfaq_csrf_token'] !== $csrfToken) { 258 $csrfOkay = false; 259 } 260 261 if ($userPassword !== $userPasswordConfirm) { 262 $userPassword = ''; 263 $userPasswordConfirm = ''; 264 $messages[] = $PMF_LANG['ad_user_error_passwordsDontMatch']; 265 } 266 267 // check login name 268 if (!$newUser->isValidLogin($userName)) { 269 $userName = ''; 270 $messages[] = $PMF_LANG['ad_user_error_loginInvalid']; 271 } 272 if ($newUser->getUserByLogin($userName)) { 273 $userName = ''; 274 $messages[] = $PMF_LANG['ad_adus_exerr']; 275 } 276 // check realname 277 if ($userRealName == '') { 278 $userRealName = ''; 279 $messages[] = $PMF_LANG['ad_user_error_noRealName']; 280 } 281 // check e-mail 282 if (is_null($userEmail)) { 283 $userEmail = ''; 284 $messages[] = $PMF_LANG['ad_user_error_noEmail']; 285 } 286 287 // ok, let's go 288 if (count($messages) === 0 && $csrfOkay) { 289 // create user account (login and password) 290 if (!$newUser->createUser($userName, $userPassword)) { 291 $messages[] = $newUser->error(); 292 } else { 293 // set user data (realname, email) 294 $newUser->userdata->set(['display_name', 'email'], [$userRealName, $userEmail]); 295 // set user status 296 $newUser->setStatus($defaultUserStatus); 297 $newUser->setSuperAdmin($userIsSuperAdmin === 'on' ? true : false); 298 } 299 } 300 301 // no errors, send notification to user and show list 302 if (count($messages) === 0) { 303 $text = sprintf( 304 "You have been registered as a new user:\n\nName: %s\nLogin name: %s\nPassword: %s\n\n" . 305 'Check it out here: %s', 306 $userRealName, 307 $userName, 308 $userPassword, 309 $faqConfig->getDefaultUrl() 310 ); 311 312 $mail = new Mail($faqConfig); 313 $mail->addTo($userEmail, $userName); 314 $mail->subject = Utils::resolveMarkers($PMF_LANG['emailRegSubject'], $faqConfig); 315 $mail->message = $text; 316 $result = $mail->send(); 317 318 $userAction = $defaultUserAction; 319 $message = sprintf('<p class="alert alert-success">%s</p>', $PMF_LANG['ad_adus_suc']); 320 // display error messages and show form again 321 } else { 322 $userAction = 'add'; 323 $message = '<p class="alert alert-danger">'; 324 foreach ($messages as $err) { 325 $message .= $err . '<br>'; 326 } 327 $message .= '</p>'; 328 } 329 } 330 331 if (!isset($message)) { 332 $message = ''; 333 } 334 335 // show new user form 336 if ($userAction === 'add' && $user->perm->checkRight($user->getUserId(), 'add_user')) { ?> 337 338 <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> 339 <h1 class="h2"> 340 <i aria-hidden="true" class="fa fa-user-plus"></i> 341 <?= $PMF_LANG['ad_adus_adduser'] ?> 342 </h1> 343 </div> 344 345 <div id="user_message"><?= $message ?></div> 346 <div id="user_create"> 347 348 <form action="?action=user&user_action=addsave" method="post" role="form"> 349 <input type="hidden" name="csrf" value="<?= $currentUser->getCsrfTokenFromSession() ?>"> 350 351 <div class="form-group row"> 352 <label class="col-lg-2 col-form-label" for="user_name"><?= $PMF_LANG['ad_adus_name'] ?></label> 353 <div class="col-lg-4"> 354 <input type="text" name="user_name" id="user_name" required tabindex="1" class="form-control" 355 value="<?= (isset($userName) ? $userName : '') ?>"> 356 </div> 357 </div> 358 359 <div class="form-group row"> 360 <label class="col-lg-2 col-form-label" for="user_realname"><?= $PMF_LANG['ad_user_realname'] ?></label> 361 <div class="col-lg-4"> 362 <input type="text" name="user_realname" id="user_realname" required tabindex="2" class="form-control" 363 value="<?= (isset($userRealName) ? $userRealName : '') ?>"> 364 </div> 365 </div> 366 367 <div class="form-group row"> 368 <label class="col-lg-2 col-form-label" for="user_email"><?= $PMF_LANG['ad_entry_email'] ?></label> 369 <div class="col-lg-4"> 370 <input type="email" name="user_email" id="user_email" required tabindex="3" class="form-control" 371 value="<?= (isset($userEmail) ? $userEmail : '') ?>"> 372 </div> 373 </div> 374 375 <div class="form-group row"> 376 <label class="col-lg-2 col-form-label" for="password"><?= $PMF_LANG['ad_adus_password'] ?></label> 377 <div class="col-lg-4"> 378 <input type="password" name="user_password" id="password" required tabindex="4" class="form-control" 379 value="<?= (isset($userPassword) ? $userPassword : '') ?>"> 380 </div> 381 </div> 382 383 <div class="form-group row"> 384 <label class="col-lg-2 col-form-label" for="password_confirm"><?= $PMF_LANG['ad_passwd_con'] ?></label> 385 <div class="col-lg-4"> 386 <input type="password" name="user_password_confirm" id="password_confirm" required class="form-control" 387 tabindex="5" value="<?= (isset($userPasswordConfirm) ? $userPasswordConfirm : '') ?>"> 388 </div> 389 </div> 390 391 <div class="form-group form-check row"> 392 <div class="offset-lg-2 col-lg-4"> 393 <input class="form-check-input" type="checkbox" id="is_superadmin" name="user_is_superadmin"> 394 <label class="form-check-label" for="is_superadmin"> 395 <?= $PMF_LANG['ad_user_is_superadmin'] ?> 396 </label> 397 </div> 398 </div> 399 400 <div class="form-group row"> 401 <div class="offset-lg-2 col-lg-10"> 402 <a class="btn btn-info" href="?action=user"> 403 <?= $PMF_LANG['ad_gen_cancel'] ?> 404 </a> 405 <button class="btn btn-success" type="submit"> 406 <?= $PMF_LANG['ad_gen_save'] ?> 407 </button> 408 </div> 409 </div> 410 </form> 411 </div> 412 <?php 413 } 414 415 // show list of users 416 if ($userAction === 'list') { ?> 417 418 <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> 419 <h1 class="h2"> 420 <i aria-hidden="true" class="fa fa-user"></i> 421 <?= $PMF_LANG['ad_user'] ?> 422 </h1> 423 <div class="btn-toolbar mb-2 mb-md-0"> 424 <div class="btn-group mr-2"> 425 <a class="btn btn-sm btn-success" href="?action=user&user_action=add"> 426 <i class="fa fa-user-plus" aria-label="true"></i> <?= $PMF_LANG['ad_user_add'] ?> 427 </a> 428 <?php if ($currentUser->perm->checkRight($user->getUserId(), 'edit_user')): ?> 429 <a class="btn btn-sm btn-info" href="?action=user&user_action=listallusers"> 430 <i class="fa fa-users" aria-label="true"></i> <?= $PMF_LANG['list_all_users'] ?> 431 </a> 432 <?php endif ?> 433 </div> 434 </div> 435 </div> 436 437 <script> 438 /** 439 * Returns the user data as JSON object 440 * 441 * @param user_id User ID 442 */ 443 function getUserData(user_id) { 444 $('#user_data_table').empty(); 445 $.getJSON('index.php?action=ajax&ajax=user&ajaxaction=get_user_data&user_id=' + user_id, function(data) { 446 $('#update_user_id').val(data.user_id); 447 $('#user_status_select').val(data.status); 448 $('#user_list_autocomplete').val(data.login); 449 $('#user_list_select').val(data.user_id); 450 $('#modal_user_id').val(data.user_id); 451 // Append input fields 452 $('#user_data_table').append( 453 '<div class="form-group row">' + 454 '<label class="col-lg-4 col-form-label"><?= $PMF_LANG['ad_user_realname'] ?></label>' + 455 '<div class="col-lg-8">' + 456 '<input type="text" name="display_name" value="' + data.display_name + '" class="form-control" required>' + 457 '</div>' + 458 '</div>' + 459 '<div class="form-group row">' + 460 '<label class="col-lg-4 col-form-label"><?= $PMF_LANG['ad_entry_email'] ?></label>' + 461 '<div class="col-lg-8">' + 462 '<input type="email" name="email" value="' + data.email + '" class="form-control" required>' + 463 '</div>' + 464 '</div>' + 465 '<div class="form-group row">' + 466 '<div class="offset-lg-4 col-lg-8">' + 467 '<div class="form-check">' + 468 '<input class="form-check-input" type="checkbox" id="is_superadmin" name="is_superadmin">' + 469 '<label class="form-check-label" for="is_superadmin"><?= $PMF_LANG['ad_user_is_superadmin'] ?></label>' + 470 '</div>' + 471 '</div>' + 472 '</div>' + 473 '<div class="form-group row">' + 474 '<div class="offset-lg-4 col-lg-8">' + 475 '<a class="btn btn-danger pmf-admin-override-password" data-toggle="modal" ' + 476 ' href="#pmf-modal-user-password-override"><?= $PMF_LANG['ad_user_override_passwd'] ?></a>' + 477 '</div>' + 478 '</div>' + 479 '<input type="hidden" name="last_modified" value="' + data.last_modified + '">', 480 ); 481 if (data.is_superadmin) { 482 $('#is_superadmin').attr('checked', 'checked'); 483 } 484 }); 485 } 486 </script> 487 488 489 <div id="user_message"><?= $message ?></div> 490 491 <div class="row"> 492 <div class="col-lg-4"> 493 <form name="user_select" id="user_select" action="?action=user&user_action=delete_confirm" 494 method="post" role="form" class="form_inline"> 495 <div class="card mb-4"> 496 <div class="card-header"> 497 <i aria-hidden="true" class="fa fa-search"></i> <?= $PMF_LANG['msgSearch'] ?> 498 </div> 499 <div class="card-body"> 500 <div class="input-group"> 501 <input type="text" id="user_list_autocomplete" name="user_list_search" 502 class="form-control pmf-user-autocomplete" autocomplete="off" 503 placeholder="<?= $PMF_LANG['ad_auth_user'] ?>"> 504 </div> 505 </div> 506 </div> 507 </form> 508 </div> 509 510 <div class="col-lg-4"> 511 <div class="card mb-4"> 512 <div class="card-header" id="user_data_legend"> 513 <i aria-hidden="true" class="fa fa-user"></i> <?= $PMF_LANG['ad_user_profou'] ?> 514 </div> 515 <form action="?action=user&user_action=update_data" method="post"> 516 <div class="card-body"> 517 <input id="update_user_id" type="hidden" name="user_id" value="0"> 518 <input type="hidden" name="csrf" value="<?= $currentUser->getCsrfTokenFromSession(); ?>"> 519 <div class="form-group row"> 520 <label for="user_status_select" class="col-lg-4 col-form-label"> 521 <?= $PMF_LANG['ad_user_status'] ?> 522 </label> 523 <div class="col-lg-8"> 524 <select id="user_status_select" class="form-control" name="user_status"> 525 <option value="active"><?= $PMF_LANG['ad_user_active'] ?></option> 526 <option value="blocked"><?= $PMF_LANG['ad_user_blocked'] ?></option> 527 <option value="protected"><?= $PMF_LANG['ad_user_protected'] ?></option> 528 </select> 529 </div> 530 </div> 531 <div id="user_data_table"></div> 532 </div> 533 <div class="card-footer"> 534 <div class="card-button text-right"> 535 <button class="btn btn-success" type="submit"> 536 <i aria-hidden="true" class="fa fa-check"></i> <?= $PMF_LANG['ad_gen_save'] ?> 537 </button> 538 </div> 539 </div> 540 </form> 541 </div> 542 </div> 543 <div class="col-lg-4" id="userRights"> 544 <form id="rightsForm" action="?action=user&user_action=update_rights" method="post" 545 accept-charset="utf-8"> 546 <input type="hidden" name="csrf" value="<?= $currentUser->getCsrfTokenFromSession() ?>"> 547 <input type="hidden" name="user_id" id="rights_user_id" value="0"> 548 549 <div class="card mb-4"> 550 <div class="card-header" id="user_rights_legend"> 551 <i aria-hidden="true" class="fa fa-lock"></i> <?= $PMF_LANG['ad_user_rights'] ?> 552 <span class="float-right"> 553 <a class="btn btn-primary btn-sm" href="#" id="checkAll"> 554 <?= $PMF_LANG['ad_user_checkall'] ?> 555 / 556 <?= $PMF_LANG['ad_user_uncheckall'] ?> 557 </a> 558 </span> 559 </div> 560 <div class="card-body"> 561 <?php foreach ($user->perm->getAllRightsData() as $right): ?> 562 <div class="form-check"> 563 <input id="user_right_<?= $right['right_id'] ?>" type="checkbox" 564 name="user_rights[]" value="<?= $right['right_id'] ?>" 565 class="form-check-input permission"> 566 <label class="form-check-label"> 567 <?php 568 if (isset($PMF_LANG['rightsLanguage'][$right['name']])) { 569 echo $PMF_LANG['rightsLanguage'][$right['name']]; 570 } else { 571 echo $right['description']; 572 } 573 ?> 574 </label> 575 </div> 576 <?php endforeach; ?> 577 </div> 578 <div class="card-footer"> 579 <div class="card-button text-right"> 580 <button class="btn btn-success" type="submit"> 581 <?= $PMF_LANG['ad_gen_save'] ?> 582 </button> 583 </div> 584 </div> 585 </div> 586 </form> 587 </div> 588 </div> 589 590 <div class="modal fade" id="pmf-modal-user-password-override"> 591 <div class="modal-dialog"> 592 <div class="modal-content"> 593 <div class="modal-header"> 594 <h4><?= $PMF_LANG['ad_menu_passwd'] ?></h4> 595 <button type="button" class="close" data-dismiss="modal" aria-label="Close"> 596 <span aria-hidden="true">×</span> 597 </button> 598 </div> 599 <div class="modal-body"> 600 <form action="#" method="post" accept-charset="utf-8"> 601 <input type="hidden" name="csrf" value="<?= $currentUser->getCsrfTokenFromSession() ?>"> 602 <input type="hidden" name="user_id" id="modal_user_id" value="<?= $userId ?>"> 603 604 <div class="form-group row"> 605 <label class="col-lg-4 col-form-label" for="npass"> 606 <?= $PMF_LANG['ad_passwd_new'] ?> 607 </label> 608 <div class="col-lg-8"> 609 <input type="password" name="npass" id="npass" class="form-control" required> 610 </div> 611 </div> 612 613 <div class="form-group row"> 614 <label class="col-lg-4 col-form-label" for="bpass"> 615 <?= $PMF_LANG['ad_passwd_con'] ?> 616 </label> 617 <div class="col-lg-8"> 618 <input type="password" name="bpass" id="bpass" class="form-control" required> 619 </div> 620 </div> 621 622 </form> 623 </div> 624 <div class="modal-footer"> 625 <button class="btn btn-primary pmf-user-password-override-action"> 626 <?= $PMF_LANG['ad_user_override_passwd'] ?> 627 </button> 628 </div> 629 </div> 630 </div> 631 </div> 632 <?php 633 } 634 635 // show list of all users 636 if ($userAction == 'listallusers' && $user->perm->checkRight($user->getUserId(), 'edit_user')) { 637 $allUsers = $user->getAllUsers(false); 638 $numUsers = count($allUsers); 639 $page = Filter::filterInput(INPUT_GET, 'page', FILTER_VALIDATE_INT, 0); 640 $perPage = 10; 641 $numPages = ceil($numUsers / $perPage); 642 $lastPage = $page * $perPage; 643 $firstPage = $lastPage - $perPage; 644 645 $baseUrl = sprintf( 646 '%sadmin/?action=user&user_action=listallusers&page=%d', 647 $faqConfig->getDefaultUrl(), 648 $page 649 ); 650 651 // Pagination options 652 $options = [ 653 'baseUrl' => $baseUrl, 654 'total' => $numUsers, 655 'perPage' => $perPage, 656 'useRewrite' => false, 657 'pageParamName' => 'page', 658 ]; 659 $pagination = new Pagination($faqConfig, $options); 660 ?> 661 662 <div 663 class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> 664 <h1 class="h2"> 665 <i aria-hidden="true" class="fa fa-user"></i> 666 <?= $PMF_LANG['ad_user'] ?> 667 </h1> 668 <div class="btn-toolbar mb-2 mb-md-0"> 669 <div class="btn-group mr-2"> 670 <a class="btn btn-sm btn-success" href="?action=user&user_action=add"> 671 <i class="fa fa-user-plus" aria-label="true"></i> 672 <?= $PMF_LANG['ad_user_add'] ?> 673 </a> 674 </div> 675 </div> 676 </div> 677 678 <div id="user_message"><?= $message ?></div> 679 680 <table class="table table-striped"> 681 <thead class="thead-dark"> 682 <tr> 683 <th><?= $PMF_LANG['ad_entry_id'] ?></th> 684 <th><?= $PMF_LANG['ad_user_status'] ?></th> 685 <th><?= $PMF_LANG['ad_user_is_superadmin'] ?></th> 686 <th><?= $PMF_LANG['msgNewContentName'] ?></th> 687 <th><?= $PMF_LANG['ad_auth_user'] ?></th> 688 <th><?= $PMF_LANG['msgNewContentMail'] ?></th> 689 <th colspan="3"> </th> 690 </tr> 691 </thead> 692 <?php if ($perPage < $numUsers): ?> 693 <tfoot> 694 <tr> 695 <td colspan="8"><?= $pagination->render() ?></td> 696 </tr> 697 </tfoot> 698 <?php endif; 699 ?> 700 <tbody> 701 <?php 702 $counter = $displayedCounter = 0; 703 foreach ($allUsers as $userId) { 704 $user->getUserById($userId, true); 705 706 if ($displayedCounter >= $perPage) { 707 continue; 708 } 709 ++$counter; 710 if ($counter <= $firstPage) { 711 continue; 712 } 713 ++$displayedCounter; 714 715 ?> 716 <tr class="row_user_id_<?= $user->getUserId() ?>"> 717 <td><?= $user->getUserId() ?></td> 718 <td class="text-center"><i class="fa <?php 719 switch ($user->getStatus()) { 720 case 'active': 721 echo 'fa-check-circle-o'; 722 break; 723 case 'blocked': 724 echo 'fa-ban'; 725 break; 726 case 'protected': 727 echo 'fa-lock'; 728 break; 729 } 730 ?> icon_user_id_<?= $user->getUserId() ?>"></i></td> 731 <td class="text-center"> 732 <i class="fa <?= $user->isSuperAdmin() ? 'fa-user-secret' : 'fa-user-times' ?>"></i> 733 </td> 734 <td><?= $user->getUserData('display_name') ?></td> 735 <td><?= $user->getLogin() ?></td> 736 <td> 737 <a href="mailto:<?= $user->getUserData('email') ?>"> 738 <?= $user->getUserData('email') ?> 739 </a> 740 </td> 741 <td> 742 <a href="?action=user&user_id=<?= $user->getUserData('user_id') ?>" class="btn btn-info"> 743 <i class="fa fa-pencil"></i> <?= $PMF_LANG['ad_user_edit'] ?> 744 </a> 745 </td> 746 <td> 747 <?php if ($user->getStatus() === 'blocked'): ?> 748 <a onclick="activateUser(this); return false;" 749 href="#" class="btn btn-success btn_user_id_<?= $user->getUserData('user_id') ?>" 750 data-csrf-token="<?= $currentUser->getCsrfTokenFromSession() ?>" 751 data-user-id="<?= $user->getUserData('user_id') ?>"> 752 <?= $PMF_LANG['ad_news_set_active'] ?> 753 </a> 754 <?php endif; 755 ?> 756 </td> 757 <td> 758 <?php if ($user->getStatus() !== 'protected'): ?> 759 <a href="#" onclick="deleteUser(this); return false;" class="btn btn-danger" 760 data-csrf-token="<?= $currentUser->getCsrfTokenFromSession() ?>" 761 data-user-id="<?= $user->getUserData('user_id') ?>"> 762 <i class="fa fa-trash"></i> <?= $PMF_LANG['ad_user_delete'] ?> 763 </a> 764 <?php endif; 765 ?> 766 </td> 767 </tr> 768 <?php 769 } 770 ?> 771 </tbody> 772 </table> 773 774 <script> 775 /** 776 * Ajax call to delete user 777 * 778 * @param identifier 779 */ 780 function deleteUser(identifier) { 781 if (confirm('<?= $PMF_LANG['ad_user_del_3'] ?>')) { 782 const csrf = $(identifier).data('csrf-token'); 783 const userId = $(identifier).data('user-id'); 784 785 $.getJSON('index.php?action=ajax&ajax=user&ajaxaction=delete_user&user_id=' + userId + '&csrf=' + csrf, 786 (response) => { 787 $('#user_message').html(response); 788 $('.row_user_id_' + userId).fadeOut('slow'); 789 }); 790 } 791 } 792 793 /** 794 * Ajax call to delete user 795 * 796 * @param identifier 797 */ 798 function activateUser(identifier) { 799 if (confirm('<?= $PMF_LANG['ad_user_active'] ?>')) { 800 const csrf = $(identifier).data('csrf-token'); 801 const userId = $(identifier).data('user-id'); 802 $.getJSON('index.php?action=ajax&ajax=user&ajaxaction=activate_user&user_id=' + userId + '&csrf=' + csrf, 803 () => { 804 const icon = $('.icon_user_id_' + userId); 805 icon.toggleClass('fa-lock fa-check'); 806 $('.btn_user_id_' + userId).remove(); 807 }); 808 } 809 } 810 811 </script> 812 <?php 813 } 814 if (isset($_GET['user_id'])) { 815 $userId = Filter::filterInput(INPUT_GET, 'user_id', FILTER_VALIDATE_INT, 0); 816 echo ' <script>updateUser(' . $userId . ');</script>'; 817 } 818} else { 819 echo $PMF_LANG['err_NotAuth']; 820} 821