mirror of
https://github.com/OPSnet/Gazelle.git
synced 2026-01-16 18:04:34 -05:00
toolbox to show privileges added and removed between successive userclasses
This commit is contained in:
@@ -118,6 +118,40 @@ class Privilege extends \Gazelle\BaseManager {
|
||||
return self::$db->to_array(false, MYSQLI_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of userclasses [A, B, C, D], return a list of pairs
|
||||
* [ ['lower' => 0, 'higher' => A], ['lower' => A, 'higher' => B], ..., ['lower' => C, 'higher' => D] ]
|
||||
* These will be used by compareUserclass()
|
||||
*/
|
||||
public function pairUserclass(array $userclassList): array {
|
||||
$result = [];
|
||||
array_unshift($userclassList, 0);
|
||||
for ($n = 0, $end = count($userclassList) - 1; $n < $end; ++$n) {
|
||||
$result[] = [
|
||||
'lower' => $userclassList[$n],
|
||||
'higher' => $userclassList[$n + 1],
|
||||
];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two userclasses (permissions.ID) return an array of
|
||||
* all privileges that have been added to the second class over the first,
|
||||
* and the privileges which are in the first class but not in the second.
|
||||
*/
|
||||
public function compareUserclass(int $lowerPermissionID, int $higherPermissionID): array {
|
||||
$list = $this->privilege();
|
||||
$lower = array_keys(array_filter($list, fn ($i) => in_array($lowerPermissionID, $i['can'])));
|
||||
$higher = array_keys(array_filter($list, fn ($i) => in_array($higherPermissionID, $i['can'])));
|
||||
sort($lower);
|
||||
sort($higher);
|
||||
return [
|
||||
'add' => array_values(array_diff($higher, $lower)),
|
||||
'remove' => array_values(array_diff($lower, $higher)),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of defined privileges. The `can` field
|
||||
* in the returned array acts as a sparse matrix.
|
||||
|
||||
@@ -829,6 +829,22 @@ defined('FORUM_MOD') or define('FORUM_MOD', 21);
|
||||
defined('MOD') or define('MOD', 11);
|
||||
defined('SYSOP') or define('SYSOP', 15);
|
||||
|
||||
// When adding a new privilege userclasses, care must be taken to
|
||||
// ensure all classes beyond the initial class receive it. The
|
||||
// Privileges Audit page is configured entirely by this definition.
|
||||
defined('USERCLASS_AUDIT') or define('USERCLASS_AUDIT',
|
||||
[
|
||||
[
|
||||
'heading' => 'User classes',
|
||||
'compare' => [USER, MEMBER, POWER, ELITE, TORRENT_MASTER, POWER_TM, ELITE_TM],
|
||||
],
|
||||
[
|
||||
'heading' => 'Staff classes',
|
||||
'compare' => [FORUM_MOD, MOD, SYSOP],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
// Permission ID of secondary class.
|
||||
defined('DONOR') or define('DONOR', 42);
|
||||
defined('FLS_TEAM') or define('FLS_TEAM', 23);
|
||||
|
||||
@@ -1132,6 +1132,29 @@ form.analysis-case {
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.compare-grid {
|
||||
column-gap: 10px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
}
|
||||
.pair-grid {
|
||||
border: 1px solid #808080;
|
||||
column-gap: 5px;
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.pair-grid div.added ul {
|
||||
list-style-type: '+ ';
|
||||
}
|
||||
.pair-grid div.removed ul {
|
||||
list-style-type: '– ';
|
||||
}
|
||||
.pair-grid .no-change {
|
||||
padding: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#more-news-loader {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -152,6 +152,9 @@ switch ($_REQUEST['action'] ?? '') {
|
||||
case 'privilege-alter':
|
||||
include_once 'managers/userclass_alter.php';
|
||||
break;
|
||||
case 'privilege-audit':
|
||||
include_once 'managers/privilege_audit.php';
|
||||
break;
|
||||
case 'privilege_matrix':
|
||||
include_once 'managers/privilege_matrix.php';
|
||||
break;
|
||||
|
||||
17
sections/tools/managers/privilege_audit.php
Normal file
17
sections/tools/managers/privilege_audit.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/** @phpstan-var \Gazelle\User $Viewer */
|
||||
/** @phpstan-var \Twig\Environment $Twig */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Gazelle;
|
||||
|
||||
if (!$Viewer->permitted('admin_manage_permissions')) {
|
||||
Error403::error();
|
||||
}
|
||||
|
||||
echo $Twig->render('admin/privilege-audit.twig', [
|
||||
'privilege_manager' => new Manager\Privilege(),
|
||||
'user_manager' => new Manager\User(),
|
||||
'config' => USERCLASS_AUDIT,
|
||||
]);
|
||||
60
templates/admin/privilege-audit.twig
Normal file
60
templates/admin/privilege-audit.twig
Normal file
@@ -0,0 +1,60 @@
|
||||
{{ header('Audit Userclass Privileges') }}
|
||||
<div class="thin">
|
||||
<div class="header">
|
||||
<div class="linkbox">
|
||||
<a href="tools.php?action=privilege_matrix" class="brackets">Privileges Matrix</a>
|
||||
<a href="tools.php?action=userclass" class="brackets">Userclass list</a>
|
||||
<a href="tools.php?action=staff_groups" class="brackets">Staff Groups</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box pad">
|
||||
{% for section in config %}
|
||||
<h2>{{ section.heading }}</h2>
|
||||
{% for comparison in privilege_manager.pairUserclass(section.compare) %}
|
||||
{% if loop.first %}
|
||||
<div class="compare-grid">
|
||||
{% endif %}
|
||||
<div class="compare">
|
||||
<h3>
|
||||
{%- if comparison.lower -%}
|
||||
{{ user_manager.userclassName(comparison.lower) }} 🠞 {{ user_manager.userclassName(comparison.higher) -}}
|
||||
{% else -%}
|
||||
Initial 🠞 {{ user_manager.userclassName(comparison.higher) -}}
|
||||
{% endif -%}
|
||||
</h3>
|
||||
{% set result = privilege_manager.compareUserclass(comparison.lower, comparison.higher) %}
|
||||
<div class="pair-grid">
|
||||
<div class="added">
|
||||
<ul>
|
||||
{% for r in result.add %}
|
||||
<li>{{ r }}</li>
|
||||
{% else %}
|
||||
{% if result.remove %}
|
||||
<li><i>None</i></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="removed">
|
||||
<ul>
|
||||
{% for r in result.remove %}
|
||||
<li>{{ r }}</li>
|
||||
{% else %}
|
||||
{% if result.add %}
|
||||
<li><i>None</i></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% if not (result.add or result.remove) %}
|
||||
<span class="no-change">No change</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% if loop.last %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{{ footer() }}
|
||||
@@ -2,8 +2,9 @@
|
||||
{{ header('Manage Permissions') }}
|
||||
<div class="header">
|
||||
<div class="linkbox">
|
||||
<a href="tools.php?action=userclass" class="brackets">Userclass List</a>
|
||||
<a href="tools.php?action=privilege_matrix" class="brackets">Privilege Matrix</a>
|
||||
<a href="tools.php?action=privilege-audit" class="brackets">Privileges Audit</a>
|
||||
<a href="tools.php?action=userclass" class="brackets">Userclass List</a>
|
||||
<a href="tools.php?action=staff_groups" class="brackets">Staff Groups</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
{{ header('Privilege Matrix') }}
|
||||
{{ header('Privileges Matrix') }}
|
||||
<div class="thin">
|
||||
<div class="header">
|
||||
<div class="linkbox">
|
||||
<a href="tools.php?action=privilege-audit" class="brackets">Privileges audit</a>
|
||||
<a href="tools.php?action=userclass" class="brackets">Userclass list</a>
|
||||
<a href="tools.php?action=staff_groups" class="brackets">Staff Groups</a>
|
||||
<br />
|
||||
<a href="tools.php?action=permissions&id=new" class="brackets">Create a new userclass</a>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Privilege Matrix</h2>
|
||||
<h2>Privileges Matrix</h2>
|
||||
<table width="100%">
|
||||
<tr class="colhead">
|
||||
<td rowspan="2" style="vertical-align: bottom">Primary Class ★<br /><br />Privilege</td>
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
<div class="thin">
|
||||
<div class="header">
|
||||
<div class="linkbox">
|
||||
<a href="tools.php?action=privilege_matrix" class="brackets">Privilege Matrix</a>
|
||||
<a href="tools.php?action=privilege_matrix" class="brackets">Privileges Matrix</a>
|
||||
<a href="tools.php?action=privilege-audit" class="brackets">Privileges Audit</a>
|
||||
<a href="tools.php?action=staff_groups" class="brackets">Staff Groups</a>
|
||||
<br />
|
||||
<a href="tools.php?action=userclass&id=new" class="brackets">Create a new userclass</a>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{{ header('Staff Group Management') }}
|
||||
<div class="header">
|
||||
<div class="linkbox">
|
||||
<a href="tools.php?action=userclass" class="brackets">Userclass List</a>
|
||||
<a href="tools.php?action=privilege_matrix" class="brackets">Privilege Matrix</a>
|
||||
<a href="tools.php?action=privilege-audit" class="brackets">Privileges Audit</a>
|
||||
<a href="tools.php?action=userclass" class="brackets">Userclass List</a>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Staff Group Management</h2>
|
||||
|
||||
@@ -152,6 +152,26 @@ class PrivilegeTest extends TestCase {
|
||||
$this->assertEquals($total + 1, $flsList[0]['total'], 'privilege-one-new-fls');
|
||||
}
|
||||
|
||||
public function testPrivilegeCompare(): void {
|
||||
$manager = new Manager\Privilege();
|
||||
$compare = $manager->compareUserclass(USER, MEMBER);
|
||||
$this->assertCount(2, $compare, 'privilege-compare-count');
|
||||
$this->assertEquals([], $compare['remove'], 'privilege-compare-remove');
|
||||
$this->assertEquals(
|
||||
[
|
||||
'edit_unknowns',
|
||||
'site_advanced_top10',
|
||||
'site_collages_manage',
|
||||
'site_collages_subscribe',
|
||||
'site_make_bookmarks',
|
||||
'site_submit_requests',
|
||||
'zip_downloader',
|
||||
],
|
||||
$compare['add'],
|
||||
'privilege-compare-add',
|
||||
);
|
||||
}
|
||||
|
||||
public function testCustomPrivilege(): void {
|
||||
$admin = $this->userList['admin'];
|
||||
$user = $this->userList['user'];
|
||||
|
||||
Reference in New Issue
Block a user