add rbac roles

This commit is contained in:
2026-05-01 10:50:12 +00:00
parent 76a30fc94f
commit e208ef1759
6 changed files with 99 additions and 406 deletions

View File

@@ -39,7 +39,7 @@ const RBAC = {
// 🎭 ROLES
loadRoles: () => api('/api/rbac/role/get', 'POST'),
createRole: (name) => api('/api/rbac/role', 'POST', { name }),
createRole: (name) => api('/api/rbac/role/create', 'POST', { name }),
deleteRole: (id) => api(`/api/rbac/role/${id}`, 'DELETE'),
// 🔗 ASSIGNMENTS
@@ -53,15 +53,15 @@ const RBAC = {
// 🖱️ DRAG & DROP
//////////////////////////////
function createDragZone(el, data) {
function createDragZone(el, data, type) {
el.draggable = true;
el.addEventListener('dragstart', (evt) => {
evt.dataTransfer.setData('application/json', JSON.stringify(data));
evt.dataTransfer.setData('application/json', JSON.stringify( { ...data, type }));
});
}
function createDropZone(el, type, target) {
const targetValue = target.ObjectGUID || target.Role_ID || target.Permission_ID;
const targetValue = target.ObjectGUID || target.ID || target.Role_ID || target.Permission_ID;
let process = { action: null, response: null, failure: false };
el.addEventListener('dragover', e => e.preventDefault());
@@ -72,39 +72,45 @@ function createDropZone(el, type, target) {
e.dataTransfer.getData('application/json')
);
if(!targetValue) {
if(!targetValue || !data.type) {
sendUserEvent('RBAC', 'Deinem Drop-Ziel wurde kein ID-Attribut zugewiesen. Frag einfach Manuel ', null, 2);
return;
}
// NOCH NICHT UNTER ADMINROUTES EDITIERT: WENN BENUTZER/GRUPPE BEREITS IN ROLLE ENTHALTEN IST
switch (type) {
case 'group':
process.action = `Du hast den Benutzer der Gruppe hinzugefügt`;
process.response = await RBAC.addUserToGroup(data.ObjectGUID, targetValue);
loadUsers();
loadGroups();
if(data.type === 'user') {
process.action = `Du hast den Benutzer der Gruppe hinzugefügt`;
process.response = await RBAC.addUserToGroup(data.ObjectGUID, targetValue);
}
break;
case 'role':
process.action = `Du hast den Benutzer der Rolle hinzugefügt`;
process.response = await RBAC.addUserToRole(data.ObjectGUID, targetValue);
break;
case 'group-to-role':
process.action = `Du hast die Gruppe der Rolle hinzugefügt`;
process.response = await RBAC.addGroupToRole(data.ObjectGUID, targetValue);
break;
if(data.type === 'user') {
process.action = `Du hast den Benutzer der Rolle hinzugefügt`;
process.response = await RBAC.addUserToRole(data.ObjectGUID, targetValue);
break;
}
if(data.type === 'group') {
process.action = `Du hast die Gruppe der Rolle hinzugefügt`;
process.response = await RBAC.addGroupToRole(data.ObjectGUID, targetValue);
break;
}
case 'permission':
process.action = `Du hast den Berechtigung der Rolle hinzugefügt`;
process.action = `Du hast die Berechtigung der Rolle hinzugefügt`;
process.response = await RBAC.addPermissionToRole(targetValue, data.ID);
break;
}
if(process.failure) return;
if(process.failure || !process.action) return;
loadUsers();
loadGroups();
loadRoles();
sendUserEvent('RBAC', process.action, null, 0);
});
}
//////////////////////////////
// 📋 TABLE (USERS)
//////////////////////////////
@@ -127,7 +133,7 @@ const rbacVT = virtualTable({
customRender: (row, tr) => {
createDragZone(tr, row);
createDragZone(tr, row, 'user');
tr.addEventListener('contextmenu', (evt) => {
evt.preventDefault();
@@ -209,7 +215,7 @@ async function loadGroups() {
};
section.append(removeButton);
createDragZone(section, group, 'group');
createDropZone(section, 'group', group);
fragment.appendChild(section);
@@ -243,7 +249,7 @@ async function loadRoles() {
const section = document.createElement('section');
const roleName = document.createElement('span');
roleName.innerHTML = role.Name;
roleName.innerHTML = `[${role.UserCount}][${role.GroupCount}] ${role.Name}`;
roleName.dataset.tooltip = role.Name;
section.append(roleName);
@@ -258,12 +264,7 @@ async function loadRoles() {
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);
createDropZone(section, 'role', role);
fragment.appendChild(section);
});
@@ -384,336 +385,3 @@ loadUsers();
loadGroups();
loadRoles();
// const ctx = new ContextMenu();
// const vt = virtualTable({
// tableEl: document.querySelector('#rbacUsersTable'),
// data: [],
// rowHeight: 20,
// buffer: 5,
// groupKey: 'ObjectSourceName', // optional zum Gruppieren
// rowKey: 'ObjectGUID',
// filterConfig: {
// hideCounter: true,
// exceptedColumns: ['', 'Rollen', 'Gruppen'],
// columnModes: {
// Aktiv: 'dropdown',
// Online: 'dropdown'
// }
// },
// customRender: (row, tr) => {
// tr.draggable = true;
// tr.dataset.guid = row['ObjectGUID'];
// tr.dataset.sAMAccountName = row['sAMAccountName'];
// tr.ondragstart = (evt) => {
// const data = {
// guid: tr.dataset.guid,
// sAMAccountName: tr.dataset.sAMAccountName
// };
// evt.dataTransfer.setData('application/json', JSON.stringify(data));
// };
// tr.oncontextmenu = async evt => {
// if (evt.target.tagName === 'BUTTON') return;
// ctx.setItems([ { label: "Details", onClick: () => showAuthDetails(row['ObjectGUID']) } ]);
// evt.preventDefault();
// ctx.show(evt.pageX + 5, {y: evt.pageY + 5 });
// };
// 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: () => {
// if(row['ObjectGUID'] === '00000000-0000-0000-0000-000000000001') return;
// deleteUser(row['ObjectGUID'], row['sAMAccountName']);
// }
// });
// 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' ] });
// }
// });
// 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 showAuthDetails(guid) {
// const details = await api(`/api/rbac/auth/details/${guid}`)
// if(!details) return;
// feedbox({
// title: `<span>Details</span>`,
// message: Object.entries(details).map(([key, value]) => /*html*/`<p><b>${key}:</b><span class="selectable">${value}</span></p>`).join(''),
// buttons: {
// yes: {
// text: 'Schließen'
// }
// },
// lock: true,
// primary: 'yes'
// })
// }
// async function createUser() {
// const name = document.getElementById('newUserName').value;
// if(!name || !name.includes('.')) {
// sendUserEvent('RBAC', 'Der sAMAccountName muss einen Punkt enthalten<br>Der Benutzer wurde nicht angelegt', null, 2);
// return;
// }
// 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 deleteUser(guid, sAMAccountName) {
// feedbox({
// title: `<span>Benutzer löschen</span>`,
// message: `
// <p>Möchtest du den Benutzer <b style="color:red;">${sAMAccountName} [${guid}]</b> wirklich löschen</p>
// `,
// buttons: {
// no: {
// text: 'Nein'
// },
// yes: {
// text: '<b>Ja</b>',
// onClick: async () => {
// const user = await api(`/api/rbac/auth/${guid}`, 'DELETE', {
// guid
// });
// if(user) {
// loadUsers();
// sendUserEvent('RBAC', `Benutzer ${user.sAMAccountName || ''} [${user.ObjectGUID}] gelöscht`, null, 0);
// }
// }
// }
// }
// });
// }
// 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();
// }
// }
// async function deleteGroup(guid, name) {
// feedbox({
// title: `<span>Gruppe löschen</span>`,
// message: `
// <p>Möchtest du die Gruppe <b style="color:red;">${name} [${guid}]</b> wirklich löschen</p>
// `,
// buttons: {
// no: {
// text: 'Nein'
// },
// yes: {
// text: '<b>Ja</b>',
// onClick: async () => {
// const group = await api(`/api/rbac/group/${guid}`, 'DELETE', {
// guid
// });
// if(group) {
// sendUserEvent('RBAC', `Gruppe ${group.Name || ''} [${group.ObjectGUID}] gelöscht`, null, 0);
// loadGroups();
// }
// }
// }
// }
// });
// // 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');
// createDropZone(section, 'group', group.ObjectGUID);
// section.innerHTML = `<span>${group.Name}</span><div class="removeButton" onclick="deleteGroup('${group.ObjectGUID}', '${group.Name}')">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');
// }
// function createDropZone(element, direction, keyAttribute) {
// element.addEventListener('dragover', (evt) => {
// evt.preventDefault();
// });
// // 📥 Drop verarbeiten
// element.addEventListener('drop', (evt) => {
// evt.preventDefault();
// const attributeValue = element.dataset[keyAttribute]; // ObjectGuid or ID
// const data = JSON.parse(
// evt.dataTransfer.getData('application/json')
// );
// switch (direction) {
// case 'user-to-group':
// addUserToGroup(data.guid, attributeValue);
// break;
// case 'user-to-role':
// addPermissionToRole(data.guid, attributeValue);
// break;
// case 'group-to-role':
// addGroupToRole(data.guid, attributeValue);
// break;
// case 'permission-to-role':
// addPermissionToRole(data.roleId, attributeValue)
// default:
// break;
// }
// });
// }
// async function addUserToGroup(authGuid, groupGuid) {
// await api('/api/rbac/group/add-user', 'POST', {
// authGuid,
// groupGuid
// });
// }
// async function addUserToRole(authGuid, roleId) {
// await api('/api/rbac/role/add-user', 'POST', {
// authGuid,
// roleId
// });
// }
// async function addGroupToRole(groupGuid, roleId) {
// await api('/api/rbac/role/add-group', 'POST', {
// groupGuid,
// roleId
// });
// }
// async function addPermissionToRole(roleId, permissionId) {
// await api('/api/rbac/role/add-permission', 'POST', {
// roleId,
// permissionId
// });
// }

View File

@@ -99,7 +99,7 @@ input {
<!-- ROLES -->
<div class="card" style="min-width:300px;flex:1 1 calc(300px)">
<input id="newRoleName" placeholder="Role Name" />
<input id="newRoleName" placeholder="Rollenname" />
<button class="bluebutton" onclick="createRole()">Create Role</button>
<div id="rbacRoleContainer">