rbac build

This commit is contained in:
2026-04-29 15:44:20 +02:00
parent 90497deebf
commit bbd9441b31
14 changed files with 1006 additions and 635 deletions

View File

@@ -260,9 +260,6 @@ JOIN dbo.RolePermissions rp ON rp.Role_ID = r.Role_ID
JOIN dbo.Permission p ON p.ID = rp.Permission_ID;
GO
/* =========================================================
FIXED vEventLog (SEQUELIZE MATCH + SYSTEM FIX)
========================================================= */
@@ -416,206 +413,3 @@ SELECT
ID
FROM dbo.[Role]
WHERE Name='ADMIN';
GO
/* =========================================================
EXTENDED RBAC VIEWS
========================================================= */
-- ========================================================
-- 1. USER GROUPS (DIRECT + INHERITED)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationGroupsExpanded AS
SELECT
ag.Authentication_ObjectGUID,
g.ObjectGUID AS GroupGUID,
g.Name AS GroupName,
'DIRECT' AS Source
FROM dbo.AuthenticationGroups ag
JOIN dbo.[Group] g
ON g.ObjectGUID = ag.Group_ObjectGUID
UNION ALL
SELECT
ag.Authentication_ObjectGUID,
gc.ParentGroup_ObjectGUID,
g.Name,
'INHERITED'
FROM dbo.AuthenticationGroups ag
JOIN dbo.GroupClosure gc
ON gc.ChildGroup_ObjectGUID = ag.Group_ObjectGUID
JOIN dbo.[Group] g
ON g.ObjectGUID = gc.ParentGroup_ObjectGUID;
GO
-- ========================================================
-- 2. ROLES (DIRECT + GROUP + HIERARCHY)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationRolesExpanded AS
SELECT
ar.Authentication_ObjectGUID,
ar.Role_ID,
r.Name AS RoleName,
'DIRECT' AS Source
FROM dbo.AuthenticationRoles ar
JOIN dbo.[Role] r
ON r.ID = ar.Role_ID
UNION ALL
SELECT
ag.Authentication_ObjectGUID,
gr.Role_ID,
r.Name,
'GROUP'
FROM dbo.AuthenticationGroups ag
JOIN dbo.GroupRoles gr
ON gr.Group_ObjectGUID = ag.Group_ObjectGUID
JOIN dbo.[Role] r
ON r.ID = gr.Role_ID
UNION ALL
SELECT
ag.Authentication_ObjectGUID,
gr.Role_ID,
r.Name,
'GROUP_INHERITED'
FROM dbo.AuthenticationGroups ag
JOIN dbo.GroupClosure gc
ON gc.ChildGroup_ObjectGUID = ag.Group_ObjectGUID
JOIN dbo.GroupRoles gr
ON gr.Group_ObjectGUID = gc.ParentGroup_ObjectGUID
JOIN dbo.[Role] r
ON r.ID = gr.Role_ID;
GO
-- ========================================================
-- 3. EFFECTIVE ROLES (DEDUPLICATED)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationEffectiveRoles AS
SELECT DISTINCT
Authentication_ObjectGUID,
Role_ID,
RoleName
FROM dbo.vAuthenticationRolesExpanded;
GO
-- ========================================================
-- 4. PERMISSIONS (DETAILED WITH ROLE SOURCE)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationPermissionsDetailed AS
SELECT
r.Authentication_ObjectGUID,
r.Role_ID,
r.RoleName,
p.Scope,
p.Resource,
p.Action,
CONCAT(p.Scope,'.',p.Resource,'.',p.Action) AS PermissionKey
FROM dbo.vAuthenticationRolesExpanded r
JOIN dbo.RolePermissions rp
ON rp.Role_ID = r.Role_ID
JOIN dbo.Permission p
ON p.ID = rp.Permission_ID;
GO
-- ========================================================
-- 5. PERMISSION MATRIX (FAST LOOKUP)
-- ========================================================
CREATE OR ALTER VIEW dbo.vPermissionMatrix AS
SELECT DISTINCT
Authentication_ObjectGUID,
CONCAT(Scope,'.',Resource,'.',Action) AS PermissionKey
FROM dbo.vAuthenticationPermissionsDetailed;
GO
-- ========================================================
-- 6. GROUP ROLES OVERVIEW
-- ========================================================
CREATE OR ALTER VIEW dbo.vGroupRolesDetailed AS
SELECT
g.ObjectGUID,
g.Name AS GroupName,
r.ID AS Role_ID,
r.Name AS RoleName
FROM dbo.GroupRoles gr
JOIN dbo.[Group] g
ON g.ObjectGUID = gr.Group_ObjectGUID
JOIN dbo.[Role] r
ON r.ID = gr.Role_ID;
GO
-- ========================================================
-- 7. GROUP HIERARCHY (READABLE)
-- ========================================================
CREATE OR ALTER VIEW dbo.vGroupHierarchyReadable AS
SELECT
parent.ObjectGUID AS ParentGroupGUID,
parent.Name AS ParentGroupName,
child.ObjectGUID AS ChildGroupGUID,
child.Name AS ChildGroupName,
gc.Depth
FROM dbo.GroupClosure gc
JOIN dbo.[Group] parent
ON parent.ObjectGUID = gc.ParentGroup_ObjectGUID
JOIN dbo.[Group] child
ON child.ObjectGUID = gc.ChildGroup_ObjectGUID;
GO
-- ========================================================
-- 8. USER OVERVIEW (ADMIN DASHBOARD)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationOverview AS
SELECT
a.ObjectGUID,
a.sAMAccountName,
a.mail,
a.givenName,
a.sn,
a.active,
a.online,
COUNT(DISTINCT r.Role_ID) AS RoleCount,
COUNT(DISTINCT g.GroupGUID) AS GroupCount
FROM dbo.Authentication a
LEFT JOIN dbo.vAuthenticationRolesExpanded r
ON r.Authentication_ObjectGUID = a.ObjectGUID
LEFT JOIN dbo.vAuthenticationGroupsExpanded g
ON g.Authentication_ObjectGUID = a.ObjectGUID
GROUP BY
a.ObjectGUID,
a.sAMAccountName,
a.mail,
a.givenName,
a.sn,
a.active,
a.online;
GO
-- ========================================================
-- 9. BONUS: PERMISSION TRACE (WHY DOES USER HAVE THIS?)
-- ========================================================
CREATE OR ALTER VIEW dbo.vPermissionTrace AS
SELECT
apd.Authentication_ObjectGUID,
apd.RoleName,
apd.Scope,
apd.Resource,
apd.Action,
apd.PermissionKey
FROM dbo.vAuthenticationPermissionsDetailed apd;
GO

View File

@@ -260,6 +260,9 @@ JOIN dbo.RolePermissions rp ON rp.Role_ID = r.Role_ID
JOIN dbo.Permission p ON p.ID = rp.Permission_ID;
GO
/* =========================================================
FIXED vEventLog (SEQUELIZE MATCH + SYSTEM FIX)
========================================================= */
@@ -413,3 +416,198 @@ SELECT
ID
FROM dbo.[Role]
WHERE Name='ADMIN';
GO
/* =========================================================
EXTENDED RBAC VIEWS
========================================================= */
-- ========================================================
-- 1. USER GROUPS (DIRECT + INHERITED)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationGroupsExpanded AS
SELECT
ag.Authentication_ObjectGUID,
g.ObjectGUID AS GroupGUID,
g.Name AS GroupName,
'DIRECT' AS Source
FROM dbo.AuthenticationGroups ag
JOIN dbo.[Group] g
ON g.ObjectGUID = ag.Group_ObjectGUID
UNION ALL
SELECT
ag.Authentication_ObjectGUID,
gc.ParentGroup_ObjectGUID,
g.Name,
'INHERITED'
FROM dbo.AuthenticationGroups ag
JOIN dbo.GroupClosure gc
ON gc.ChildGroup_ObjectGUID = ag.Group_ObjectGUID
JOIN dbo.[Group] g
ON g.ObjectGUID = gc.ParentGroup_ObjectGUID;
GO
-- ========================================================
-- 2. ROLES (DIRECT + GROUP + HIERARCHY)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationRolesExpanded AS
SELECT
ar.Authentication_ObjectGUID,
ar.Role_ID,
r.Name AS RoleName,
'DIRECT' AS Source
FROM dbo.AuthenticationRoles ar
JOIN dbo.[Role] r
ON r.ID = ar.Role_ID
UNION ALL
SELECT
ag.Authentication_ObjectGUID,
gr.Role_ID,
r.Name,
'GROUP'
FROM dbo.AuthenticationGroups ag
JOIN dbo.GroupRoles gr
ON gr.Group_ObjectGUID = ag.Group_ObjectGUID
JOIN dbo.[Role] r
ON r.ID = gr.Role_ID
UNION ALL
SELECT
ag.Authentication_ObjectGUID,
gr.Role_ID,
r.Name,
'GROUP_INHERITED'
FROM dbo.AuthenticationGroups ag
JOIN dbo.GroupClosure gc
ON gc.ChildGroup_ObjectGUID = ag.Group_ObjectGUID
JOIN dbo.GroupRoles gr
ON gr.Group_ObjectGUID = gc.ParentGroup_ObjectGUID
JOIN dbo.[Role] r
ON r.ID = gr.Role_ID;
GO
-- ========================================================
-- 3. EFFECTIVE ROLES (DEDUPLICATED)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationEffectiveRoles AS
SELECT DISTINCT
Authentication_ObjectGUID,
Role_ID,
RoleName
FROM dbo.vAuthenticationRolesExpanded;
GO
-- ========================================================
-- 4. PERMISSIONS (DETAILED WITH ROLE SOURCE)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationPermissionsDetailed AS
SELECT
r.Authentication_ObjectGUID,
r.Role_ID,
r.RoleName,
p.Scope,
p.Resource,
p.Action,
CONCAT(p.Scope,'.',p.Resource,'.',p.Action) AS PermissionKey
FROM dbo.vAuthenticationRolesExpanded r
JOIN dbo.RolePermissions rp
ON rp.Role_ID = r.Role_ID
JOIN dbo.Permission p
ON p.ID = rp.Permission_ID;
GO
-- ========================================================
-- 5. PERMISSION MATRIX (FAST LOOKUP)
-- ========================================================
CREATE OR ALTER VIEW dbo.vPermissionMatrix AS
SELECT DISTINCT
Authentication_ObjectGUID,
CONCAT(Scope,'.',Resource,'.',Action) AS PermissionKey
FROM dbo.vAuthenticationPermissionsDetailed;
GO
-- ========================================================
-- 6. GROUP ROLES OVERVIEW
-- ========================================================
CREATE OR ALTER VIEW dbo.vGroupRolesDetailed AS
SELECT
g.ObjectGUID,
g.Name AS GroupName,
r.ID AS Role_ID,
r.Name AS RoleName
FROM dbo.GroupRoles gr
JOIN dbo.[Group] g
ON g.ObjectGUID = gr.Group_ObjectGUID
JOIN dbo.[Role] r
ON r.ID = gr.Role_ID;
GO
-- ========================================================
-- 7. GROUP HIERARCHY (READABLE)
-- ========================================================
CREATE OR ALTER VIEW dbo.vGroupHierarchyReadable AS
SELECT
parent.ObjectGUID AS ParentGroupGUID,
parent.Name AS ParentGroupName,
child.ObjectGUID AS ChildGroupGUID,
child.Name AS ChildGroupName,
gc.Depth
FROM dbo.GroupClosure gc
JOIN dbo.[Group] parent
ON parent.ObjectGUID = gc.ParentGroup_ObjectGUID
JOIN dbo.[Group] child
ON child.ObjectGUID = gc.ChildGroup_ObjectGUID;
GO
-- ========================================================
-- 8. USER OVERVIEW (ADMIN DASHBOARD)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationOverview AS
SELECT a.ObjectGUID, a.sAMAccountName, a.mail, a.givenName, a.sn, a.active, a.online, COUNT(DISTINCT r.Role_ID) AS RoleCount, COUNT(DISTINCT g.GroupGUID) AS GroupCount, a.title, a.department, a.streetAddress,
a.telephoneNumber, a.physicalDeliveryOfficeName, a.distinguishedName, dbo.ObjectSource.Name AS ObjectSourceName
FROM dbo.Authentication AS a LEFT OUTER JOIN
dbo.ObjectSource ON a.ObjectSource_ID = dbo.ObjectSource.ID LEFT OUTER JOIN
dbo.vAuthenticationRolesExpanded AS r ON r.Authentication_ObjectGUID = a.ObjectGUID LEFT OUTER JOIN
dbo.vAuthenticationGroupsExpanded AS g ON g.Authentication_ObjectGUID = a.ObjectGUID
GROUP BY a.ObjectGUID, a.sAMAccountName, a.mail, a.givenName, a.sn, a.active, a.online, a.title, a.department, a.streetAddress, a.telephoneNumber, a.physicalDeliveryOfficeName, a.distinguishedName, dbo.ObjectSource.Name
GO
-- ========================================================
-- 8.1. GROUP OVERVIEW (ADMIN DASHBOARD)
-- ========================================================
CREATE OR ALTER VIEW dbo.vGroupOverview AS
SELECT dbo.[Group].ObjectGUID, dbo.[Group].Name, COUNT(DISTINCT ag.Authentication_ObjectGUID) AS UserCount, COUNT(DISTINCT gr.Role_ID) AS RoleCount, dbo.ObjectSource.Name AS ObjectSourceName,
dbo.[Group].distinguishedName
FROM dbo.ObjectSource RIGHT OUTER JOIN
dbo.[Group] ON dbo.ObjectSource.ID = dbo.[Group].ObjectSource_ID LEFT OUTER JOIN
dbo.AuthenticationGroups AS ag ON dbo.[Group].ObjectGUID = ag.Group_ObjectGUID LEFT OUTER JOIN
dbo.GroupRoles AS gr ON dbo.[Group].ObjectGUID = gr.Group_ObjectGUID
GROUP BY dbo.[Group].ObjectGUID, dbo.[Group].Name, dbo.ObjectSource.Name, dbo.[Group].distinguishedName
-- ========================================================
-- 9. BONUS: PERMISSION TRACE (WHY DOES USER HAVE THIS?)
-- ========================================================
CREATE OR ALTER VIEW dbo.vPermissionTrace AS
SELECT
apd.Authentication_ObjectGUID,
apd.RoleName,
apd.Scope,
apd.Resource,
apd.Action,
apd.PermissionKey
FROM dbo.vAuthenticationPermissionsDetailed apd;
GO

View File

@@ -1483,7 +1483,7 @@ window.addEventListener('resize', () => {
},
refresh(){ applyFilters(); render(); },
clearData() { data = [] },
source(newData) { data = []; this.addData(newData); },
source(newData) { data = []; this.addData(newData); this.refresh(); },
prepareData() { prepareData(); }
};
}

View File

@@ -1,46 +1,176 @@
function test() {
function createInput({ id, placeholder }) {
const input = document.createElement('input');
input.type = 'text';
input.id = id;
input.style.width = 'calc(100% - 30px)';
input.placeholder = placeholder;
input.required = true;
return input;
}
const container = document.createElement('div');
container.id = 'rbacAuthCreation';
container.append(
createInput({ id: 'rbacAuthsAMAccountName', placeholder: 'sAMAccountName <Vorname.Nachname>' }),
createInput({ id: 'rbacAuthsMail', placeholder: 'E-Mail' }),
createInput({ id: 'rbacAuthsSn', placeholder: 'Vorname' }),
createInput({ id: 'rbacAuthsGivenName', placeholder: 'Nachname' })
);
feedbox({
title: `<span>Erstelle eine neue Authentifizierung</span>`,
message: container.outerHTML,
buttons: {
cancel: {
text: 'Abbrechen'
},
yes: {
text: '<b>Erstellen</b>',
onClick: () => {
fetch('/api/rbac/auths/create', {
method: 'POST',
body: JSON.stringify({
sAMAccountName: document.getElementById('rbacAuthsAMAccountName').value,
mail: document.getElementById('rbacAuthsMail').value,
sn: document.getElementById('rbacAuthsSn').value,
givenName: document.getElementById('rbacAuthsGivenName').value
})
})
}
const vt = virtualTable({
tableEl: document.querySelector('#rbacUsersTable'),
data: [],
rowHeight: 20,
buffer: 5,
groupKey: 'ObjectSourceName', // optional zum Gruppieren
rowKey: 'ObjectGUID',
filterConfig: {
exceptedColumns: ['Status_ID', 'Anhänge'],
columnModes: {
ID: 'text', Status: 'dropdown', Objekt: 'text', Priorität: 'dropdown',
Erstelldatum: 'text', Gewerk: 'dropdown', Typ: 'dropdown',
Bedarfsmelder: 'text', Bearbeiter: 'text', Genehmiger: 'text',
Status: 'dropdown'
}
},
lock: true
customRender: (row, tr) => {
createTd(tr,
`<button class="redbutton"
${row['ObjectGUID'] === '00000000-0000-0000-0000-000000000001' ?
'disabled data-tooltip="Der Administrator kann nicht gelöscht werden"' :
''
}>X</button>`, {
styles: {
'position': 'sticky',
'left': '0px',
'width': '20px',
'z-index': '2'
}, classes: [
'text-align:left'
], onclick: () => {
sendUserEvent('RBAC', `Benutzer ${row['sn'][0].toUpperCase() + row['sn'].slice(1)}, ${row['givenName'][0].toUpperCase() + row['givenName'].slice(1)} gelöscht`, null, 3);
}
});
createTd(tr, row['ObjectGUID'], { classes: [ 'text-align:left' ], styles: { 'max-width': '100px' }, attributes: { 'data-tooltip': row['ObjectGUID'] } });
createTd(tr, row['sAMAccountName'], { classes: [ 'text-align:left' ], attributes: { 'data-tooltip': row['sAMAccountName'] } });
createTd(tr, row['sn'], { classes: [ 'text-align:left' ], attributes: { 'data-tooltip': row['sn'] } });
createTd(tr, row['givenName'], { classes: [ 'text-align:left' ], attributes: { 'data-tooltip': row['givenName'] } });
createTd(tr, row['mail'], { classes: [ 'text-align:left' ], attributes: { 'data-tooltip': row['mail'] } });
createTd(tr, row['active'], { classes: [ 'text-align:center' ] });
createTd(tr, row['online'], { classes: [ 'text-align:center' ] });
createTd(tr, row['RoleCount'], { classes: [ 'text-align:center' ] });
createTd(tr, row['GroupCount'], { classes: [ 'text-align:center' ] });
createTd(tr, row['ObjectSourceName'], { classes: [ 'text-align:right' ] });
}
});
async function api(url, method = 'GET', body) {
const res = await fetch(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: body ? JSON.stringify(body) : undefined
});
return res.json();
}
async function createUser() {
const name = document.getElementById('newUserName').value;
const sn = name.split('.')[1];
const givenName = name.split('.')[0];
const mail = `${name}@test.com`;
const user = await api('/api/rbac/auth/create', 'POST', {
sAMAccountName: name,
mail: mail,
sn: sn[0].toUpperCase() + sn.slice(1),
givenName: givenName[0].toUpperCase() + givenName.slice(1)
});
if(user) {
sendUserEvent('RBAC', `Benutzer ${sn[0].toUpperCase() + sn.slice(1)}, ${givenName[0].toUpperCase() + givenName.slice(1)} angelegt`, null, 0);
loadUsers();
}
}
async function loadUsers() {
try {
const users = await api('/api/rbac/auth/get', 'POST');
if(users) {
vt.source(users);
return;
}
sendUserEvent('RBAC', 'Benutzer konnten nicht geladen', null, 4);
} catch(err) {
writeEventLog(4, 'RBAC', err);
}
}
async function createGroup() {
const name = document.getElementById('newGroupName').value;
const group = await api('/api/rbac/group/create', 'POST', {
name
});
if(group) {
sendUserEvent('RBAC', `Gruppe ${name} angelegt`, null, 0);
loadGroups();
}
}
// HIER WEITER - GRUPPEN KARTEN MÜSSEN HÜBSCHER WERDEN.
// BENUTZER UND GRUPPEN KÖNNEN NOCH NICHT GELÖSCHT WERDEN.
// GRUPPEN AUCH OBJECTSOURCE_ID 1?
async function loadGroups() {
try {
const rbacGroupContainer = document.getElementById('rbacGroupContainer');
rbacGroupContainer.innerHTML = '';
const groups = await api('/api/rbac/group/get', 'POST');
if(groups) {
let fragment = document.createDocumentFragment();
groups.forEach(group => {
const section = document.createElement('section');
section.innerHTML = `<span>${group.Name}</span><div class="removeButton" onclick="this.parentNode.remove()">X</div>`;
section.dataset.tooltip = group.Name;
fragment.appendChild(section);
});
rbacGroupContainer.innerHTML = '';
rbacGroupContainer.appendChild(fragment);
return;
}
sendUserEvent('RBAC', 'Gruppen konnten nicht geladen', null, 4);
} catch(err) {
writeEventLog(4, 'RBAC', err);
}
}
loadUsers();
loadGroups();
async function createRole() {
const name = document.getElementById('newRoleName').value;
await api('/api/role', 'POST', {
name
});
loadRoles();
}
async function loadRoles() {
document.getElementById('roleList').innerHTML = 'Reload roles...';
}
async function createPermission() {
const scope = document.getElementById('permScope').value;
const resource = document.getElementById('permResource').value;
const action = document.getElementById('permAction').value;
await api('/permission', 'POST', {
scope,
resource,
action
});
alert('Permission created');
}
async function addUserToGroup(authId, groupId) {
await api('/api/rbac/group/add-user', 'POST', {
authId,
groupId
});
}
async function addPermissionToRole(roleId, permissionId) {
await api('/role/add-permission', 'POST', {
roleId,
permissionId
});
}

View File

@@ -18,7 +18,9 @@ input.width\:25px { width:25px; }
*::placeholder, input[id="sAMAccountName"] { font-style:italic; font-weight:100; letter-spacing:3px; }
html, button { font-size: var(--fontSize); font-family: var(--fontFamily); }
button.monolyth, button.bluebutton, button.greenbutton, button.yellowbutton, button.redbutton { display:inline-block; padding:8px 10px; margin:0.2rem 1.6rem; font-weight:600; text-align:center; text-decoration:none; color:rgb(255, 255, 255); border:none; border-radius:8px; box-shadow:0 4px 6px rgba(0,0,0,0.1); transition:all var(--times-transition-colors) ease; }
/* button.monolyth, button.bluebutton, button.greenbutton, button.yellowbutton, button.redbutton { display:inline-block; padding:8px 10px; margin:0.2rem 1.6rem; font-weight:600; text-align:center; text-decoration:none; color:rgb(255, 255, 255); border:none; border-radius:8px; box-shadow:0 4px 6px rgba(0,0,0,0.1); transition:all var(--times-transition-colors) ease; } */
button.monolyth, button.bluebutton, button.greenbutton, button.yellowbutton, button.redbutton { display:inline-block; padding:4px 8px; margin:0px 5px; font-weight:600; text-align:center; text-decoration:none; color:rgb(255, 255, 255); border:none; border-radius:8px; box-shadow:0 4px 6px rgba(0,0,0,0.1); transition:all var(--times-transition-colors) ease; }
button.monolyth { background-color:transparent; }
button:not(:disabled).monolyth:hover { opacity:0.9; }
button.bluebutton { color:var(--theme-button-blue-default-color); background:var(--theme-button-blue-default-backcolor); }
@@ -406,14 +408,23 @@ label { color:var(--muted); display:block; margin-bottom:6px; }
border-bottom:1px solid #eee;
}
button.removeButton {
.removeButton {
border:none;
background:none;
color:#d11a2a;
background:#d11a2a;
color:white;
cursor:var(--theme-cursor-pointer) -16 16, pointer;
/* font-size:14px; */
padding: 0 4px;
border-radius: 47%;
transition: background var(--times-transition-colors) ease, color var(--times-transition-colors) ease;
}
.removeButton:hover {
background:#ec5d4d;
color:white;
}
input[type="file"] {
display:none;
}

View File

@@ -22,7 +22,7 @@ table thead { position:sticky; top:0; z-index:20; }
/* #endregion */
/* echte Tabelle */
table { width:calc(100%); border-spacing:0 5px; }
table { width:calc(100%); border-spacing:0 2px; }
table th, table td { min-width:100px; max-width:250px; overflow:hidden; white-space:nowrap; }
table tr.grouprow:hover { background: rgba(0,0,0,0.05);}
@@ -35,6 +35,7 @@ thead, tbody { display:table-row-group; }
table thead th { padding:5px; }
/* table tbody td { padding:0 5px; } */
/* table tbody td { padding:5px 0px 5px 20px; } */
table tbody td:not(:first-child):not(:last-child), table thead th:not(:first-child):not(:last-child) { border-width:0; border-style:solid; }
table tbody tr.grouprow { font-weight:700; }
@@ -49,20 +50,21 @@ td { overflow:hidden; text-overflow:ellipsis; /* verhindert, dass Inhalt die Zel
border-bottom-width:8px;
border-bottom-style:solid;
display:flex;
justify-content:flex-start;
flex-direction:column;
flex-wrap:wrap;
gap:10px;
flex-direction:row;
gap:0;
position:sticky;
left:0px;
top:0px;
width: 100% !important;
/* z-index:20; */
padding:5px 10px;
padding:0px;
border-radius:var(--border-raduis) var(--border-raduis) 0 0;
justify-content: flex-start;
align-items: center;
flex: 1;
}
.table-filter-container .live-counter { position:absolute; right:18px; margin-left:auto; font-weight:bold; }
.table-filter-container input, .table-filter-container select { padding:5px !important; }
.table-filter-container input { padding:5px !important; }
th.sort-asc::after {

View File

@@ -4,20 +4,107 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#rbacAdmin {
font-family: Arial;
padding: 20px;
}
#rbacGroupContainer {
display: flex;
width: 100%;
height: 100%;
flex: 1;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
align-content: flex-start;
justify-content: flex-start;
}
section {
display:inline-flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 5px;
width: 120px;
border: 1px solid #ccc;
border-radius: 8px;
margin: 0 2px 2px 0;
}
section span {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
input {
margin: 5px;
}
</style>
</head>
<body>
<div class="container grid" style="height:100vh; grid-template-columns: 1fr 1fr;">
<div class="card static" id="rbacEntities">
</div>
<div class="card static" id="rbacEntityContent">
<!-- USERS -->
<div class="container grid" style="grid-template-columns: calc(50% - 8px) calc(50% - 8px);height:100vh;">
<div class="card">
Users <input id="newUserName" placeholder="sAMAccountName" /> <button class="bluebutton" onclick="createUser()">Create User</button>
<div class="table-wrapper fit-table">
<table id="rbacUsersTable">
<thead>
<tr>
<th class="text-align:left"></th>
<th class="text-align:left">ObjectGUID</th>
<th class="text-align:left">sAMAccountName</th>
<th class="text-align:left">Name</th>
<th class="text-align:left">Vorname</th>
<th class="text-align:left">Mail</th>
<th class="text-align:center">Aktiv</th>
<th class="text-align:center">Online</th>
<th class="text-align:center">Rollen</th>
<th class="text-align:center">Gruppen</th>
<th class="text-align:right">Herkunft</th>
</tr>
</thead>
<tbody>
<tr><td colspan="100%">BENUTZER WERDEN GELADEN . . .</td></tr>
</tbody>
</table>
</div>
</div>
<div class="static" style="pointer-events:none;position:absolute; bottom:20px;right:0px;">
<button id="rbacCreateAuthentication" class="yellowbutton" onclick="test()" style="pointer-events:auto">Neuer Benutzer</button>
<!-- GROUPS -->
<div class="card static" style="flex:1 0 100vw;">
<input id="newGroupName" placeholder="Gruppenname" /> <button class="bluebutton" onclick="createGroup()">Create Group</button>
<div id="rbacGroupContainer">
<span>GRUPPEN WERDEN GELADEN . . .</span>
</div>
<input id="newGroupName" placeholder="Group Name" />
<button class="bluebutton" onclick="createGroup()">Create Group</button>
</div>
<!-- ROLES -->
<div class="card">
<h3>Roles</h3>
<div id="roleList"></div>
<input id="newRoleName" placeholder="Role Name" />
<button class="bluebutton" onclick="createRole()">Create Role</button>
</div>
<!-- PERMISSIONS -->
<div class="card">
<h3>Permissions</h3>
<input id="permScope" placeholder="Scope" />
<input id="permResource" placeholder="Resource" />
<input id="permAction" placeholder="Action" />
<button class="bluebutton" onclick="createPermission()">Create Permission</button>
</div>
</div>
</body>
@@ -25,11 +112,5 @@
reloadPluginScript('/javascript/rbacAPI.js');
fetch('/api/rbac/getEntities', { method: 'POST' })
.then(res => res.json())
.then(json => {
});
</script>
</html>

View File

@@ -107,13 +107,16 @@ const server = https.createServer(httpsOptions, app);
databaseModel.set('authenticationGroupsModel', require(`@models/authenticationGroupsModel`)(service.get('sqlManager').getInstance('main')));
databaseModel.set('authenticationRolesModel', require(`@models/authenticationRolesModel`)(service.get('sqlManager').getInstance('main')));
databaseModel.set('groupClosureModel', require(`@models/groupClosureModel`)(service.get('sqlManager').getInstance('main')));
databaseModel.set('groupModel', require(`@models/groupModel`)(service.get('sqlManager').getInstance('main')));
databaseModel.set('group', require(`@models/groupModel`)(service.get('sqlManager').getInstance('main')));
databaseModel.set('groupRolesModel', require(`@models/groupRolesModel`)(service.get('sqlManager').getInstance('main')));
databaseModel.set('objectSourceModel', require(`@models/objectSourceModel`)(service.get('sqlManager').getInstance('main')));
databaseModel.set('permissionModel', require(`@models/permissionModel`)(service.get('sqlManager').getInstance('main')));
databaseModel.set('roleModel', require(`@models/roleModel`)(service.get('sqlManager').getInstance('main')));
databaseModel.set('rolePermissionsModel', require(`@models/rolePermissionsModel`)(service.get('sqlManager').getInstance('main')));
databaseModel.set('authenticationOverviewView', require(`@models/authenticationOverviewView`)(service.get('sqlManager').getInstance('main')));
databaseModel.set('groupOverviewView', require(`@models/groupOverviewView`)(service.get('sqlManager').getInstance('main')));
service.set('rbacManager', new RBACManager(databaseModel, runtimeFile.configuration.live.integration.token.secret));
service.set('authenticationManager', new AuthenticationManager(databaseModel.get('authentication'), runtimeFile.configuration.live.integration.token.secret));

View File

@@ -5,6 +5,7 @@ module.exports = (sequelize) => {
const Authentication = sequelize.define('Authentication', {
ObjectGUID: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false,
},

View File

@@ -0,0 +1,46 @@
const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
const AuthenticationOverview = sequelize.define('AuthenticationOverviewView', {
ObjectGUID: {
type: DataTypes.UUID,
primaryKey: true
},
sAMAccountName: {
type: DataTypes.STRING
},
mail: {
type: DataTypes.STRING
},
givenName: {
type: DataTypes.STRING
},
sn: {
type: DataTypes.STRING
},
active: {
type: DataTypes.BOOLEAN
},
online: {
type: DataTypes.BOOLEAN
},
RoleCount: {
type: DataTypes.INTEGER
},
GroupCount: {
type: DataTypes.INTEGER
},
ObjectSourceName: {
type: DataTypes.STRING
}
}, {
tableName: 'vAuthenticationOverview',
schema: 'dbo',
timestamps: false,
// 🔥 WICHTIG für Views
freezeTableName: true
});
return AuthenticationOverview;
};

View File

@@ -4,7 +4,9 @@ module.exports = (sequelize) => {
const Group = sequelize.define('Group', {
ObjectGUID: {
type: DataTypes.UUID,
primaryKey: true
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
Name: DataTypes.STRING(255),
ObjectSource_ID: DataTypes.INTEGER,

View File

@@ -0,0 +1,39 @@
const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
const GroupOverview = sequelize.define('GroupOverviewView', {
ObjectGUID: {
type: DataTypes.UUID,
primaryKey: true
},
Name: {
type: DataTypes.STRING
},
UserCount: {
type: DataTypes.INTEGER
},
RoleCount: {
type: DataTypes.INTEGER
},
ObjectSourceName: {
type: DataTypes.STRING
},
distinguishedName: {
type: DataTypes.STRING
}
}, {
tableName: 'vGroupOverview',
schema: 'dbo',
timestamps: false,
freezeTableName: true
});
return GroupOverview;
};

View File

@@ -2,7 +2,7 @@ const { exec } = require('child_process');
const fs = require('fs');
const path = require('path');
const { localPath, cache, runtimeFile } = require('@root/globalize.js');
let rbacUsers, rbacGroups, rbacRoles, rbacPermissions = [];
module.exports = {
route(app, service) {
@@ -76,205 +76,6 @@ module.exports = {
});
// =========================================================
// 👤 AUTH
// =========================================================
app.post('/api/rbac/auth/create', async (req, res) => {
try {
const user = await rbac.createAuth(req.body);
res.json(user);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.put('/api/rbac/auth/:id', async (req, res) => {
try {
await rbac.updateAuth(req.params.id, req.body);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.delete('/api/rbac/auth/:id', async (req, res) => {
try {
await rbac.deleteAuth(req.params.id);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// =========================================================
// 👥 GROUPS
// =========================================================
app.post('/api/rbac/group/create', async (req, res) => {
try {
const group = await rbac.createGroup(req.body);
res.json(group);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.put('/api/rbac/group/:id', async (req, res) => {
try {
await rbac.updateGroup(req.params.id, req.body);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.delete('/api/rbac/group/:id', async (req, res) => {
try {
await rbac.deleteGroup(req.params.id);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// =========================================================
// 🔗 USER ↔ GROUP
// =========================================================
app.post('/api/rbac/group/add-user', async (req, res) => {
try {
const { authId, groupId } = req.body;
await rbac.addUserToGroup(authId, groupId);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.post('/api/rbac/group/remove-user', async (req, res) => {
try {
const { authId, groupId } = req.body;
await rbac.removeUserFromGroup(authId, groupId);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// =========================================================
// 🎭 ROLES
// =========================================================
app.post('/api/rbac/role/get', async (req, res) => {
try {
const role = await rbac.createRole(req.body);
res.json(role);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.put('/api/rbac/role/:id', async (req, res) => {
try {
await rbac.updateRole(req.params.id, req.body);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.delete('/api/rbac/role/:id', async (req, res) => {
try {
await rbac.deleteRole(req.params.id);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// =========================================================
// 🔗 ROLE ASSIGNMENTS
// =========================================================
app.post('/api/rbac/role/assign-user', async (req, res) => {
try {
const { authId, roleId } = req.body;
await rbac.assignRoleToUser(authId, roleId);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.post('/api/rbac/role/assign-group', async (req, res) => {
try {
const { groupId, roleId } = req.body;
await rbac.assignRoleToGroup(groupId, roleId);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// =========================================================
// 🔐 PERMISSIONS
// =========================================================
app.post('/permission', async (req, res) => {
try {
const perm = await rbac.createPermission(req.body);
res.json(perm);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.put('/permission/:id', async (req, res) => {
try {
await rbac.updatePermission(req.params.id, req.body);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.delete('/permission/:id', async (req, res) => {
try {
await rbac.deletePermission(req.params.id);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// =========================================================
// 🔗 ROLE ↔ PERMISSION
// =========================================================
app.post('/api/rbac/role/add-permission', async (req, res) => {
try {
const { roleId, permissionId } = req.body;
await rbac.addPermissionToRole(roleId, permissionId);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.post('/api/rbac/role/remove-permission', async (req, res) => {
try {
const { roleId, permissionId } = req.body;
await rbac.removePermissionFromRole(roleId, permissionId);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.post('/api/plugins/activation', async (req, res) => {
const { name, state } = req.body;
let result = null;
@@ -288,6 +89,260 @@ module.exports = {
service.get('socketManager').broadcast('/', 'plugin_status', result);
res.status(200).json(result);
});
// =========================================================
// 👤 AUTH
// =========================================================
app.post('/api/rbac/auth/get', async (req, res) => {
try {
rbacUsers = await service.get('rbacManager').getAuth();
res.json(rbacUsers);
} catch (err) {
service.get('eventManager').writeLog(req.cookies.ObjectGUID, 4, 'RBAC', err);
res.status(500).json({ error: err.message });
}
})
app.post('/api/rbac/auth/create', async (req, res) => {
try {
if(rbacUsers.map(user => user.sAMAccountName.toLowerCase() ).includes(req.body.sAMAccountName.toLowerCase())) {
service.get('eventManager').writeLog(req.cookies.ObjectGUID, 2, 'RBAC', `${req.body.sAMAccountName} nicht angelegt.\r\nBenutzer existiert bereits`);
return res.status(400).json({ error: `${req.body.sAMAccountName} existiert bereits` });
}
const user = await service.get('rbacManager').createAuth(req.body);
res.json(user);
} catch (err) {
service.get('eventManager').writeLog(null, 4, 'RBAC', err.message);
res.status(500).json({ error: err.message });
}
});
app.put('/api/rbac/auth/:id', async (req, res) => {
try {
await service.get('rbacManager').updateAuth(req.params.id, req.body);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.delete('/api/rbac/auth/:id', async (req, res) => {
try {
await service.get('rbacManager').deleteAuth(req.params.id);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// =========================================================
// 👥 GROUPS
// =========================================================
app.post('/api/rbac/group/get', async (req, res) => {
try {
rbacGroups = await service.get('rbacManager').getGroup();
res.json(rbacGroups);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.post('/api/rbac/group/create', async (req, res) => {
try {
if(rbacGroups.map(group => group.Name.toLowerCase()).includes(req.body.name.toLowerCase())) {
service.get('eventManager').writeLog(req.cookies.ObjectGUID, 2, 'RBAC', `${req.body.name} nicht angelegt.\r\nGruppe existiert bereits`);
return res.status(400).json({ error: `${req.body.name} existiert bereits` });
}
const group = await service.get('rbacManager').createGroup(req.body);
res.json(group);
} catch (err) {
service.get('eventManager').writeLog(null, 4, 'RBAC', err.message);
res.status(500).json({ error: err.message });
}
});
app.put('/api/rbac/group/:id', async (req, res) => {
try {
await service.get('rbacManager').updateGroup(req.params.id, req.body);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.delete('/api/rbac/group/:id', async (req, res) => {
try {
await service.get('rbacManager').deleteGroup(req.params.id);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// =========================================================
// 🔗 USER ↔ GROUP
// =========================================================
app.post('/api/rbac/group/add-user', async (req, res) => {
try {
const { authId, groupId } = req.body;
await service.get('rbacManager').addUserToGroup(authId, groupId);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.post('/api/group/remove-user', async (req, res) => {
try {
const { authId, groupId } = req.body;
await service.get('rbacManager').removeUserFromGroup(authId, groupId);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// =========================================================
// 🎭 ROLES
// =========================================================
app.post('/api/role', async (req, res) => {
try {
const role = await service.get('rbacManager').createRole(req.body);
res.json(role);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.put('/role/:id', async (req, res) => {
try {
await service.get('rbacManager').updateRole(req.params.id, req.body);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.delete('/role/:id', async (req, res) => {
try {
await service.get('rbacManager').deleteRole(req.params.id);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// =========================================================
// 🔗 ROLE ASSIGNMENTS
// =========================================================
app.post('/role/assign-user', async (req, res) => {
try {
const { authId, roleId } = req.body;
await service.get('rbacManager').assignRoleToUser(authId, roleId);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.post('/role/assign-group', async (req, res) => {
try {
const { groupId, roleId } = req.body;
await service.get('rbacManager').assignRoleToGroup(groupId, roleId);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// =========================================================
// 🔐 PERMISSIONS
// =========================================================
app.post('/permission', async (req, res) => {
try {
const perm = await service.get('rbacManager').createPermission(req.body);
res.json(perm);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.put('/permission/:id', async (req, res) => {
try {
await service.get('rbacManager').updatePermission(req.params.id, req.body);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.delete('/permission/:id', async (req, res) => {
try {
await service.get('rbacManager').deletePermission(req.params.id);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// =========================================================
// 🔗 ROLE ↔ PERMISSION
// =========================================================
app.post('/role/add-permission', async (req, res) => {
try {
const { roleId, permissionId } = req.body;
await service.get('rbacManager').addPermissionToRole(roleId, permissionId);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.post('/api/role/remove-permission', async (req, res) => {
try {
const { roleId, permissionId } = req.body;
await service.get('rbacManager').removePermissionFromRole(roleId, permissionId);
res.json({ ok: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.post('/api/plugins/getAll', async (req, res) => {
try {

View File

@@ -237,11 +237,16 @@ class RBACManager {
//#region CRUD
// =========================================================
// 👤 AUTH CRUD
// =========================================================
// =========================================================
// 👤 AUTH CRUD
// =========================================================
async createAuth(data) {
async getAuth() {
const Auth = this.db.get('authenticationOverviewView');
return await Auth.findAll({ raw: true });
}
async createAuth(data) {
const Auth = this.db.get('authentication');
return await Auth.create({
@@ -249,69 +254,73 @@ class RBACManager {
mail: data.mail,
sn: data.sn,
givenName: data.givenName,
ObjectSource_ID: 1,
active: true
});
}
}
async updateAuth(id, data) {
async updateAuth(id, data) {
const Auth = this.db.get('authentication');
return await Auth.update(data, {
where: { ObjectGUID: id }
});
}
}
async deleteAuth(id) {
async deleteAuth(id) {
const Auth = this.db.get('authentication');
return await Auth.destroy({
where: { ObjectGUID: id }
});
}
}
// =========================================================
// 👥 GROUP CRUD
// =========================================================
// =========================================================
// 👥 GROUP CRUD
// =========================================================
async getGroup() {
const group = this.db.get('groupOverviewView');
return await group.findAll({ raw: true }) || [];
}
async createGroup(data) {
const Group = this.db.get('groupsModel');
return await Group.create({
async createGroup(data) {
const group = this.db.get('group');
return await group.create({
Name: data.name,
Description: data.description || null
ObjectSource_ID: 1
});
}
}
async updateGroup(id, data) {
const Group = this.db.get('groupsModel');
async updateGroup(id, data) {
const Group = this.db.get('group');
return await Group.update(data, {
where: { ObjectGUID: id }
});
}
}
async deleteGroup(id) {
const Group = this.db.get('groupsModel');
async deleteGroup(id) {
const Group = this.db.get('group');
return await Group.destroy({
where: { ObjectGUID: id }
});
}
}
// =========================================================
// 🔗 AUTH ↔ GROUP RELATION
// =========================================================
// =========================================================
// 🔗 AUTH ↔ GROUP RELATION
// =========================================================
async addUserToGroup(authId, groupId) {
async addUserToGroup(authId, groupId) {
const AuthGroups = this.db.get('authenticationGroupsModel');
return await AuthGroups.create({
Authentication_ObjectGUID: authId,
Group_ObjectGUID: groupId
});
}
}
async removeUserFromGroup(authId, groupId) {
async removeUserFromGroup(authId, groupId) {
const AuthGroups = this.db.get('authenticationGroupsModel');
return await AuthGroups.destroy({
@@ -320,60 +329,60 @@ class RBACManager {
Group_ObjectGUID: groupId
}
});
}
}
// =========================================================
// 🎭 ROLE CRUD
// =========================================================
// =========================================================
// 🎭 ROLE CRUD
// =========================================================
async createRole(data) {
async createRole(data) {
const Role = this.db.get('rolesModel');
return await Role.create({
Name: data.name,
Description: data.description || null
});
}
}
async updateRole(id, data) {
async updateRole(id, data) {
const Role = this.db.get('rolesModel');
return await Role.update(data, {
where: { ID: id }
});
}
}
async deleteRole(id) {
async deleteRole(id) {
const Role = this.db.get('rolesModel');
return await Role.destroy({
where: { ID: id }
});
}
}
// =========================================================
// 🔗 ROLE ASSIGNMENTS
// =========================================================
// =========================================================
// 🔗 ROLE ASSIGNMENTS
// =========================================================
async assignRoleToUser(authId, roleId) {
async assignRoleToUser(authId, roleId) {
const AuthRoles = this.db.get('authenticationRolesModel');
return await AuthRoles.create({
Authentication_ObjectGUID: authId,
Role_ID: roleId
});
}
}
async assignRoleToGroup(groupId, roleId) {
async assignRoleToGroup(groupId, roleId) {
const GroupRoles = this.db.get('groupRolesModel');
return await GroupRoles.create({
Group_ObjectGUID: groupId,
Role_ID: roleId
});
}
}
async removeRoleFromUser(authId, roleId) {
async removeRoleFromUser(authId, roleId) {
const AuthRoles = this.db.get('authenticationRolesModel');
return await AuthRoles.destroy({
@@ -382,13 +391,13 @@ class RBACManager {
Role_ID: roleId
}
});
}
}
// =========================================================
// 🔐 PERMISSION CRUD
// =========================================================
// =========================================================
// 🔐 PERMISSION CRUD
// =========================================================
async createPermission(data) {
async createPermission(data) {
const Permission = this.db.get('permissionModel');
return await Permission.create({
@@ -396,38 +405,38 @@ class RBACManager {
Resource: data.resource,
Action: data.action
});
}
}
async updatePermission(id, data) {
async updatePermission(id, data) {
const Permission = this.db.get('permissionModel');
return await Permission.update(data, {
where: { ID: id }
});
}
}
async deletePermission(id) {
async deletePermission(id) {
const Permission = this.db.get('permissionModel');
return await Permission.destroy({
where: { ID: id }
});
}
}
// =========================================================
// 🔗 ROLE ↔ PERMISSION
// =========================================================
// =========================================================
// 🔗 ROLE ↔ PERMISSION
// =========================================================
async addPermissionToRole(roleId, permissionId) {
async addPermissionToRole(roleId, permissionId) {
const RolePerms = this.db.get('rolePermissionsModel');
return await RolePerms.create({
Role_ID: roleId,
Permission_ID: permissionId
});
}
}
async removePermissionFromRole(roleId, permissionId) {
async removePermissionFromRole(roleId, permissionId) {
const RolePerms = this.db.get('rolePermissionsModel');
return await RolePerms.destroy({
@@ -436,8 +445,8 @@ class RBACManager {
Permission_ID: permissionId
}
});
}
//#endregio
}
//#endregion
}
module.exports = RBACManager;