Allow non-super users to impersonate select users.

This commit is contained in:
Pachira 2023-07-28 21:20:19 +00:00
parent a22433f7dd
commit 8ef113f3a9
5 changed files with 47 additions and 14 deletions

View file

@ -21,6 +21,7 @@ $canManagePerms = perms_check_user(MSZ_PERMS_USER, $currentUserId, MSZ_PERM_USER
$canManageNotes = perms_check_user(MSZ_PERMS_USER, $currentUserId, MSZ_PERM_USER_MANAGE_NOTES);
$canManageWarnings = perms_check_user(MSZ_PERMS_USER, $currentUserId, MSZ_PERM_USER_MANAGE_WARNINGS);
$canManageBans = perms_check_user(MSZ_PERMS_USER, $currentUserId, MSZ_PERM_USER_MANAGE_BANS);
$canImpersonate = perms_check_user(MSZ_PERMS_USER, $currentUserId, MSZ_PERM_USER_IMPERSONATE);
$hasAccess = $canManageUsers || $canManageNotes || $canManageWarnings || $canManageBans;
if(!$hasAccess) {
@ -44,15 +45,24 @@ $permissions = $canEditPerms ? manage_perms_list(perms_get_user_raw($userId)) :
if(CSRF::validateRequest() && $canEdit) {
if(!empty($_POST['impersonate_user'])) {
if(!$currentUser->isSuper()) {
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 {
$authToken->setImpersonatedUserId($userInfo->getId());
$authToken->applyCookie();
url_redirect('index');
return;
$allowToImpersonate = $currentUser->isSuper();
if(!$allowToImpersonate) {
$allowImpersonateUsers = $msz->getConfig()->getArray(sprintf('impersonate.allow.u%s', $currentUser->getId()));
$allowToImpersonate = in_array((string)$userInfo->getId(), $allowImpersonateUsers, true);
}
if($allowToImpersonate) {
$authToken->setImpersonatedUserId($userInfo->getId());
$authToken->applyCookie();
url_redirect('index');
return;
} else $notices[] = 'You aren\'t allowed to impersonate this user.';
}
}
@ -207,5 +217,6 @@ Template::render('manage.users.user', [
'can_manage_notes' => $canManageNotes,
'can_manage_warnings' => $canManageWarnings,
'can_manage_bans' => $canManageBans,
'can_impersonate' => $canImpersonate,
'permissions' => $permissions ?? [],
]);

View file

@ -112,19 +112,33 @@ if($authToken->isValid()) {
if($sessionInfo->shouldBumpExpires())
$authToken->applyCookie($sessionInfo->getExpiresTime());
// only allow impersonation when super user
if($authToken->hasImpersonatedUserId() && $userInfo->isSuper()) {
$userInfoReal = $userInfo;
if($authToken->hasImpersonatedUserId()) {
$allowToImpersonate = $userInfo->isSuper();
$impersonatedUserId = $authToken->getImpersonatedUserId();
try {
$userInfo = User::byId($authToken->getImpersonatedUserId());
} catch(RuntimeException $ex) {
$userInfo = $userInfoReal;
if(!$allowToImpersonate) {
$allowImpersonateUsers = $cfg->getArray(sprintf('impersonate.allow.u%s', $userInfo->getId()));
$allowToImpersonate = in_array((string)$impersonatedUserId, $allowImpersonateUsers, true);
}
$removeImpersonationData = !$allowToImpersonate;
if($allowToImpersonate) {
$userInfoReal = $userInfo;
try {
$userInfo = User::byId($impersonatedUserId);
} catch(RuntimeException $ex) {
$userInfo = $userInfoReal;
$removeImpersonationData = true;
}
$userInfo->setCurrent();
}
if($removeImpersonationData) {
$authToken->removeImpersonatedUserId();
$authToken->applyCookie();
}
$userInfo->setCurrent();
}
}
}

View file

@ -211,6 +211,11 @@ function manage_perms_list(array $rawPerms): array {
'title' => 'Can manage user bans.',
'perm' => MSZ_PERM_USER_MANAGE_BANS,
],
[
'section' => 'impersonate',
'title' => 'Can impersonate select users.',
'perm' => MSZ_PERM_USER_IMPERSONATE,
],
],
],
[

View file

@ -23,6 +23,7 @@ define('MSZ_PERM_USER_MANAGE_WARNINGS', 0x01000000);
//define('MSZ_PERM_USER_MANAGE_BLACKLISTS', 0x02000000); // Replaced with MSZ_PERM_GENERAL_MANAGE_BLACKLIST
define('MSZ_PERM_USER_MANAGE_NOTES', 0x04000000);
define('MSZ_PERM_USER_MANAGE_BANS', 0x08000000);
define('MSZ_PERM_USER_IMPERSONATE', 0x10000000);
define('MSZ_PERMS_CHANGELOG', 'changelog');
define('MSZ_PERM_CHANGELOG_MANAGE_CHANGES', 0x00000001);

View file

@ -164,7 +164,9 @@
<button class="input__button manage__user__button">Send</button>
</div>
</form>
{% endif %}
{% if can_impersonate %}
<form method="post" action="{{ url('manage-user', {'user': user_info.id}) }}" class="container manage__user__container">
{{ container_title('Impersonate ' ~ user_info.username ~ ' (' ~ user_info.id ~ ')') }}