misuzu/public-legacy/manage/users/user.php
flash 383e2ed0e0 Rewrote the user information class.
This one took multiple days and it pretty invasive into the core of Misuzu so issue might (will) arise, there's also some features that have gone temporarily missing in the mean time and some inefficiencies introduced that will be fixed again at a later time.
The old class isn't gone entirely because I still have to figure out what I'm gonna do about validation, but for the most part this knocks out one of the "layers of backwards compatibility", as I've been referring to it, and is moving us closer to a future where Flashii actually gets real updates.
If you run into anything that's broken and you're inhibited from reporting it through the forum, do it through chat or mail me at flashii-issues@flash.moe.
2023-08-02 22:12:47 +00:00

227 lines
8.2 KiB
PHP

<?php
namespace Misuzu;
use RuntimeException;
use Index\Colour\Colour;
use Misuzu\Users\User;
if(!$msz->isLoggedIn()) {
echo render_error(403);
return;
}
$users = $msz->getUsers();
$roles = $msz->getRoles();
$currentUser = $msz->getActiveUser();
$canManageUsers = perms_check_user(MSZ_PERMS_USER, $currentUser->getId(), MSZ_PERM_USER_MANAGE_USERS);
$canManagePerms = perms_check_user(MSZ_PERMS_USER, $currentUser->getId(), MSZ_PERM_USER_MANAGE_PERMS);
$canManageNotes = perms_check_user(MSZ_PERMS_USER, $currentUser->getId(), MSZ_PERM_USER_MANAGE_NOTES);
$canManageWarnings = perms_check_user(MSZ_PERMS_USER, $currentUser->getId(), MSZ_PERM_USER_MANAGE_WARNINGS);
$canManageBans = perms_check_user(MSZ_PERMS_USER, $currentUser->getId(), MSZ_PERM_USER_MANAGE_BANS);
$canImpersonate = perms_check_user(MSZ_PERMS_USER, $currentUser->getId(), MSZ_PERM_USER_IMPERSONATE);
$canSendTestMail = $currentUser->isSuperUser();
$hasAccess = $canManageUsers || $canManageNotes || $canManageWarnings || $canManageBans;
if(!$hasAccess) {
echo render_error(403);
return;
}
$notices = [];
$userId = (int)filter_input(INPUT_GET, 'u', FILTER_SANITIZE_NUMBER_INT);
try {
$userInfo = $users->getUser($userId, 'id');
} catch(RuntimeException $ex) {
echo render_error(404);
return;
}
$currentUserRank = $users->getUserRank($currentUser);
$userRank = $users->getUserRank($userInfo);
$canEdit = $canManageUsers && ($currentUser->isSuperUser() || (string)$currentUser->getId() === $userInfo->getId() || $currentUserRank > $userRank);
$canEditPerms = $canEdit && $canManagePerms;
$permissions = $canEditPerms ? manage_perms_list(perms_get_user_raw($userId)) : [];
if(CSRF::validateRequest() && $canEdit) {
if(!empty($_POST['impersonate_user'])) {
if(!$canImpersonate) {
$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 {
$allowToImpersonate = $currentUser->isSuperUser();
if(!$allowToImpersonate) {
$allowImpersonateUsers = $msz->getConfig()->getArray(sprintf('impersonate.allow.u%s', $currentUser->getId()));
$allowToImpersonate = in_array($userInfo->getId(), $allowImpersonateUsers, true);
}
if($allowToImpersonate) {
$msz->createAuditLog('USER_IMPERSONATE', [$userInfo->getId(), $userInfo->getName()]);
$authToken->setImpersonatedUserId($userInfo->getId());
$authToken->applyCookie();
url_redirect('index');
return;
} else $notices[] = 'You aren\'t allowed to impersonate this user.';
}
}
if(!empty($_POST['send_test_email'])) {
if(!$canSendTestMail) {
$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->getName()],
'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[] = (string)$item;
}
$existingRoles = [];
foreach($roles->getRoles(userInfo: $userInfo) as $roleInfo)
$existingRoles[$roleInfo->getId()] = $roleInfo;
$removeRoles = [];
foreach($existingRoles as $roleInfo) {
if($roleInfo->isDefault() || !($currentUser->isSuperUser() || $userRank > $roleInfo->getRank()))
continue;
if(!in_array($roleInfo->getId(), $applyRoles))
$removeRoles[] = $roleInfo;
}
if(!empty($removeRoles))
$users->removeRoles($userInfo, $removeRoles);
$addRoles = [];
foreach($applyRoles as $roleId) {
try {
$roleInfo = $existingRoles[$roleId] ?? $roles->getRole($roleId);
} catch(RuntimeException $ex) {
continue;
}
if(!$currentUser->isSuperUser() && $userRank <= $roleInfo->getRank())
continue;
if(!in_array($roleInfo, $existingRoles))
$addRoles[] = $roleInfo;
}
if(!empty($addRoles))
$users->addRoles($userInfo, $addRoles);
}
if(!empty($_POST['user']) && is_array($_POST['user'])) {
$setCountry = (string)($_POST['user']['country'] ?? '');
$setTitle = (string)($_POST['user']['title'] ?? '');
$displayRole = (string)($_POST['user']['display_role'] ?? 0);
if(!$users->hasRole($userInfo, $displayRole))
$notices[] = 'User does not have the role you\'re trying to assign as primary.';
$countryValidation = strlen($setCountry) === 2
&& ctype_alpha($setCountry)
&& ctype_upper($setCountry);
if(!$countryValidation)
$notices[] = 'Country code was invalid.';
if(strlen($setTitle) > 64)
$notices[] = 'User title was invalid.';
if(empty($notices)) {
$users->updateUser(
userInfo: $userInfo,
displayRoleInfo: $displayRole,
countryCode: (string)($_POST['user']['country'] ?? 'XX'),
title: (string)($_POST['user']['title'] ?? '')
);
}
}
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))
$users->updateUser(userInfo: $userInfo, colour: $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
$users->updateUser(userInfo: $userInfo, password: $passwordNewValue);
}
}
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));
}
url_redirect('manage-user', ['user' => $userInfo->getId()]);
return;
}
$rolesAll = $roles->getRoles();
$userRoleIds = $users->hasRoles($userInfo, $rolesAll);
Template::render('manage.users.user', [
'user_info' => $userInfo,
'manage_notices' => $notices,
'manage_roles' => $rolesAll,
'manage_user_has_roles' => $userRoleIds,
'can_edit_user' => $canEdit,
'can_edit_perms' => $canEdit && $canEditPerms,
'can_manage_notes' => $canManageNotes,
'can_manage_warnings' => $canManageWarnings,
'can_manage_bans' => $canManageBans,
'can_impersonate' => $canImpersonate,
'can_send_test_mail' => $canSendTestMail,
'permissions' => $permissions ?? [],
]);