Added personal role management.
This commit is contained in:
parent
3cb971aa03
commit
e7cddfd37e
12 changed files with 226 additions and 31 deletions
66
assets/less/classes/settings/role.less
Normal file
66
assets/less/classes/settings/role.less
Normal file
|
@ -0,0 +1,66 @@
|
|||
.settings__role {
|
||||
border: 1px solid var(--accent-colour);
|
||||
background-color: var(--accent-colour);
|
||||
border-radius: 2px;
|
||||
margin: 2px;
|
||||
overflow: none;
|
||||
width: 200px;
|
||||
|
||||
&__collection {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
&__content {
|
||||
background-color: var(--background-colour-translucent);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-size: 1.2em;
|
||||
line-height: 1.7em;
|
||||
border-bottom: 1px solid var(--accent-colour);
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
&__description {
|
||||
font-size: .9em;
|
||||
line-height: 1.8em;
|
||||
padding: 0 2px;
|
||||
margin: 0 2px;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
&__options {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
font-size: 1.5em;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
&__option {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
text-shadow: inherit;
|
||||
transition: color .2s;
|
||||
flex: 0 0 auto;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
&:not(&--disabled):hover {
|
||||
color: var(--accent-colour);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
opacity: .2;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
overflow: hidden;
|
||||
|
||||
&--current {
|
||||
// todo: make this now bad
|
||||
// todo: make this not bad
|
||||
background-image: linear-gradient(0deg, #111c, #111c);
|
||||
background-color: var(--accent-colour);
|
||||
}
|
||||
|
|
|
@ -133,6 +133,7 @@ body {
|
|||
@import "classes/settings/login-history";
|
||||
@import "classes/settings/session";
|
||||
@import "classes/settings/sessions";
|
||||
@import "classes/settings/role";
|
||||
|
||||
// News
|
||||
@import "classes/news/container";
|
||||
|
|
56
build.php
56
build.php
|
@ -141,23 +141,35 @@ function recursiveConcat(string $source, string $existing = ''): string
|
|||
return $existing;
|
||||
}
|
||||
|
||||
$doAll = empty($argv[1]) || $argv[1] === 'all';
|
||||
$doCss = $doAll || $argv[1] === 'css';
|
||||
$doJs = $doAll || $argv[1] === 'js';
|
||||
|
||||
// Make sure we're running from the misuzu root directory.
|
||||
chdir(__DIR__);
|
||||
|
||||
misuzu_log('Cleanup');
|
||||
createDirIfNotExist(CSS_DIR);
|
||||
createDirIfNotExist(JS_DIR);
|
||||
deleteAllFilesInDir(CSS_DIR, '*.css');
|
||||
deleteAllFilesInDir(JS_DIR, '*.js');
|
||||
deleteAllFilesInDir(TS_DIR, '*.d.ts');
|
||||
|
||||
misuzu_log();
|
||||
misuzu_log('Compiling LESS');
|
||||
if ($doCss) {
|
||||
createDirIfNotExist(CSS_DIR);
|
||||
deleteAllFilesInDir(CSS_DIR, '*.css');
|
||||
}
|
||||
|
||||
if (!is_file(LESS_DIR . LESS_ENTRY_POINT)) {
|
||||
misuzu_log('==> ERR: Entry point for this style does not exist (' . basename(LESS_ENTRY_POINT) . ')');
|
||||
} else {
|
||||
system(sprintf(LESS_CMD, escapeshellarg(LESS_DIR . LESS_ENTRY_POINT), LESS_DEST));
|
||||
if ($doJs) {
|
||||
createDirIfNotExist(JS_DIR);
|
||||
deleteAllFilesInDir(JS_DIR, '*.js');
|
||||
deleteAllFilesInDir(TS_DIR, '*.d.ts');
|
||||
}
|
||||
|
||||
if ($doCss) {
|
||||
misuzu_log();
|
||||
misuzu_log('Compiling LESS');
|
||||
|
||||
if (!is_file(LESS_DIR . LESS_ENTRY_POINT)) {
|
||||
misuzu_log('==> ERR: Entry point for this style does not exist (' . basename(LESS_ENTRY_POINT) . ')');
|
||||
} else {
|
||||
system(sprintf(LESS_CMD, escapeshellarg(LESS_DIR . LESS_ENTRY_POINT), LESS_DEST));
|
||||
}
|
||||
}
|
||||
|
||||
misuzu_log();
|
||||
|
@ -169,16 +181,22 @@ define('IMPORT_SEQ', [
|
|||
'files' => NODE_IMPORT_CSS,
|
||||
'destination' => NODE_DEST_CSS,
|
||||
'insert-semicolon' => false,
|
||||
'do' => $doCss,
|
||||
],
|
||||
[
|
||||
'name' => 'JavaScript',
|
||||
'files' => NODE_IMPORT_JS,
|
||||
'destination' => NODE_DEST_JS,
|
||||
'insert-semicolon' => true,
|
||||
'do' => $doJs,
|
||||
],
|
||||
]);
|
||||
|
||||
foreach (IMPORT_SEQ as $sequence) {
|
||||
if (!$sequence['do']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
misuzu_log("=> {$sequence['name']}");
|
||||
|
||||
$contents = '';
|
||||
|
@ -203,12 +221,14 @@ foreach (IMPORT_SEQ as $sequence) {
|
|||
file_put_contents($sequence['destination'], $contents);
|
||||
}
|
||||
|
||||
misuzu_log();
|
||||
misuzu_log('Compiling TypeScript');
|
||||
misuzu_log(shell_exec('tsc --extendedDiagnostics -p tsconfig.json'));
|
||||
file_put_contents(TS_DEST, recursiveConcat(TS_SRC));
|
||||
deleteAllFilesInDir(TS_SRC, '*.js');
|
||||
rmdir(TS_SRC);
|
||||
if ($doJs) {
|
||||
misuzu_log();
|
||||
misuzu_log('Compiling TypeScript');
|
||||
misuzu_log(shell_exec('tsc --extendedDiagnostics -p tsconfig.json'));
|
||||
file_put_contents(TS_DEST, recursiveConcat(TS_SRC));
|
||||
deleteAllFilesInDir(TS_SRC, '*.js');
|
||||
rmdir(TS_SRC);
|
||||
}
|
||||
|
||||
misuzu_log();
|
||||
misuzu_log('Copying data...');
|
||||
|
@ -222,7 +242,7 @@ foreach (NODE_COPY_DIRECTORY as $source => $dest) {
|
|||
}
|
||||
|
||||
// no need to do this in debug mode, auto reload is enabled and cache is disabled
|
||||
if (!file_exists(__DIR__ . '/.debug')) {
|
||||
if ($doAll && !file_exists(__DIR__ . '/.debug')) {
|
||||
// Clear Twig cache
|
||||
misuzu_log();
|
||||
misuzu_log('Deleting template cache');
|
||||
|
|
22
database/2018_11_17_191807_roles_table_extensions.php
Normal file
22
database/2018_11_17_191807_roles_table_extensions.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
namespace Misuzu\DatabaseMigrations\RolesTableExtensions;
|
||||
|
||||
use PDO;
|
||||
|
||||
function migrate_up(PDO $conn): void
|
||||
{
|
||||
$conn->exec("
|
||||
ALTER TABLE `msz_roles`
|
||||
CHANGE COLUMN `role_secret` `role_hidden` TINYINT(1) NOT NULL DEFAULT '0' AFTER `role_description`,
|
||||
ADD COLUMN `role_can_leave` TINYINT(1) NOT NULL DEFAULT '0' AFTER `role_hidden`;
|
||||
");
|
||||
}
|
||||
|
||||
function migrate_down(PDO $conn): void
|
||||
{
|
||||
$conn->exec("
|
||||
ALTER TABLE `msz_roles`
|
||||
CHANGE COLUMN `role_hidden` `role_secret` TINYINT(1) NOT NULL DEFAULT '0' AFTER `role_description`,
|
||||
DROP COLUMN `role_can_leave`;
|
||||
");
|
||||
}
|
|
@ -375,12 +375,12 @@ switch ($_GET['v'] ?? null) {
|
|||
$updateRole = db_prepare('
|
||||
INSERT INTO `msz_roles`
|
||||
(
|
||||
`role_name`, `role_hierarchy`, `role_secret`, `role_colour`,
|
||||
`role_name`, `role_hierarchy`, `role_hidden`, `role_colour`,
|
||||
`role_description`, `role_title`
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
:role_name, :role_hierarchy, :role_secret, :role_colour,
|
||||
:role_name, :role_hierarchy, :role_hidden, :role_colour,
|
||||
:role_description, :role_title
|
||||
)
|
||||
');
|
||||
|
@ -389,7 +389,7 @@ switch ($_GET['v'] ?? null) {
|
|||
UPDATE `msz_roles`
|
||||
SET `role_name` = :role_name,
|
||||
`role_hierarchy` = :role_hierarchy,
|
||||
`role_secret` = :role_secret,
|
||||
`role_hidden` = :role_hidden,
|
||||
`role_colour` = :role_colour,
|
||||
`role_description` = :role_description,
|
||||
`role_title` = :role_title
|
||||
|
@ -400,7 +400,7 @@ switch ($_GET['v'] ?? null) {
|
|||
|
||||
$updateRole->bindValue('role_name', $roleName);
|
||||
$updateRole->bindValue('role_hierarchy', $roleHierarchy);
|
||||
$updateRole->bindValue('role_secret', $roleSecret ? 1 : 0);
|
||||
$updateRole->bindValue('role_hidden', $roleSecret ? 1 : 0);
|
||||
$updateRole->bindValue('role_colour', $roleColour);
|
||||
$updateRole->bindValue('role_description', $roleDescription);
|
||||
$updateRole->bindValue('role_title', $roleTitle);
|
||||
|
|
|
@ -78,7 +78,7 @@ if (!$role) {
|
|||
$roles = db_query('
|
||||
SELECT `role_id`, `role_name`, `role_colour`
|
||||
FROM `msz_roles`
|
||||
WHERE `role_secret` = 0
|
||||
WHERE `role_hidden` = 0
|
||||
ORDER BY `role_id`
|
||||
')->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
|
|
|
@ -51,9 +51,29 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
}
|
||||
}
|
||||
|
||||
if (!$disableAccountOptions) {
|
||||
$currentPasswordValid = !empty($_POST['current_password']);
|
||||
if (!empty($_POST['role'])) {
|
||||
$roleId = (int)($_POST['role']['id'] ?? 0);
|
||||
|
||||
if ($roleId > 0 && user_role_has(user_session_current('user_id'), $roleId)) {
|
||||
switch ($_POST['role']['mode'] ?? '') {
|
||||
case 'display':
|
||||
user_role_set_display(user_session_current('user_id'), $roleId);
|
||||
break;
|
||||
|
||||
case 'leave':
|
||||
if (user_role_can_leave($roleId)) {
|
||||
user_role_remove(user_session_current('user_id'), $roleId);
|
||||
} else {
|
||||
$errors[] = "You're not allow to leave this role, an administrator has to remove it for you.";
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$errors[] = "You're trying to modify a role that hasn't been assigned to you.";
|
||||
}
|
||||
}
|
||||
|
||||
if (!$disableAccountOptions && !empty($_POST['current_password'])) {
|
||||
if (!user_password_verify_db(user_session_current('user_id'), $_POST['current_password'] ?? '')) {
|
||||
$errors[] = 'Your password was incorrect.';
|
||||
} else {
|
||||
|
@ -158,17 +178,16 @@ $logins['list'] = user_login_attempts_list($sessions['offset'], $sessions['take'
|
|||
$logs['list'] = audit_log_list($logs['offset'], $logs['take'], user_session_current('user_id'));
|
||||
|
||||
$getUserRoles = db_prepare('
|
||||
SELECT r.`role_id`, r.`role_name`
|
||||
SELECT r.`role_id`, r.`role_name`, r.`role_description`, r.`role_colour`, r.`role_can_leave`
|
||||
FROM `msz_user_roles` as ur
|
||||
LEFT JOIN `msz_roles` as r
|
||||
ON r.`role_id` = ur.`role_id`
|
||||
WHERE ur.`user_id` = :user_id
|
||||
ORDER BY r.`role_hierarchy` DESC
|
||||
');
|
||||
$getUserRoles->bindValue('user_id', user_session_current('user_id'));
|
||||
$userRoles = $getUserRoles->execute() ? $getUserRoles->fetchAll(PDO::FETCH_ASSOC) : [];
|
||||
|
||||
var_dump($userRoles);
|
||||
|
||||
if (empty($errors)) { // delete this in 2019
|
||||
$errors[] = 'A few of the elements on this page have been moved to the on-profile editor. To find them, go to your profile and hit the "Edit Profile" button below your avatar.';
|
||||
}
|
||||
|
@ -180,5 +199,6 @@ echo tpl_render('user.settings', [
|
|||
'sessions' => $sessions,
|
||||
'logins' => $logins,
|
||||
'logs' => $logs,
|
||||
'roles' => $userRoles,
|
||||
'user_roles' => $userRoles,
|
||||
'user_display_role' => user_role_get_display(user_session_current('user_id')),
|
||||
]);
|
||||
|
|
|
@ -26,6 +26,17 @@ function user_role_remove(int $userId, int $roleId): bool
|
|||
return $removeRole->execute();
|
||||
}
|
||||
|
||||
function user_role_can_leave(int $roleId): bool
|
||||
{
|
||||
$canLeaveRole = db_prepare('
|
||||
SELECT `role_can_leave` != 0
|
||||
FROM `msz_roles`
|
||||
WHERE `role_id` = :role_id
|
||||
');
|
||||
$canLeaveRole->bindValue('role_id', $roleId);
|
||||
return $canLeaveRole->execute() ? (bool)$canLeaveRole->fetchColumn() : false;
|
||||
}
|
||||
|
||||
function user_role_has(int $userId, int $roleId): bool
|
||||
{
|
||||
$hasRole = db_prepare('
|
||||
|
@ -55,3 +66,18 @@ function user_role_set_display(int $userId, int $roleId): bool
|
|||
|
||||
return $setDisplay->execute();
|
||||
}
|
||||
|
||||
function user_role_get_display(int $userId): int
|
||||
{
|
||||
if ($userId < 1) {
|
||||
return MSZ_ROLE_MAIN;
|
||||
}
|
||||
|
||||
$fetchRole = db_prepare('
|
||||
SELECT `display_role`
|
||||
FROM `msz_users`
|
||||
WHERE `user_id` = :user_id
|
||||
');
|
||||
$fetchRole->bindValue('user_id', $userId);
|
||||
return $fetchRole->execute() ? (int)$fetchRole->fetchColumn() : MSZ_ROLE_MAIN;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
<?php
|
||||
// Quick note to myself and others about the `display_role` column in the users database.
|
||||
// Never ever EVER use it for ANYTHING other than determining display colours, there's a small chance that it might not be accurate.
|
||||
// And even if it were, roles properties are aggregated and thus must all be accounted for.
|
||||
|
||||
define('MSZ_PERM_USER_EDIT_PROFILE', 1);
|
||||
define('MSZ_PERM_USER_CHANGE_AVATAR', 1 << 1);
|
||||
define('MSZ_PERM_USER_CHANGE_BACKGROUND', 1 << 2);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<label class="form__label">
|
||||
<div class="form__label__text">Hide Rank</div>
|
||||
<div class="form__label__input">
|
||||
{{ input_checkbox('role[secret]', '', edit_role is defined and edit_role.role_secret) }}
|
||||
{{ input_checkbox('role[secret]', '', edit_role is defined and edit_role.role_hidden) }}
|
||||
</div>
|
||||
</label>
|
||||
|
||||
|
|
|
@ -92,6 +92,42 @@
|
|||
<div class="settings__description">
|
||||
<p>This is a listing of the user roles you're a part of, you can select which you want to leave or which one you want to boast as your main role which will change your username colour accordingly.</p>
|
||||
</div>
|
||||
|
||||
<div class="settings__role__collection">
|
||||
{% for role in user_roles %}
|
||||
{% set is_display_role = user_display_role == role.role_id %}
|
||||
|
||||
<div class="settings__role" style="{{ role.role_colour|html_colour('--accent-colour') }}">
|
||||
<div class="settings__role__content">
|
||||
<div class="settings__role__name">
|
||||
{{ role.role_name }}
|
||||
</div>
|
||||
|
||||
<div class="settings__role__description">
|
||||
{{ role.role_description }}
|
||||
</div>
|
||||
|
||||
<form class="settings__role__options" method="post" action="/settings.php">
|
||||
{{ input_csrf('settings') }}
|
||||
{{ input_hidden('role[id]', role.role_id) }}
|
||||
|
||||
<button class="settings__role__option{% if is_display_role %} settings__role__option--disabled{% endif %}"
|
||||
name="role[mode]" value="display" title="Set this as your display role"
|
||||
{% if is_display_role %}disabled{% endif %}>
|
||||
<i class="far {{ is_display_role ? 'fa-check-square' : 'fa-square' }}"></i>
|
||||
</button>
|
||||
|
||||
<button class="settings__role__option{% if not role.role_can_leave %} settings__role__option--disabled{% endif %}"
|
||||
name="role[mode]" value="leave" title="Leave this role"
|
||||
onclick="return confirm('ARE YOU SURE DAWG?')"
|
||||
{% if not role.role_can_leave %}disabled{% endif %}>
|
||||
<i class="fas fa-times-circle"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container settings__container" id="sessions">
|
||||
|
|
Loading…
Add table
Reference in a new issue