misuzu/public-legacy/manage/users/user.php
flash 00d1d2922d Changed the way msz_auth is handled.
Going forward msz_auth is always assumed to be present, even while the user is not logged in.
If the cookie is not present a default, empty value will be used.
The msz_uid and msz_sid cookies are also still upconverted for some reason but are no longer removed even though there's no active sessions that can possibly have those anymore.
As with the previous change, shit may be broken so report any Anomalies you come across, through flashii-issues@flash.moe if necessary.
2023-08-03 01:35:08 +00:00

232 lines
8.4 KiB
PHP

<?php
namespace Misuzu;
use RuntimeException;
use Index\Colour\Colour;
use Misuzu\Auth\AuthTokenCookie;
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()]);
$tokenBuilder = $msz->getAuthInfo()->getTokenInfo()->toBuilder();
$tokenBuilder->setImpersonatedUserId($userInfo->getId());
$tokenInfo = $tokenBuilder->toInfo();
AuthTokenCookie::apply($tokenPacker->pack($tokenInfo));
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 ?? [],
]);