misuzu/public/manage/users.php

465 lines
16 KiB
PHP
Raw Normal View History

<?php
require_once '../../misuzu.php';
$userPerms = perms_get_user(MSZ_PERMS_USER, user_session_current('user_id', 0));
2018-05-27 00:20:35 +00:00
$isPostRequest = $_SERVER['REQUEST_METHOD'] === 'POST';
2018-05-16 21:06:14 +00:00
$queryQffset = (int)($_GET['o'] ?? 0);
2018-08-15 01:12:58 +00:00
tpl_vars([
'can_manage_users' => $canManageUsers = perms_check($userPerms, MSZ_PERM_USER_MANAGE_USERS),
'can_manage_roles' => $canManageRoles = perms_check($userPerms, MSZ_PERM_USER_MANAGE_ROLES),
'can_manage_perms' => $canManagePerms = perms_check($userPerms, MSZ_PERM_USER_MANAGE_PERMS),
2018-07-08 19:24:59 +00:00
]);
switch ($_GET['v'] ?? null) {
default:
case 'listing':
2018-07-08 19:24:59 +00:00
if (!$canManageUsers && !$canManagePerms) {
2018-07-07 23:24:34 +00:00
echo render_error(403);
break;
}
2018-05-16 21:06:14 +00:00
$usersTake = 30;
$manageUsersCount = db_query('
2018-05-16 21:06:14 +00:00
SELECT COUNT(`user_id`)
FROM `msz_users`
')->fetchColumn();
$getManageUsers = db_prepare('
2018-05-16 02:58:21 +00:00
SELECT
u.`user_id`, u.`username`, u.`user_country`, r.`role_id`,
COALESCE(u.`user_title`, r.`role_title`, r.`role_name`) as `user_title`,
COALESCE(u.`user_colour`, r.`role_colour`) as `user_colour`
2018-05-16 02:58:21 +00:00
FROM `msz_users` as u
LEFT JOIN `msz_roles` as r
ON u.`display_role` = r.`role_id`
2018-07-07 23:24:34 +00:00
ORDER BY `user_id`
2018-05-16 21:06:14 +00:00
LIMIT :offset, :take
');
$getManageUsers->bindValue('offset', $queryQffset);
$getManageUsers->bindValue('take', $usersTake);
$manageUsers = $getManageUsers->execute() ? $getManageUsers->fetchAll() : [];
2018-05-16 02:58:21 +00:00
2018-08-15 01:12:58 +00:00
tpl_vars([
2018-05-16 21:06:14 +00:00
'manage_users' => $manageUsers,
'manage_users_count' => $manageUsersCount,
'manage_users_range' => $usersTake,
'manage_users_offset' => $queryQffset,
]);
echo tpl_render('manage.users.users');
break;
case 'view':
2018-07-08 19:24:59 +00:00
if (!$canManageUsers && !$canManagePerms) {
2018-07-07 23:24:34 +00:00
echo render_error(403);
break;
}
2018-05-27 00:20:35 +00:00
$userId = $_GET['u'] ?? null;
2018-05-27 00:20:35 +00:00
if ($userId === null || ($userId = (int)$userId) < 1) {
echo 'no';
break;
}
$getUser = db_prepare('
2018-05-16 02:58:21 +00:00
SELECT
u.*,
INET6_NTOA(u.`register_ip`) as `register_ip_decoded`,
INET6_NTOA(u.`last_ip`) as `last_ip_decoded`,
COALESCE(u.`user_colour`, r.`role_colour`) as `colour`
2018-05-16 02:58:21 +00:00
FROM `msz_users` as u
LEFT JOIN `msz_roles` as r
ON u.`display_role` = r.`role_id`
WHERE `user_id` = :user_id
2018-05-27 23:24:16 +00:00
ORDER BY `user_id`
2018-05-16 02:58:21 +00:00
');
2018-05-27 00:20:35 +00:00
$getUser->bindValue('user_id', $userId);
2018-05-16 02:58:21 +00:00
$getUser->execute();
$manageUser = $getUser->execute() ? $getUser->fetch() : [];
if (!$manageUser) {
echo 'Could not find that user.';
break;
}
$getHasRoles = db_prepare('
2018-05-27 01:59:57 +00:00
SELECT `role_id`, `role_name`
FROM `msz_roles`
WHERE `role_id` IN (
SELECT `role_id`
FROM `msz_user_roles`
WHERE `user_id` = :user_id
)
');
$getHasRoles->bindValue('user_id', $manageUser['user_id']);
$hasRoles = $getHasRoles->execute() ? $getHasRoles->fetchAll() : [];
$getAvailableRoles = db_prepare('
2018-05-27 01:59:57 +00:00
SELECT `role_id`, `role_name`
FROM `msz_roles`
WHERE `role_id` NOT IN (
SELECT `role_id`
FROM `msz_user_roles`
WHERE `user_id` = :user_id
)
');
$getAvailableRoles->bindValue('user_id', $manageUser['user_id']);
$availableRoles = $getAvailableRoles->execute() ? $getAvailableRoles->fetchAll() : [];
2018-07-08 19:24:59 +00:00
if ($canManagePerms) {
2018-08-15 01:12:58 +00:00
tpl_var('permissions', $permissions = manage_perms_list(perms_get_user_raw($userId)));
2018-07-08 19:24:59 +00:00
}
2018-05-27 01:59:57 +00:00
if ($isPostRequest) {
2018-10-02 19:16:42 +00:00
if (!csrf_verify('users_edit', $_POST['csrf'] ?? '')) {
2018-05-27 01:59:57 +00:00
echo 'csrf err';
break;
}
2018-07-08 19:24:59 +00:00
if (!empty($_POST['user']) && is_array($_POST['user'])
&& user_validate_username($_POST['user']['username']) === ''
2018-07-11 20:03:43 +00:00
&& user_validate_email($_POST['user']['email']) === ''
&& strlen($_POST['user']['country']) === 2) {
$updateUserDetails = db_prepare('
2018-07-08 19:24:59 +00:00
UPDATE `msz_users`
SET `username` = :username,
`email` = LOWER(:email),
2018-07-11 20:03:43 +00:00
`user_title` = :title,
`user_country` = :country
2018-07-08 19:24:59 +00:00
WHERE `user_id` = :user_id
');
$updateUserDetails->bindValue('username', $_POST['user']['username']);
$updateUserDetails->bindValue('email', $_POST['user']['email']);
2018-07-11 20:03:43 +00:00
$updateUserDetails->bindValue('country', $_POST['user']['country']);
2018-07-08 19:24:59 +00:00
$updateUserDetails->bindValue(
'title',
strlen($_POST['user']['title'])
? $_POST['user']['title']
: null
);
$updateUserDetails->bindValue('user_id', $userId);
$updateUserDetails->execute();
}
2018-05-27 01:59:57 +00:00
if (!empty($_POST['colour']) && is_array($_POST['colour'])) {
$userColour = null;
if (!empty($_POST['colour']['enable'])) {
$userColour = colour_create();
foreach (['red', 'green', 'blue'] as $key) {
$value = (int)($_POST['colour'][$key] ?? -1);
$func = 'colour_set_' . ucfirst($key);
if ($value < 0 || $value > 0xFF) {
echo 'invalid colour value';
break 2;
}
$func($userColour, $value);
}
}
$updateUserColour = db_prepare('
UPDATE `msz_users`
SET `user_colour` = :colour
WHERE `user_id` = :user_id
');
$updateUserColour->bindValue('colour', $userColour);
$updateUserColour->bindValue('user_id', $userId);
$updateUserColour->execute();
}
2018-07-08 19:24:59 +00:00
if (!empty($_POST['password'])
&& is_array($_POST['password'])
&& !empty($_POST['password']['new'])
&& !empty($_POST['password']['confirm'])
&& user_validate_password($_POST['password']['new']) === ''
&& $_POST['password']['new'] === $_POST['password']['confirm']) {
$updatePassword = db_prepare('
2018-07-08 19:24:59 +00:00
UPDATE `msz_users`
SET `password` = :password
WHERE `user_id` = :user_id
');
$updatePassword->bindValue('password', user_password_hash($_POST['password']['new']));
$updatePassword->bindValue('user_id', $userId);
$updatePassword->execute();
}
2018-05-27 01:59:57 +00:00
if (isset($_POST['add_role'])) {
user_role_add($manageUser['user_id'], $_POST['add_role']['role']);
}
if (isset($_POST['manage_roles'])) {
switch ($_POST['manage_roles']['mode'] ?? '') {
case 'display':
user_role_set_display($manageUser['user_id'], $_POST['manage_roles']['role']);
break;
case 'remove':
if ((int)$_POST['manage_roles']['role'] !== MSZ_ROLE_MAIN) {
user_role_remove($manageUser['user_id'], $_POST['manage_roles']['role']);
}
break;
}
}
2018-07-08 19:24:59 +00:00
if (!empty($permissions) && !empty($_POST['perms']) && is_array($_POST['perms'])) {
$perms = manage_perms_apply($permissions, $_POST['perms']);
if ($perms !== null) {
$permKeys = array_keys($perms);
$setPermissions = db_prepare('
2018-07-08 19:24:59 +00:00
REPLACE INTO `msz_permissions`
(`role_id`, `user_id`, `' . implode('`, `', $permKeys) . '`)
VALUES
(NULL, :user_id, :' . implode(', :', $permKeys) . ')
');
$setPermissions->bindValue('user_id', $userId);
foreach ($perms as $key => $value) {
$setPermissions->bindValue($key, $value);
}
$setPermissions->execute();
} else {
$deletePermissions = db_prepare('
2018-07-08 19:24:59 +00:00
DELETE FROM `msz_permissions`
WHERE `role_id` IS NULL
AND `user_id` = :user_id
');
$deletePermissions->bindValue('user_id', $userId);
$deletePermissions->execute();
}
}
2018-05-27 01:59:57 +00:00
header("Location: ?v=view&u={$manageUser['user_id']}");
break;
}
2018-08-15 01:12:58 +00:00
tpl_vars([
2018-05-27 01:59:57 +00:00
'available_roles' => $availableRoles,
'has_roles' => $hasRoles,
'view_user' => $manageUser,
2018-07-08 19:24:59 +00:00
'profile_fields' => user_profile_fields_get(),
2018-05-27 01:59:57 +00:00
]);
echo tpl_render('manage.users.user');
break;
case 'roles':
2018-07-08 19:24:59 +00:00
if (!$canManageRoles && !$canManagePerms) {
2018-07-07 23:24:34 +00:00
echo render_error(403);
break;
}
2018-05-16 21:06:14 +00:00
$rolesTake = 10;
$manageRolesCount = db_query('
2018-05-16 21:06:14 +00:00
SELECT COUNT(`role_id`)
FROM `msz_roles`
')->fetchColumn();
$getManageRoles = db_prepare('
2018-05-16 02:58:21 +00:00
SELECT
2018-08-15 20:29:18 +00:00
`role_id`, `role_colour`, `role_name`, `role_title`,
2018-05-16 02:58:21 +00:00
(
SELECT COUNT(`user_id`)
FROM `msz_user_roles` as ur
WHERE ur.`role_id` = r.`role_id`
) as `users`
FROM `msz_roles` as r
2018-05-16 21:06:14 +00:00
LIMIT :offset, :take
');
$getManageRoles->bindValue('offset', $queryQffset);
$getManageRoles->bindValue('take', $rolesTake);
$manageRoles = $getManageRoles->execute() ? $getManageRoles->fetchAll() : [];
2018-05-16 02:58:21 +00:00
2018-08-15 01:12:58 +00:00
tpl_vars([
2018-05-16 21:06:14 +00:00
'manage_roles' => $manageRoles,
'manage_roles_count' => $manageRolesCount,
'manage_roles_range' => $rolesTake,
'manage_roles_offset' => $queryQffset,
]);
2018-08-15 01:12:58 +00:00
echo tpl_render('manage.users.roles');
break;
case 'role':
2018-07-08 19:24:59 +00:00
if (!$canManageRoles && !$canManagePerms) {
2018-07-07 23:24:34 +00:00
echo render_error(403);
break;
}
2018-05-27 00:20:35 +00:00
$roleId = $_GET['r'] ?? null;
2018-07-08 19:24:59 +00:00
if ($canManagePerms) {
2018-08-15 01:12:58 +00:00
tpl_var('permissions', $permissions = manage_perms_list(perms_get_role_raw($roleId ?? 0)));
2018-07-08 19:24:59 +00:00
}
2018-05-27 00:20:35 +00:00
if ($isPostRequest) {
2018-10-02 19:16:42 +00:00
if (!csrf_verify('users_role', $_POST['csrf'] ?? '')) {
echo 'csrf err';
break;
}
if (!isset($_POST['role'])) {
echo 'no';
break;
}
2018-05-27 00:20:35 +00:00
$roleName = $_POST['role']['name'] ?? '';
$roleNameLength = strlen($roleName);
2018-05-27 00:20:35 +00:00
if ($roleNameLength < 1 || $roleNameLength > 255) {
echo 'invalid name length';
break;
}
2018-05-27 00:20:35 +00:00
$roleSecret = !empty($_POST['role']['secret']);
2018-05-27 00:20:35 +00:00
$roleHierarchy = (int)($_POST['role']['hierarchy'] ?? -1);
2018-05-27 00:20:35 +00:00
if ($roleHierarchy < 1 || $roleHierarchy > 100) {
echo 'Invalid hierarchy value.';
break;
}
2018-05-27 00:20:35 +00:00
$roleColour = colour_create();
2018-04-30 21:39:43 +00:00
if (!empty($_POST['role']['colour']['inherit'])) {
2018-05-27 00:20:35 +00:00
colour_set_inherit($roleColour);
2018-04-30 21:39:43 +00:00
} else {
foreach (['red', 'green', 'blue'] as $key) {
$value = (int)($_POST['role']['colour'][$key] ?? -1);
2018-04-30 21:39:43 +00:00
$func = 'colour_set_' . ucfirst($key);
if ($value < 0 || $value > 0xFF) {
echo 'invalid colour value';
break 2;
}
2018-05-27 00:20:35 +00:00
$func($roleColour, $value);
}
}
2018-07-08 19:24:59 +00:00
$roleDescription = $_POST['role']['description'] ?? null;
$roleTitle = $_POST['role']['title'] ?? null;
2018-07-08 19:24:59 +00:00
if ($roleDescription !== null) {
$rdLength = strlen($roleDescription);
if ($rdLength < 1) {
$roleDescription = null;
} elseif ($rdLength > 1000) {
echo 'description is too long';
break;
}
}
if ($roleTitle !== null) {
$rtLength = strlen($roleTitle);
if ($rtLength < 1) {
$roleTitle = null;
} elseif ($rtLength > 64) {
echo 'title is too long';
break;
}
}
2018-05-27 00:20:35 +00:00
if ($roleId < 1) {
$updateRole = db_prepare('
2018-05-16 02:58:21 +00:00
INSERT INTO `msz_roles`
2018-07-08 19:24:59 +00:00
(
2018-11-17 20:37:18 +00:00
`role_name`, `role_hierarchy`, `role_hidden`, `role_colour`,
`role_description`, `role_title`
2018-07-08 19:24:59 +00:00
)
2018-05-16 02:58:21 +00:00
VALUES
2018-07-08 19:24:59 +00:00
(
2018-11-17 20:37:18 +00:00
:role_name, :role_hierarchy, :role_hidden, :role_colour,
:role_description, :role_title
2018-07-08 19:24:59 +00:00
)
2018-05-16 02:58:21 +00:00
');
} else {
$updateRole = db_prepare('
2018-07-08 19:24:59 +00:00
UPDATE `msz_roles`
SET `role_name` = :role_name,
`role_hierarchy` = :role_hierarchy,
2018-11-17 20:37:18 +00:00
`role_hidden` = :role_hidden,
2018-07-08 19:24:59 +00:00
`role_colour` = :role_colour,
`role_description` = :role_description,
`role_title` = :role_title
2018-05-16 02:58:21 +00:00
WHERE `role_id` = :role_id
');
2018-05-27 00:20:35 +00:00
$updateRole->bindValue('role_id', $roleId);
2018-05-16 02:58:21 +00:00
}
2018-05-27 00:20:35 +00:00
$updateRole->bindValue('role_name', $roleName);
$updateRole->bindValue('role_hierarchy', $roleHierarchy);
2018-11-17 20:37:18 +00:00
$updateRole->bindValue('role_hidden', $roleSecret ? 1 : 0);
2018-05-27 00:20:35 +00:00
$updateRole->bindValue('role_colour', $roleColour);
$updateRole->bindValue('role_description', $roleDescription);
2018-07-08 19:24:59 +00:00
$updateRole->bindValue('role_title', $roleTitle);
2018-05-16 02:58:21 +00:00
$updateRole->execute();
2018-05-27 00:20:35 +00:00
if ($roleId < 1) {
$roleId = (int)db_last_insert_id();
2018-05-16 02:58:21 +00:00
}
2018-07-08 19:24:59 +00:00
if (!empty($permissions) && !empty($_POST['perms']) && is_array($_POST['perms'])) {
$perms = manage_perms_apply($permissions, $_POST['perms']);
if ($perms !== null) {
$permKeys = array_keys($perms);
$setPermissions = db_prepare('
2018-07-08 19:24:59 +00:00
REPLACE INTO `msz_permissions`
(`role_id`, `user_id`, `' . implode('`, `', $permKeys) . '`)
VALUES
(:role_id, NULL, :' . implode(', :', $permKeys) . ')
');
$setPermissions->bindValue('role_id', $roleId);
foreach ($perms as $key => $value) {
$setPermissions->bindValue($key, $value);
}
$setPermissions->execute();
} else {
$deletePermissions = db_prepare('
2018-07-08 19:24:59 +00:00
DELETE FROM `msz_permissions`
WHERE `role_id` = :role_id
AND `user_id` IS NULL
');
$deletePermissions->bindValue('role_id', $roleId);
$deletePermissions->execute();
}
}
2018-05-27 00:20:35 +00:00
header("Location: ?v=role&r={$roleId}");
break;
}
2018-05-27 00:20:35 +00:00
if ($roleId !== null) {
if ($roleId < 1) {
echo 'no';
break;
}
$getEditRole = db_prepare('
2018-05-16 02:58:21 +00:00
SELECT *
FROM `msz_roles`
WHERE `role_id` = :role_id
');
2018-05-27 00:20:35 +00:00
$getEditRole->bindValue('role_id', $roleId);
$editRole = $getEditRole->execute() ? $getEditRole->fetch() : [];
2018-05-27 00:20:35 +00:00
if (!$editRole) {
echo 'invalid role';
break;
}
2018-08-15 01:12:58 +00:00
tpl_vars(['edit_role' => $editRole]);
}
echo tpl_render('manage.users.role');
break;
}