Added hierarchy checks in important places, mostly closes #94.

This commit is contained in:
flash 2019-01-22 16:18:01 +01:00
parent b170ef315e
commit 6424f646e2
5 changed files with 58 additions and 8 deletions

View file

@ -100,7 +100,7 @@ switch ($_GET['v'] ?? null) {
$hasRoles = db_fetch_all($getHasRoles);
$getAvailableRoles = db_prepare('
SELECT `role_id`, `role_name`
SELECT `role_id`, `role_name`, `role_hierarchy`
FROM `msz_roles`
WHERE `role_id` NOT IN (
SELECT `role_id`
@ -121,6 +121,11 @@ switch ($_GET['v'] ?? null) {
break;
}
if (!user_check_authority(user_session_current('user_id'), $userId)) {
echo 'You are not allowed to administer this user.';
break;
}
if (!empty($_POST['user']) && is_array($_POST['user'])
&& user_validate_username($_POST['user']['username']) === ''
&& user_validate_email($_POST['user']['email']) === ''
@ -191,7 +196,7 @@ switch ($_GET['v'] ?? null) {
$updatePassword->execute();
}
if (isset($_POST['add_role'])) {
if (isset($_POST['add_role']) && user_role_check_authority(user_session_current('user_id'), (int)$_POST['add_role']['role'])) {
user_role_add($manageUser['user_id'], $_POST['add_role']['role']);
}
@ -202,7 +207,7 @@ switch ($_GET['v'] ?? null) {
break;
case 'remove':
if ((int)$_POST['manage_roles']['role'] !== MSZ_ROLE_MAIN) {
if ((int)$_POST['manage_roles']['role'] !== MSZ_ROLE_MAIN && user_role_check_authority(user_session_current('user_id'), (int)$_POST['manage_roles']['role'])) {
user_role_remove($manageUser['user_id'], $_POST['manage_roles']['role']);
}
break;
@ -309,6 +314,15 @@ switch ($_GET['v'] ?? null) {
break;
}
$roleHierarchy = (int)($_POST['role']['hierarchy'] ?? -1);
if ($roleId === null
? (user_get_hierarchy(user_session_current('user_id')) <= $roleHierarchy)
: !user_role_check_authority(user_session_current('user_id'), $roleId)) {
echo 'Your hierarchy is too low to do this.';
break;
}
if (!isset($_POST['role'])) {
echo 'no';
break;
@ -324,8 +338,6 @@ switch ($_GET['v'] ?? null) {
$roleSecret = !empty($_POST['role']['secret']);
$roleHierarchy = (int)($_POST['role']['hierarchy'] ?? -1);
if ($roleHierarchy < 1 || $roleHierarchy > 100) {
echo 'Invalid hierarchy value.';
break;

View file

@ -121,7 +121,7 @@ switch ($mode) {
$userPerms = perms_get_user(MSZ_PERMS_USER, user_session_current('user_id', 0));
$canManageWarnings = perms_check($userPerms, MSZ_PERM_USER_MANAGE_WARNINGS);
$canEdit = !$isRestricted && user_session_active() && (
$viewingOwnProfile || perms_check($userPerms, MSZ_PERM_USER_MANAGE_USERS)
$viewingOwnProfile || (perms_check($userPerms, MSZ_PERM_USER_MANAGE_USERS) && user_check_authority(user_session_current('user_id', 0), $userId))
);
$isEditing = $mode === 'edit';

View file

@ -135,3 +135,23 @@ function user_role_get(int $roleId): array
$getRole->bindValue('role_id', $roleId);
return db_fetch($getRole);
}
function user_role_check_authority(int $userId, int $roleId): bool
{
$checkHierarchy = db_prepare('
SELECT (
SELECT MAX(r.`role_hierarchy`)
FROM `msz_roles` AS r
LEFT JOIN `msz_user_roles` AS ur
ON ur.`role_id` = r.`role_id`
WHERE ur.`user_id` = :user_id
) > (
SELECT `role_hierarchy`
FROM `msz_roles`
WHERE `role_id` = :role_id
)
');
$checkHierarchy->bindValue('user_id', $userId);
$checkHierarchy->bindValue('role_id', $roleId);
return (bool)($checkHierarchy->execute() ? $checkHierarchy->fetchColumn() : false);
}

View file

@ -212,8 +212,12 @@ function user_get_last_ip(int $userId): string
return $getAddress->execute() ? $getAddress->fetchColumn() : '';
}
function user_check_authority(int $userId, int $subjectId): bool
function user_check_authority(int $userId, int $subjectId, bool $canManageSelf = true): bool
{
if ($canManageSelf && $userId === $subjectId) {
return true;
}
$checkHierarchy = db_prepare('
SELECT (
SELECT MAX(r.`role_hierarchy`)
@ -234,6 +238,19 @@ function user_check_authority(int $userId, int $subjectId): bool
return (bool)($checkHierarchy->execute() ? $checkHierarchy->fetchColumn() : false);
}
function user_get_hierarchy(int $userId): int
{
$getHierarchy = db_prepare('
SELECT MAX(r.`role_hierarchy`)
FROM `msz_roles` AS r
LEFT JOIN `msz_user_roles` AS ur
ON ur.`role_id` = r.`role_id`
WHERE ur.`user_id` = :user_id
');
$getHierarchy->bindValue('user_id', $userId);
return (int)($getHierarchy->execute() ? $getHierarchy->fetchColumn() : 0);
}
define('MSZ_E_USER_BIRTHDATE_OK', 0);
define('MSZ_E_USER_BIRTHDATE_USER', 1);
define('MSZ_E_USER_BIRTHDATE_DATE', 2);

View file

@ -9,7 +9,8 @@
{{ user_card(user, '?v=view&u=%d', '?v=role&r=%d', [
{
'href': '/profile.php?u=%d'|format(user.user_id),
'text': 'Profile',
'title': 'Profile',
'icon': 'fas fa-user',
}
]) }}
</div>