rbac roles implementation

This commit is contained in:
2026-04-30 14:22:12 +02:00
parent 6679ed20fe
commit 76a30fc94f
7 changed files with 190 additions and 43 deletions

View File

@@ -22,7 +22,6 @@ const api = async (url, method = 'GET', body) => {
//////////////////////////////
const RBAC = {
// 👤 USERS
loadUsers: async () => (await api('/api/rbac/auth/get', 'POST'))
.map(({ active, online, ...rest }) => ({
@@ -30,31 +29,24 @@ const RBAC = {
Aktiv: active
}))
.sort((a, b) => a.sAMAccountName.localeCompare(b.sAMAccountName)),
createUser: (data) => api('/api/rbac/auth/create', 'POST', data),
deleteUser: (guid) => api(`/api/rbac/auth/${guid}`, 'DELETE'),
// 👥 GROUPS
loadGroups: () => api('/api/rbac/group/get', 'POST'),
createGroup: (name) => api('/api/rbac/group/create', 'POST', { name }),
deleteGroup: (guid) => api(`/api/rbac/group/${guid}`, 'DELETE'),
// 🎭 ROLES
loadRoles: () => api('/api/rbac/role/get', 'POST'),
createRole: (name) => api('/api/rbac/role', 'POST', { name }),
deleteRole: (id) => api(`/api/rbac/role/${id}`, 'DELETE'),
// 🔗 ASSIGNMENTS
addUserToGroup: (authGuid, groupGuid) =>
api('/api/rbac/group/add-user', 'POST', { authGuid, groupGuid }),
addUserToRole: (authGuid, roleId) =>
api('/api/rbac/role/add-user', 'POST', { authGuid, roleId }),
addGroupToRole: (groupGuid, roleId) =>
api('/api/rbac/role/add-group', 'POST', { groupGuid, roleId }),
addPermissionToRole: (roleId, permissionId) =>
api('/api/rbac/role/add-permission', 'POST', { roleId, permissionId })
addUserToGroup: (authGuid, groupGuid) => api('/api/rbac/group/add-user', 'POST', { authGuid, groupGuid }),
addUserToRole: (authGuid, roleId) => api('/api/rbac/role/add-user', 'POST', { authGuid, roleId }),
addGroupToRole: (groupGuid, roleId) => api('/api/rbac/role/add-group', 'POST', { groupGuid, roleId }),
addPermissionToRole: (roleId, permissionId) => api('/api/rbac/role/add-permission', 'POST', { roleId, permissionId })
};
//////////////////////////////
@@ -90,6 +82,7 @@ function createDropZone(el, type, target) {
process.action = `Du hast den Benutzer der Gruppe hinzugefügt`;
process.response = await RBAC.addUserToGroup(data.ObjectGUID, targetValue);
loadUsers();
loadGroups();
break;
case 'role':
process.action = `Du hast den Benutzer der Rolle hinzugefügt`;
@@ -116,7 +109,7 @@ function createDropZone(el, type, target) {
// 📋 TABLE (USERS)
//////////////////////////////
const vt = virtualTable({
const rbacVT = virtualTable({
tableEl: document.querySelector('#rbacUsersTable'),
data: [],
rowHeight: 20,
@@ -184,7 +177,7 @@ const vt = virtualTable({
async function loadUsers() {
try {
vt.source(await RBAC.loadUsers());
rbacVT.source(await RBAC.loadUsers());
} catch (err) {
console.error(err);
}
@@ -193,29 +186,29 @@ async function loadUsers() {
async function loadGroups() {
const container = document.getElementById('rbacGroupContainer');
container.innerHTML = '';
const groups = await RBAC.loadGroups();
const fragment = document.createDocumentFragment();
groups.forEach(group => {
const section = document.createElement('section');
const groupName = document.createElement('span');
groupName.innerHTML = group.Name;
groupName.innerHTML = `[${group.UserCount}] ${group.Name}`;
groupName.dataset.tooltip = group.Name;
groupName.dataset.tooltipMode = 'ellipsis';
section.append(groupName);
if(group.ObjectGUID !== '00000000-0000-0000-0000-000000000001') {
const removeButton = document.createElement('div');
removeButton.className = 'removeButton';
removeButton.innerHTML = 'X';
removeButton.onclick = async () => {
await deleteGroup(group.ObjectGUID, group.Name);
};
section.append(removeButton);
const removeButton = document.createElement('button');
if(group.ObjectGUID === '00000000-0000-0000-0000-000000000001') {
removeButton.disabled = true;
removeButton.dataset.tooltip = `Die Gruppe ${group.Name} kann nicht gelöscht werden`;
}
removeButton.className = 'removeButton';
removeButton.innerHTML = 'X';
removeButton.onclick = async () => {
await deleteGroup(group.ObjectGUID, group.Name);
};
section.append(removeButton);
createDropZone(section, 'group', group);
@@ -236,6 +229,49 @@ async function createGroup() {
}
}
async function loadRoles() {
const container = document.getElementById('rbacRoleContainer');
container.innerHTML = '';
const roles = await RBAC.loadRoles();
const fragment = document.createDocumentFragment();
roles.forEach(role => {
const section = document.createElement('section');
const roleName = document.createElement('span');
roleName.innerHTML = role.Name;
roleName.dataset.tooltip = role.Name;
section.append(roleName);
const removeButton = document.createElement('button');
removeButton.className = 'removeButton';
removeButton.innerHTML = 'X';
removeButton.onclick = async () => {
await deleteRole(role.ID, role.Name);
};
section.append(removeButton);
// 🔥 DROP ZONES
createDropZone(section, 'role', role); // User → Role
createDropZone(section, 'group-to-role', role); // Group → Role
// optional: permissions
createDropZone(section, 'permission', role);
fragment.appendChild(section);
});
container.appendChild(fragment);
}
//////////////////////////////
// 👤 USER ACTIONS
//////////////////////////////
@@ -301,6 +337,44 @@ async function deleteGroup(guid, name) {
}
//////////////////////////////
// 🎭 ROLE ACTIONS
//////////////////////////////
async function createRole() {
const name = document.getElementById('newRoleName').value;
if (!name) return;
const role = await RBAC.createRole(name);
sendUserEvent('RBAC', `Rolle ${name} angelegt`, null, 0);
loadRoles();
}
async function deleteRole(id, name) {
feedbox({
title: `<span>Rolle löschen</span>`,
message: `Möchtest du die Rolle <b style="color:red;">${name}</b> wirklich löschen`,
buttons: {
no: { text: 'Nein' },
yes: {
text: '<b style=color:red>Ja</b>',
onClick: async () => {
await RBAC.deleteRole(id);
sendUserEvent('RBAC', `Rolle ${name} gelöscht`, null, 0);
loadRoles();
loadUsers(); // optional, falls RoleCount betroffen
}
}
}
});
}
//////////////////////////////
// 🚀 INIT
@@ -308,7 +382,7 @@ async function deleteGroup(guid, name) {
loadUsers();
loadGroups();
loadRoles();
// const ctx = new ContextMenu();

View File

@@ -36,6 +36,7 @@ section {
transition: background var(--times-transition-colors) ease, border-color var(--times-transition-colors) ease, color var(--times-transition-colors) ease;
}
section:hover {
background: var(--theme-accent-hover-backcolor);
color: var(--theme-accent-hover-color);
@@ -101,7 +102,7 @@ input {
<input id="newRoleName" placeholder="Role Name" />
<button class="bluebutton" onclick="createRole()">Create Role</button>
<div id="rbacGroupContainer">
<div id="rbacRoleContainer">
<span>ROLLEN WERDEN GELADEN . . .</span>
</div>
</div>