diff --git a/public-legacy/manage/users/user.php b/public-legacy/manage/users/user.php index 23cea50..38f7a44 100644 --- a/public-legacy/manage/users/user.php +++ b/public-legacy/manage/users/user.php @@ -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 ?? [], ]); diff --git a/public/index.php b/public/index.php index 7a0dc78..020e765 100644 --- a/public/index.php +++ b/public/index.php @@ -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(); } } } diff --git a/src/manage.php b/src/manage.php index a2e1340..63632f7 100644 --- a/src/manage.php +++ b/src/manage.php @@ -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, + ], ], ], [ diff --git a/src/perms.php b/src/perms.php index e5ab6de..5388131 100644 --- a/src/perms.php +++ b/src/perms.php @@ -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); diff --git a/templates/manage/users/user.twig b/templates/manage/users/user.twig index ced3b81..a0ecb41 100644 --- a/templates/manage/users/user.twig +++ b/templates/manage/users/user.twig @@ -164,7 +164,9 @@ + {% endif %} + {% if can_impersonate %}
{{ container_title('Impersonate ' ~ user_info.username ~ ' (' ~ user_info.id ~ ')') }}