2022-09-13 13:14:49 +00:00
|
|
|
<?php
|
|
|
|
namespace Misuzu;
|
|
|
|
|
2023-07-22 15:02:41 +00:00
|
|
|
use RuntimeException;
|
2023-01-02 23:48:04 +00:00
|
|
|
use Index\Colour\Colour;
|
2023-08-30 22:37:21 +00:00
|
|
|
use Misuzu\Perm;
|
2023-08-03 01:35:08 +00:00
|
|
|
use Misuzu\Auth\AuthTokenCookie;
|
2022-09-13 13:14:49 +00:00
|
|
|
use Misuzu\Users\User;
|
|
|
|
|
2024-12-02 02:28:08 +00:00
|
|
|
if(!isset($msz) || !($msz instanceof \Misuzu\MisuzuContext))
|
|
|
|
die('Script must be called through the Misuzu route dispatcher.');
|
|
|
|
|
2024-11-30 04:09:29 +00:00
|
|
|
$viewerPerms = $msz->authInfo->getPerms('user');
|
|
|
|
if(!$msz->authInfo->isLoggedIn)
|
2023-08-31 15:59:53 +00:00
|
|
|
Template::throwError(403);
|
2022-09-13 13:14:49 +00:00
|
|
|
|
2024-11-30 04:09:29 +00:00
|
|
|
$currentUser = $msz->authInfo->userInfo;
|
2022-09-13 13:14:49 +00:00
|
|
|
|
2023-08-30 22:37:21 +00:00
|
|
|
$canManageUsers = $viewerPerms->check(Perm::U_USERS_MANAGE);
|
|
|
|
$canManagePerms = $viewerPerms->check(Perm::U_PERMS_MANAGE);
|
|
|
|
$canManageNotes = $viewerPerms->check(Perm::U_NOTES_MANAGE);
|
|
|
|
$canManageWarnings = $viewerPerms->check(Perm::U_WARNINGS_MANAGE);
|
|
|
|
$canManageBans = $viewerPerms->check(Perm::U_BANS_MANAGE);
|
|
|
|
$canImpersonate = $viewerPerms->check(Perm::U_CAN_IMPERSONATE);
|
2024-11-30 04:09:29 +00:00
|
|
|
$canSendTestMail = $currentUser->super;
|
2023-07-26 18:19:46 +00:00
|
|
|
$hasAccess = $canManageUsers || $canManageNotes || $canManageWarnings || $canManageBans;
|
2023-07-25 14:52:51 +00:00
|
|
|
|
2023-08-31 15:59:53 +00:00
|
|
|
if(!$hasAccess)
|
|
|
|
Template::throwError(403);
|
2023-07-25 14:52:51 +00:00
|
|
|
|
|
|
|
$notices = [];
|
2024-12-02 02:28:08 +00:00
|
|
|
$userId = (string)filter_input(INPUT_GET, 'u', FILTER_SANITIZE_NUMBER_INT);
|
2023-07-25 14:52:51 +00:00
|
|
|
|
2022-09-13 13:14:49 +00:00
|
|
|
try {
|
2024-11-30 04:09:29 +00:00
|
|
|
$userInfo = $msz->usersCtx->users->getUser($userId, 'id');
|
2023-07-22 15:02:41 +00:00
|
|
|
} catch(RuntimeException $ex) {
|
2023-08-31 15:59:53 +00:00
|
|
|
Template::throwError(404);
|
2022-09-13 13:14:49 +00:00
|
|
|
}
|
|
|
|
|
2024-11-30 04:09:29 +00:00
|
|
|
$currentUserRank = $msz->usersCtx->users->getUserRank($currentUser);
|
|
|
|
$userRank = $msz->usersCtx->users->getUserRank($userInfo);
|
2023-08-02 22:12:47 +00:00
|
|
|
|
2024-11-30 04:20:20 +00:00
|
|
|
$canEdit = $canManageUsers && ($currentUser->super || (string)$currentUser->id === $userInfo->id || $currentUserRank > $userRank);
|
2023-07-25 14:52:51 +00:00
|
|
|
$canEditPerms = $canEdit && $canManagePerms;
|
2023-08-30 22:37:21 +00:00
|
|
|
|
2024-11-30 04:09:29 +00:00
|
|
|
$permsInfos = $msz->perms->getPermissionInfo(userInfo: $userInfo, categoryNames: Perm::INFO_FOR_USER);
|
2023-08-30 22:37:21 +00:00
|
|
|
$permsLists = Perm::createList(Perm::LISTS_FOR_USER);
|
2023-08-30 23:56:30 +00:00
|
|
|
$permsNeedRecalc = false;
|
2022-09-13 13:14:49 +00:00
|
|
|
|
|
|
|
if(CSRF::validateRequest() && $canEdit) {
|
2023-05-21 18:15:04 +00:00
|
|
|
if(!empty($_POST['impersonate_user'])) {
|
2023-07-28 21:20:19 +00:00
|
|
|
if(!$canImpersonate) {
|
2023-05-21 18:15:04 +00:00
|
|
|
$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 {
|
2024-11-30 04:09:29 +00:00
|
|
|
$allowToImpersonate = $currentUser->super;
|
2023-07-28 21:20:19 +00:00
|
|
|
|
|
|
|
if(!$allowToImpersonate) {
|
2024-11-30 04:20:20 +00:00
|
|
|
$allowImpersonateUsers = $msz->config->getArray(sprintf('impersonate.allow.u%s', $currentUser->id));
|
|
|
|
$allowToImpersonate = in_array($userInfo->id, $allowImpersonateUsers, true);
|
2023-07-28 21:20:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if($allowToImpersonate) {
|
2024-11-30 04:20:20 +00:00
|
|
|
$msz->createAuditLog('USER_IMPERSONATE', [$userInfo->id, $userInfo->name]);
|
2023-08-03 01:35:08 +00:00
|
|
|
|
2024-11-30 04:09:29 +00:00
|
|
|
$tokenBuilder = $msz->authInfo->tokenInfo->toBuilder();
|
2024-11-30 04:20:20 +00:00
|
|
|
$tokenBuilder->setImpersonatedUserId($userInfo->id);
|
2023-08-03 01:35:08 +00:00
|
|
|
$tokenInfo = $tokenBuilder->toInfo();
|
|
|
|
|
2024-12-02 02:28:08 +00:00
|
|
|
AuthTokenCookie::apply($msz->authCtx->createAuthTokenPacker()->pack($tokenInfo));
|
2024-11-30 04:09:29 +00:00
|
|
|
Tools::redirect($msz->urls->format('index'));
|
2023-07-28 21:20:19 +00:00
|
|
|
return;
|
|
|
|
} else $notices[] = 'You aren\'t allowed to impersonate this user.';
|
2023-05-21 18:15:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-13 13:14:49 +00:00
|
|
|
if(!empty($_POST['send_test_email'])) {
|
2023-08-02 22:12:47 +00:00
|
|
|
if(!$canSendTestMail) {
|
2022-09-13 13:14:49 +00:00
|
|
|
$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(
|
2024-11-30 04:09:29 +00:00
|
|
|
[$userInfo->emailAddress => $userInfo->name],
|
2022-09-13 13:14:49 +00:00
|
|
|
'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.';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-05 01:33:12 +00:00
|
|
|
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.');
|
2023-07-27 23:26:05 +00:00
|
|
|
$applyRoles[] = (string)$item;
|
2023-07-05 01:33:12 +00:00
|
|
|
}
|
|
|
|
|
2023-07-27 23:26:05 +00:00
|
|
|
$existingRoles = [];
|
2024-11-30 04:09:29 +00:00
|
|
|
foreach(iterator_to_array($msz->usersCtx->roles->getRoles(userInfo: $userInfo)) as $roleInfo)
|
|
|
|
$existingRoles[$roleInfo->id] = $roleInfo;
|
2022-09-13 13:14:49 +00:00
|
|
|
|
|
|
|
$removeRoles = [];
|
|
|
|
|
2023-07-27 23:26:05 +00:00
|
|
|
foreach($existingRoles as $roleInfo) {
|
2024-11-30 04:09:29 +00:00
|
|
|
if($roleInfo->default || !($currentUser->super || $userRank > $roleInfo->rank))
|
2022-09-13 13:14:49 +00:00
|
|
|
continue;
|
2023-07-27 23:26:05 +00:00
|
|
|
|
2024-11-30 04:20:20 +00:00
|
|
|
if(!in_array($roleInfo->id, $applyRoles))
|
2023-07-27 23:26:05 +00:00
|
|
|
$removeRoles[] = $roleInfo;
|
2022-09-13 13:14:49 +00:00
|
|
|
}
|
|
|
|
|
2023-07-27 23:26:05 +00:00
|
|
|
if(!empty($removeRoles))
|
2024-11-30 04:09:29 +00:00
|
|
|
$msz->usersCtx->users->removeRoles($userInfo, $removeRoles);
|
2023-07-27 23:26:05 +00:00
|
|
|
|
|
|
|
$addRoles = [];
|
2022-09-13 13:14:49 +00:00
|
|
|
|
|
|
|
foreach($applyRoles as $roleId) {
|
|
|
|
try {
|
2024-11-30 04:09:29 +00:00
|
|
|
$roleInfo = $existingRoles[$roleId] ?? $msz->usersCtx->roles->getRole($roleId);
|
2023-07-22 15:02:41 +00:00
|
|
|
} catch(RuntimeException $ex) {
|
2022-09-13 13:14:49 +00:00
|
|
|
continue;
|
|
|
|
}
|
2023-07-27 23:26:05 +00:00
|
|
|
|
2024-11-30 04:09:29 +00:00
|
|
|
if(!$currentUser->super && $userRank <= $roleInfo->rank)
|
2022-09-13 13:14:49 +00:00
|
|
|
continue;
|
|
|
|
|
2023-07-27 23:26:05 +00:00
|
|
|
if(!in_array($roleInfo, $existingRoles))
|
|
|
|
$addRoles[] = $roleInfo;
|
|
|
|
}
|
2022-09-13 13:14:49 +00:00
|
|
|
|
2023-07-27 23:26:05 +00:00
|
|
|
if(!empty($addRoles))
|
2024-11-30 04:09:29 +00:00
|
|
|
$msz->usersCtx->users->addRoles($userInfo, $addRoles);
|
2023-08-30 22:37:21 +00:00
|
|
|
|
|
|
|
if(!empty($addRoles) || !empty($removeRoles))
|
2023-08-30 23:56:30 +00:00
|
|
|
$permsNeedRecalc = true;
|
2022-09-13 13:14:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!empty($_POST['user']) && is_array($_POST['user'])) {
|
2023-08-30 22:37:21 +00:00
|
|
|
$setCountry = (string)($_POST['user']['country'] ?? '');
|
|
|
|
$setTitle = (string)($_POST['user']['title'] ?? '');
|
2022-09-13 13:14:49 +00:00
|
|
|
|
2023-07-27 23:26:05 +00:00
|
|
|
$displayRole = (string)($_POST['user']['display_role'] ?? 0);
|
2024-11-30 04:09:29 +00:00
|
|
|
if(!$msz->usersCtx->users->hasRole($userInfo, $displayRole))
|
2023-07-27 23:26:05 +00:00
|
|
|
$notices[] = 'User does not have the role you\'re trying to assign as primary.';
|
2022-09-13 13:14:49 +00:00
|
|
|
|
|
|
|
$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.';
|
|
|
|
|
2023-07-27 23:26:05 +00:00
|
|
|
if(empty($notices)) {
|
2024-11-30 04:09:29 +00:00
|
|
|
$msz->usersCtx->users->updateUser(
|
2023-07-27 23:26:05 +00:00
|
|
|
userInfo: $userInfo,
|
|
|
|
displayRoleInfo: $displayRole,
|
2023-08-02 22:12:47 +00:00
|
|
|
countryCode: (string)($_POST['user']['country'] ?? 'XX'),
|
|
|
|
title: (string)($_POST['user']['title'] ?? '')
|
2023-07-27 23:26:05 +00:00
|
|
|
);
|
|
|
|
}
|
2022-09-13 13:14:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!empty($_POST['colour']) && is_array($_POST['colour'])) {
|
|
|
|
$setColour = null;
|
|
|
|
|
2023-01-02 23:48:04 +00:00
|
|
|
if(!empty($_POST['colour']['enable'])) {
|
|
|
|
$setColour = \Index\Colour\Colour::parse((string)($_POST['colour']['hex'] ?? ''));
|
|
|
|
if($setColour->shouldInherit())
|
|
|
|
$notices[] = 'Invalid colour specified.';
|
|
|
|
}
|
2022-09-13 13:14:49 +00:00
|
|
|
|
|
|
|
if(empty($notices))
|
2024-11-30 04:09:29 +00:00
|
|
|
$msz->usersCtx->users->updateUser(userInfo: $userInfo, colour: $setColour);
|
2022-09-13 13:14:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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.';
|
2023-08-30 23:41:44 +00:00
|
|
|
else {
|
2024-11-30 04:09:29 +00:00
|
|
|
$passwordValidation = $msz->usersCtx->users->validatePassword($passwordNewValue);
|
2023-08-30 23:41:44 +00:00
|
|
|
if($passwordValidation !== '')
|
2024-11-30 04:09:29 +00:00
|
|
|
$notices[] = $msz->usersCtx->users->validatePasswordText($passwordValidation);
|
2023-08-30 23:41:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(empty($notices))
|
2024-11-30 04:09:29 +00:00
|
|
|
$msz->usersCtx->users->updateUser(userInfo: $userInfo, password: $passwordNewValue);
|
2022-09-13 13:14:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-30 22:37:21 +00:00
|
|
|
if($canEditPerms && filter_has_var(INPUT_POST, 'perms')) {
|
|
|
|
$permsApply = Perm::convertSubmission(
|
|
|
|
filter_input(INPUT_POST, 'perms', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY),
|
|
|
|
Perm::INFO_FOR_USER
|
|
|
|
);
|
2022-09-13 13:14:49 +00:00
|
|
|
|
2023-08-30 22:37:21 +00:00
|
|
|
foreach($permsApply as $categoryName => $values)
|
2024-11-30 04:09:29 +00:00
|
|
|
$msz->perms->setPermissions($categoryName, $values['allow'], $values['deny'], userInfo: $userInfo);
|
2022-09-13 13:14:49 +00:00
|
|
|
|
2023-08-30 23:56:30 +00:00
|
|
|
$permsNeedRecalc = true;
|
2022-09-13 13:14:49 +00:00
|
|
|
}
|
2023-08-02 22:12:47 +00:00
|
|
|
|
2023-08-30 23:56:30 +00:00
|
|
|
if($permsNeedRecalc)
|
2024-11-30 04:09:29 +00:00
|
|
|
$msz->perms->precalculatePermissions(
|
|
|
|
$msz->forumCtx->categories,
|
2024-11-30 04:20:20 +00:00
|
|
|
[$userInfo->id]
|
2023-09-08 13:22:46 +00:00
|
|
|
);
|
2023-08-30 23:56:30 +00:00
|
|
|
|
2024-11-30 04:20:20 +00:00
|
|
|
Tools::redirect($msz->urls->format('manage-user', ['user' => $userInfo->id]));
|
2023-08-02 22:12:47 +00:00
|
|
|
return;
|
2022-09-13 13:14:49 +00:00
|
|
|
}
|
|
|
|
|
2024-11-30 04:09:29 +00:00
|
|
|
$rolesAll = iterator_to_array($msz->usersCtx->roles->getRoles());
|
|
|
|
$userRoleIds = $msz->usersCtx->users->hasRoles($userInfo, $rolesAll);
|
2023-07-27 23:26:05 +00:00
|
|
|
|
2022-09-13 13:14:49 +00:00
|
|
|
Template::render('manage.users.user', [
|
|
|
|
'user_info' => $userInfo,
|
|
|
|
'manage_notices' => $notices,
|
2023-07-27 23:26:05 +00:00
|
|
|
'manage_roles' => $rolesAll,
|
|
|
|
'manage_user_has_roles' => $userRoleIds,
|
2022-09-13 13:14:49 +00:00
|
|
|
'can_edit_user' => $canEdit,
|
|
|
|
'can_edit_perms' => $canEdit && $canEditPerms,
|
2023-07-25 14:40:31 +00:00
|
|
|
'can_manage_notes' => $canManageNotes,
|
2023-07-26 18:19:46 +00:00
|
|
|
'can_manage_warnings' => $canManageWarnings,
|
|
|
|
'can_manage_bans' => $canManageBans,
|
2023-07-28 21:20:19 +00:00
|
|
|
'can_impersonate' => $canImpersonate,
|
2023-08-02 22:12:47 +00:00
|
|
|
'can_send_test_mail' => $canSendTestMail,
|
2023-08-30 22:37:21 +00:00
|
|
|
'perms_lists' => $permsLists,
|
|
|
|
'perms_infos' => $permsInfos,
|
2022-09-13 13:14:49 +00:00
|
|
|
]);
|