getId(), MSZ_PERM_USER_MANAGE_USERS)) { echo render_error(403); return; } $notices = []; $userId = (int)filter_input(INPUT_GET, 'u', FILTER_SANITIZE_NUMBER_INT); $currentUser = User::getCurrent(); $currentUserId = $currentUser->getId(); try { $userInfo = User::byId($userId); } catch(UserNotFoundException $ex) { echo render_error(404); return; } $canEdit = $currentUser->hasAuthorityOver($userInfo); $canEditPerms = $canEdit && perms_check_user(MSZ_PERMS_USER, $currentUserId, MSZ_PERM_USER_MANAGE_PERMS); $permissions = manage_perms_list(perms_get_user_raw($userId)); if(CSRF::validateRequest() && $canEdit) { if(!empty($_POST['impersonate_user'])) { if(!$currentUser->isSuper()) { $notices[] = 'You must be a super user to do this.'; } elseif(!is_string($_POST['impersonate_user']) || $_POST['impersonate_user'] !== 'meow') { $notices[] = 'You didn\'t say the magic word.'; } else { $authToken->setImpersonatedUserId($userInfo->getId()); $authToken->applyCookie(); url_redirect('index'); return; } } if(!empty($_POST['send_test_email'])) { if(!$currentUser->isSuper()) { $notices[] = 'You must be a super user to do this.'; } elseif(!is_string($_POST['send_test_email']) || $_POST['send_test_email'] !== 'yes_send_it') { $notices[] = 'Invalid request thing shut the fuck up.'; } else { $testMail = Mailer::sendMessage( [$userInfo->getEMailAddress() => $userInfo->getUsername()], 'Flashii Test E-mail', 'You were sent this e-mail to validate if you can receive e-mails from Flashii. You may discard it.' ); if(!$testMail) $notices[] = 'Failed to send test e-mail.'; } } if(!empty($_POST['roles']) && is_array($_POST['roles'])) { // Read user input array and throw intval on em $applyRoles = []; foreach($_POST['roles'] as $item) { if(!ctype_digit($item)) die('Invalid item encountered in roles list.'); $applyRoles[] = (int)$item; } // Fetch existing roles $existingRoles = $userInfo->getRoles(); // Initialise set array with existing roles $setRoles = $existingRoles; // Storage array for roles to dump $removeRoles = []; // STEP 1: Check for roles to be removed in the existing set. // Roles that the current users isn't allowed to touch (hierarchy) will stay. foreach($setRoles as $role) { // Also prevent the main role from being removed. if($role->isDefault() || !$currentUser->hasAuthorityOver($role)) continue; if(!in_array($role->getId(), $applyRoles)) $removeRoles[] = $role; } // STEP 2: Purge the ones marked for removal. $setRoles = array_diff($setRoles, $removeRoles); // STEP 3: Add roles to the set array from the user input, if the user has authority over the given roles. foreach($applyRoles as $roleId) { try { $role = $existingRoles[$roleId] ?? UserRole::byId($roleId); } catch(UserRoleNotFoundException $ex) { continue; } if(!$currentUser->hasAuthorityOver($role)) continue; if(!in_array($role, $setRoles)) $setRoles[] = $role; } foreach($removeRoles as $role) $userInfo->removeRole($role); foreach($setRoles as $role) $userInfo->addRole($role); } if(!empty($_POST['user']) && is_array($_POST['user'])) { //$setUsername = (string)($_POST['user']['username'] ?? ''); //$setEMailAddress = (string)($_POST['user']['email'] ?? ''); $setCountry = (string)($_POST['user']['country'] ?? ''); $setTitle = (string)($_POST['user']['title'] ?? ''); $displayRole = (int)($_POST['user']['display_role'] ?? 0); try { $userInfo->setDisplayRole(UserRole::byId($displayRole)); } catch(UserRoleNotFoundException $ex) {} //$usernameValidation = User::validateUsername($setUsername); //$emailValidation = User::validateEMailAddress($setEMailAddress); $countryValidation = strlen($setCountry) === 2 && ctype_alpha($setCountry) && ctype_upper($setCountry); //if(!empty($usernameValidation)) // $notices[] = User::usernameValidationErrorString($usernameValidation); // if(!empty($emailValidation)) { // $notices[] = $emailValidation === 'in-use' // ? 'This e-mail address has already been used!' // : 'This e-mail address is invalid!'; // } if(!$countryValidation) $notices[] = 'Country code was invalid.'; if(strlen($setTitle) > 64) $notices[] = 'User title was invalid.'; if(empty($notices)) $userInfo // ->setUsername((string)($_POST['user']['username'] ?? '')) // ->setEMailAddress((string)($_POST['user']['email'] ?? '')) ->setCountry((string)($_POST['user']['country'] ?? '')) ->setTitle((string)($_POST['user']['title'] ?? '')) ->setDisplayRole(UserRole::byId((int)($_POST['user']['display_role'] ?? 0))); } if(!empty($_POST['colour']) && is_array($_POST['colour'])) { $setColour = null; if(!empty($_POST['colour']['enable'])) { $setColour = \Index\Colour\Colour::parse((string)($_POST['colour']['hex'] ?? '')); if($setColour->shouldInherit()) $notices[] = 'Invalid colour specified.'; } if(empty($notices)) $userInfo->setColour($setColour); } if(!empty($_POST['password']) && is_array($_POST['password'])) { $passwordNewValue = (string)($_POST['password']['new'] ?? ''); $passwordConfirmValue = (string)($_POST['password']['confirm'] ?? ''); if(!empty($passwordNewValue)) { if($passwordNewValue !== $passwordConfirmValue) $notices[] = 'Confirm password does not match.'; elseif(!empty(User::validatePassword($passwordNewValue))) $notices[] = 'New password is too weak.'; else $userInfo->setPassword($passwordNewValue); } } if(empty($notices)) $userInfo->save(); if($canEditPerms && !empty($_POST['perms']) && is_array($_POST['perms'])) { $perms = manage_perms_apply($permissions, $_POST['perms']); if($perms !== null) { if(!perms_set_user_raw($userId, $perms)) $notices[] = 'Failed to update permissions.'; } else { if(!perms_delete_user($userId)) $notices[] = 'Failed to remove permissions.'; } // this smells, make it refresh/apply in a non-retarded way $permissions = manage_perms_list(perms_get_user_raw($userId)); } } Template::render('manage.users.user', [ 'user_info' => $userInfo, 'manage_notices' => $notices, 'manage_roles' => UserRole::all(true), 'can_edit_user' => $canEdit, 'can_edit_perms' => $canEdit && $canEditPerms, 'permissions' => $permissions ?? [], ]);