-
-
Notifications
You must be signed in to change notification settings - Fork 159
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Permissions overhaul - Define permissions in the database
2nd attempt at this one! Similar to #1008 but separately defining the roles, modules and associated permissions in the database. Also has admin being a defined role automatically having full access. Parent issue: #530
- Loading branch information
wrongecho
committed
Sep 14, 2024
1 parent
6975d6e
commit 271019b
Showing
10 changed files
with
513 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<div class="modal" id="addRoleModal" tabindex="-1"> | ||
<div class="modal-dialog"> | ||
<div class="modal-content bg-dark"> | ||
<div class="modal-header"> | ||
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>Add new role</h5> | ||
<button type="button" class="close text-white" data-dismiss="modal"> | ||
<span>×</span> | ||
</button> | ||
</div> | ||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> | ||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>"> | ||
<div class="modal-body bg-white"> | ||
<div class="tab-content"> | ||
|
||
<div class="form-group"> | ||
<label>Name <strong class="text-danger">*</strong></label> | ||
<div class="input-group"> | ||
<div class="input-group-prepend"> | ||
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span> | ||
</div> | ||
<input type="text" class="form-control" name="role_name" placeholder="Role Name" required> | ||
</div> | ||
</div> | ||
|
||
<div class="form-group"> | ||
<label>Description <strong class="text-danger">*</strong></label> | ||
<div class="input-group"> | ||
<div class="input-group-prepend"> | ||
<span class="input-group-text"><i class="fa fa-fw fa-chevron-right"></i></span> | ||
</div> | ||
<input type="text" class="form-control" name="role_description" placeholder="Role Description" required> | ||
</div> | ||
</div> | ||
|
||
<div class="form-group"> | ||
<label>Admin Access <strong class="text-danger">*</strong></label> | ||
<div class="input-group"> | ||
<div class="input-group-prepend"> | ||
<span class="input-group-text"><i class="fa fa-fw fa-tools"></i></span> | ||
</div> | ||
<select class="form-control select2" name="role_is_admin" required> | ||
<option value="0">No - edit after creation to set permissions</option> | ||
<option value="1">Yes - this role should have full admin access</option> | ||
</select> | ||
</div> | ||
</div> | ||
|
||
</div> | ||
|
||
</div> | ||
<div class="modal-footer bg-white"> | ||
<button type="submit" name="add_role" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> | ||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
<div class="modal" id="editRoleModal<?php echo $role_id; ?>" tabindex="-1"> | ||
<div class="modal-dialog"> | ||
<div class="modal-content bg-dark"> | ||
<div class="modal-header"> | ||
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>Editing role: | ||
<strong><?php echo $role_name; ?></strong></h5> | ||
<button type="button" class="close text-white" data-dismiss="modal"> | ||
<span>×</span> | ||
</button> | ||
</div> | ||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> | ||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>"> | ||
<input type="hidden" name="role_id" value="<?php echo $role_id; ?>"> | ||
<div class="modal-body bg-white"> | ||
|
||
<ul class="nav nav-pills nav-justified mb-3"> | ||
<li class="nav-item"> | ||
<a class="nav-link active" data-toggle="pill" href="#pills-role-details<?php echo $role_id; ?>">Details</a> | ||
</li> | ||
<li class="nav-item"> | ||
<a class="nav-link" data-toggle="pill" href="#pills-role-access<?php echo $role_id; ?>">Access</a> | ||
</li> | ||
</ul> | ||
|
||
<hr> | ||
|
||
<div class="tab-content"> | ||
|
||
<div class="tab-pane fade show active" id="pills-role-details<?php echo $role_id; ?>"> | ||
|
||
<div class="form-group"> | ||
<label>Name <strong class="text-danger">*</strong></label> | ||
<div class="input-group"> | ||
<div class="input-group-prepend"> | ||
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span> | ||
</div> | ||
<input type="text" class="form-control" name="role_name" placeholder="Role Name" value="<?php echo $role_name; ?>" required> | ||
</div> | ||
</div> | ||
|
||
<div class="form-group"> | ||
<label>Description <strong class="text-danger">*</strong></label> | ||
<div class="input-group"> | ||
<div class="input-group-prepend"> | ||
<span class="input-group-text"><i class="fa fa-fw fa-chevron-right"></i></span> | ||
</div> | ||
<input type="text" class="form-control" name="role_description" placeholder="Role Description" value="<?php echo $role_description; ?>" required> | ||
</div> | ||
</div> | ||
|
||
|
||
<div class="form-group"> | ||
<label>Admin Access <strong class="text-danger">*</strong></label> | ||
<div class="input-group"> | ||
<div class="input-group-prepend"> | ||
<span class="input-group-text"><i class="fa fa-fw fa-tools"></i></span> | ||
</div> | ||
<select class="form-control select2" name="role_is_admin" required> | ||
<option value="1" <?php if ($role_admin) { echo 'selected'; } ?> >Yes - this role should have full admin access</option> | ||
<option value="0" <?php if (!$role_admin) { echo 'selected'; } ?>>No - use permissions on the next tab</option> | ||
</select> | ||
</div> | ||
</div> | ||
|
||
</div> | ||
|
||
<div class="tab-pane fade" id="pills-role-access<?php echo $role_id; ?>"> | ||
|
||
<?php if ($role_admin) { ?> | ||
<div class="alert alert-warning"><strong>Module permissions do not apply to Admins.</strong></div> | ||
<?php } ?> | ||
|
||
<?php | ||
|
||
// Enumerate modules | ||
$sql_modules = mysqli_query($mysqli, "SELECT * FROM modules"); | ||
while ($row_modules = mysqli_fetch_array($sql_modules)) { | ||
$module_id = intval($row_modules['module_id']); | ||
$module_name = nullable_htmlentities($row_modules['module_name']); | ||
$module_name_display = ucfirst(str_replace("module_","",$module_name)); | ||
$module_description = nullable_htmlentities($row_modules['module_description']); | ||
|
||
// Get permission level for module | ||
$module_permission_row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT user_role_permission_level FROM user_role_permissions WHERE module_id = $module_id AND user_role_id = $role_id LIMIT 1")); | ||
$module_permission = 0; | ||
if ($module_permission_row) { | ||
$module_permission = $module_permission_row['user_role_permission_level']; | ||
} | ||
?> | ||
|
||
<div class="form-group"> | ||
<label> <?php echo $module_name_display ?> <strong class="text-danger">*</strong></label> | ||
<div class="input-group"> | ||
<select class="form-control select2" name="<?php echo "$module_id##$module_name" ?>" required> | ||
<option value="0" <?php if ($module_permission == 0) { echo 'selected'; } ?> >None</option> | ||
<option value="1" <?php if ($module_permission == 1) { echo 'selected'; } ?> >Read</option> | ||
<option value="2" <?php if ($module_permission == 2) { echo 'selected'; } ?>>Modify (Read, Edit, Archive)</option> | ||
<option value="3" <?php if ($module_permission == 3) { echo 'selected'; } ?>>Full (Read, Edit, Archive, Delete)</option> | ||
</select> | ||
</div> | ||
<small class="form-text text-muted"><?php echo $module_description ?></small> | ||
|
||
</div> | ||
|
||
<?php } // End while ?> | ||
|
||
</div> | ||
|
||
</div> | ||
|
||
</div> | ||
<div class="modal-footer bg-white"> | ||
<button type="submit" name="edit_role" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> | ||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
<?php | ||
|
||
// Default Column Sortby Filter | ||
$sort = "user_role_is_admin"; | ||
$order = "DESC"; | ||
|
||
require_once "inc_all_admin.php"; | ||
|
||
|
||
//Rebuild URL | ||
$url_query_strings_sort = http_build_query($get_copy); | ||
|
||
$sql = mysqli_query( | ||
$mysqli, | ||
"SELECT SQL_CALC_FOUND_ROWS * FROM user_roles | ||
WHERE (user_roles.user_role_name LIKE '%$q%' OR user_roles.user_role_description LIKE '%$q%') | ||
AND user_roles.user_role_archived_at IS NULL | ||
ORDER BY $sort $order LIMIT $record_from, $record_to" | ||
); | ||
|
||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); | ||
|
||
?> | ||
<div class="alert alert-danger"><strong>Roles are not yet active/enforced - do not use.</strong><hr></div> | ||
|
||
<div class="card card-dark"> | ||
<div class="card-header py-2"> | ||
<h3 class="card-title mt-2"><i class="fas fa-fw fa-user-shield mr-2"></i>Roles</h3> | ||
<div class="card-tools"> | ||
<div class="btn-group"> | ||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addRoleModal"> | ||
<i class="fas fa-fw fa-user-plus mr-2"></i>New Role | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
<div class="card-body"> | ||
<form class="mb-4" autocomplete="off"> | ||
<div class="row"> | ||
<div class="col-md-4"> | ||
<div class="input-group"> | ||
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) {echo stripslashes(nullable_htmlentities($q));} ?>" placeholder="Search Roles"> | ||
<div class="input-group-append"> | ||
<button class="btn btn-primary"><i class="fa fa-search"></i></button> | ||
</div> | ||
</div> | ||
</div> | ||
<div class="col-md-8"> | ||
<div class="float-right"> | ||
<!--<button type="button" class="btn btn-default" data-toggle="modal" data-target="#exportRoleModal"><i class="fa fa-fw fa-download mr-2"></i>Export</button>--> | ||
</div> | ||
</div> | ||
</div> | ||
</form> | ||
<hr> | ||
<div class="table-responsive-sm"> | ||
<table class="table table-striped table-borderless table-hover"> | ||
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> | ||
<tr> | ||
<th class="text-center"><a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_role_name&order=<?php echo $disp; ?>">Name</a></th> | ||
<th class="text-center"><a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_role_description&order=<?php echo $disp; ?>">Description</a></th> | ||
<th><a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_role_is_admin&order=<?php echo $disp; ?>">Admin</a></th> | ||
<th><a class="text-dark">User count</a></th> | ||
|
||
<th class="text-center">Action</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<?php | ||
|
||
while ($row = mysqli_fetch_array($sql)) { | ||
$role_id = intval($row['user_role_id']); | ||
$role_name = nullable_htmlentities($row['user_role_name']); | ||
$role_description = nullable_htmlentities($row['user_role_description']); | ||
$role_admin = intval($row['user_role_is_admin']); | ||
$role_archived_at = nullable_htmlentities($row['user_role_archived_at']); | ||
|
||
// Count number of users that have each role | ||
$sql_role_user_count = mysqli_query($mysqli, "SELECT COUNT(users.user_id) FROM users LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role = $role_id AND user_archived_at IS NULL"); | ||
$role_user_count = mysqli_fetch_row($sql_role_user_count)[0]; | ||
|
||
?> | ||
<tr> | ||
<td class="text-center"> | ||
<a class="text-dark" href="#" data-toggle="modal" data-target="#editRoleModal<?php echo $role_id; ?>"> | ||
<div class="text-secondary"><?php echo $role_name; ?></div> | ||
</a> | ||
</td> | ||
<td><?php echo $role_description; ?></td> | ||
<td><?php echo $role_admin ? 'Yes' : 'No' ; ?></td> | ||
<td><?php echo $role_user_count ?></td> | ||
<td> | ||
<?php if ($role_id !== 3) { ?> | ||
<div class="dropdown dropleft text-center"> | ||
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> | ||
<i class="fas fa-ellipsis-h"></i> | ||
</button> | ||
<div class="dropdown-menu"> | ||
|
||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#editRoleModal<?php echo $role_id; ?>"> | ||
<i class="fas fa-fw fa-user-edit mr-2"></i>Edit | ||
</a> | ||
|
||
<?php if (empty($role_archived_at) && $role_user_count == 0) { ?> | ||
<!-- To be added--> | ||
<!-- <div class="dropdown-divider"></div>--> | ||
<!-- <a class="dropdown-item text-danger confirm-link" href="post.php?archive_role=--><?php //echo $role_id; ?><!--&csrf_token=--><?php //echo $_SESSION['csrf_token'] ?><!--">--> | ||
<!-- <i class="fas fa-fw fa-archive mr-2"></i>Archive--> | ||
<!-- </a>--> | ||
<?php } ?> | ||
|
||
</div> | ||
</div> | ||
<?php } ?> | ||
</td> | ||
</tr> | ||
|
||
<?php | ||
|
||
require "admin_role_edit_modal.php"; | ||
|
||
|
||
} | ||
|
||
?> | ||
|
||
</tbody> | ||
</table> | ||
</div> | ||
<?php require_once "pagination.php"; | ||
?> | ||
</div> | ||
</div> | ||
|
||
<?php | ||
|
||
require_once "admin_role_add_modal.php"; | ||
|
||
require_once "footer.php"; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.