rbac and licenses
This commit is contained in:
@@ -18,7 +18,7 @@ const ctx = new ContextMenu();
|
||||
const windowCleanup = new Map();
|
||||
const username = getCookie('sAMAccountName');
|
||||
const LS_KEY = (key) => `${username}:${key}`;
|
||||
const MAX_PADDING = { left: 4, top: 4, right: 4, bottom: (56 - 4) };
|
||||
let MAX_PADDING = { left: 4, top: 4, right: 4, bottom: 40 };
|
||||
|
||||
startBtn.addEventListener('click', (evt) => {
|
||||
evt.stopPropagation(); // verhindert sofortiges Schließen
|
||||
@@ -28,13 +28,19 @@ startBtn.addEventListener('click', (evt) => {
|
||||
|
||||
function updateStartMenuPosition() {
|
||||
const height = taskbar.offsetHeight;
|
||||
startMenu.style.bottom = (height + 5) + 'px';
|
||||
startMenu.style.bottom = (height + 12) + 'px';
|
||||
}
|
||||
|
||||
const observer = new ResizeObserver(entries => {
|
||||
for (let entry of entries) {
|
||||
const height = entry.contentRect.height;
|
||||
document.documentElement.style.setProperty('--auto-taskbar-height', height + 'px');
|
||||
MAX_PADDING = { left: 4, top: 4, right: 4, bottom: height + 8 };
|
||||
|
||||
windowsContainer.querySelectorAll('[data-winid]').forEach(win => {
|
||||
if(win.dataset.state === 'maximized') {
|
||||
applyMaximized(win) ;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -42,6 +42,11 @@ const RBAC = {
|
||||
createRole: (name) => api('/api/rbac/role/create', 'POST', { name }),
|
||||
deleteRole: (id) => api(`/api/rbac/role/${id}`, 'DELETE'),
|
||||
|
||||
// 🎭 PERMISSIONS
|
||||
loadPermissions: () => api('/api/rbac/permission/get', 'POST'),
|
||||
createPermission: (data) => api('/api/rbac/permission/create', 'POST', data),
|
||||
deletePermission: (id) => api(`/api/rbac/permission/${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 }),
|
||||
@@ -115,7 +120,7 @@ function createDropZone(el, type, target) {
|
||||
// 📋 TABLE (USERS)
|
||||
//////////////////////////////
|
||||
|
||||
const rbacVT = virtualTable({
|
||||
const rbacUsersVT = virtualTable({
|
||||
tableEl: document.querySelector('#rbacUsersTable'),
|
||||
data: [],
|
||||
rowHeight: 20,
|
||||
@@ -177,13 +182,81 @@ const rbacVT = virtualTable({
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// 📋 TABLE (PERMISSIONS)
|
||||
//////////////////////////////
|
||||
|
||||
const rbacPermissionsVT = virtualTable({
|
||||
tableEl: document.querySelector('#rbacPermissionsTable'),
|
||||
data: [],
|
||||
rowHeight: 20,
|
||||
buffer: 5,
|
||||
groupKey: 'Scope',
|
||||
rowKey: 'ID',
|
||||
filterConfig: {
|
||||
hideCounter: true,
|
||||
exceptedColumns: ['', 'ID']
|
||||
},
|
||||
|
||||
customRender: (row, tr) => {
|
||||
|
||||
createDragZone(tr, row, 'user');
|
||||
|
||||
tr.addEventListener('contextmenu', (evt) => {
|
||||
evt.preventDefault();
|
||||
|
||||
ctx.setItems([
|
||||
{
|
||||
label: "Details",
|
||||
onClick: () => showAuthDetails(row.ObjectGUID)
|
||||
}
|
||||
]);
|
||||
|
||||
ctx.show(evt.pageX + 5, { y: evt.pageY + 5 });
|
||||
});
|
||||
|
||||
createTd(tr,
|
||||
`<button class="redbutton"
|
||||
${row['ID'] === 1 ?
|
||||
'disabled data-tooltip="Die SYSTEM-Berechtigung kann nicht gelöscht werden"' :
|
||||
''
|
||||
}>X</button>`, {
|
||||
styles: {
|
||||
'position': 'sticky',
|
||||
'left': '0px',
|
||||
'max-width': '20px',
|
||||
'z-index': '2'
|
||||
}, classes: [
|
||||
'text-align:left'
|
||||
], onclick: () => {
|
||||
if(row['ID'] === 1) return;
|
||||
deletePermission(row['ID'], `${row['Scope']}.${row['Resource']}.${row['Action']}`);
|
||||
}
|
||||
});
|
||||
createTd(tr, row['ID'], { classes: [ 'text-align:left' ], styles: { 'max-width': '100px' } } );
|
||||
createTd(tr, row['Scope'], { classes: [ 'text-align:left' ] });
|
||||
createTd(tr, row['Resource'], { classes: [ 'text-align:center' ] });
|
||||
createTd(tr, row['Action'], { classes: [ 'text-align:center' ] });
|
||||
}
|
||||
});
|
||||
|
||||
//////////////////////////////
|
||||
// 📥 LOADERS
|
||||
//////////////////////////////
|
||||
|
||||
async function loadUsers() {
|
||||
try {
|
||||
rbacVT.source(await RBAC.loadUsers());
|
||||
rbacUsersVT.source(await RBAC.loadUsers());
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadPermissions() {
|
||||
try {
|
||||
rbacPermissionsVT.source(await RBAC.loadPermissions());
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
@@ -273,6 +346,7 @@ async function loadRoles() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// 👤 USER ACTIONS
|
||||
//////////////////////////////
|
||||
@@ -307,6 +381,9 @@ async function deleteUser(guid, name) {
|
||||
const user = await RBAC.deleteUser(guid);
|
||||
sendUserEvent('RBAC', `Benutzer ${user.sAMAccountName || ''} [${user.ObjectGUID}] gelöscht`, null, 0);
|
||||
loadUsers();
|
||||
loadGroups();
|
||||
loadRoles();
|
||||
loadPermissions();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -331,6 +408,8 @@ async function deleteGroup(guid, name) {
|
||||
sendUserEvent('RBAC', `Du hast die Gruppe ${name || ''} [${group.ObjectGUID}] gelöscht`, null, 0);
|
||||
loadUsers();
|
||||
loadGroups();
|
||||
loadRoles();
|
||||
loadPermissions();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -369,19 +448,65 @@ async function deleteRole(id, name) {
|
||||
|
||||
sendUserEvent('RBAC', `Rolle ${name} gelöscht`, null, 0);
|
||||
|
||||
loadUsers();
|
||||
loadGroups();
|
||||
loadRoles();
|
||||
loadUsers(); // optional, falls RoleCount betroffen
|
||||
loadPermissions(); // optional, falls RoleCount betroffen
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// 🎭 PERMISSION ACTIONS
|
||||
//////////////////////////////
|
||||
|
||||
async function createPermission() {
|
||||
const scope = document.getElementById('permScope').value;
|
||||
const resource = document.getElementById('permResource').value;
|
||||
const action = document.getElementById('permAction').value;
|
||||
|
||||
if (!scope || !resource || !action) return;
|
||||
|
||||
|
||||
const permission = await RBAC.createPermission( { scope, resource, action } );
|
||||
|
||||
sendUserEvent('RBAC', `Berechtigung ${scope}.${resource}.${action} angelegt`, null, 0);
|
||||
loadPermissions();
|
||||
}
|
||||
|
||||
|
||||
async function deletePermission(id, name) {
|
||||
feedbox({
|
||||
title: `<span>Berechtigung löschen</span>`,
|
||||
message: `Möchtest du die Berechtigung <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.deletePermission(id);
|
||||
|
||||
sendUserEvent('RBAC', `Berechtigung ${name} gelöscht`, null, 0);
|
||||
|
||||
loadUsers();
|
||||
loadGroups();
|
||||
loadRoles();
|
||||
loadPermissions();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// 🚀 INIT
|
||||
//////////////////////////////
|
||||
|
||||
loadUsers();
|
||||
loadGroups();
|
||||
loadRoles();
|
||||
|
||||
loadUsers();
|
||||
loadGroups();
|
||||
loadRoles();
|
||||
loadPermissions();
|
||||
@@ -31,8 +31,8 @@ body, html { margin:0; padding:0; height:100%; overflow: hidden; font-family: va
|
||||
.window-resize-se { bottom: -6px;right: -6px;cursor: var(--theme-cursor-resize-270); }
|
||||
.window-resize-sw { bottom: -6px;left: -6px;cursor: var(--theme-cursor-resize-45); }
|
||||
|
||||
#taskbar { z-index: 2; position: absolute; width:100%; bottom:0; left:0; height:var(--auto-taskbar-height); overflow:visible; display:flex; flex: 0 0 auto; min-width:0; align-items:center; padding:0 8px; box-sizing:border-box; }
|
||||
#start-btn { transition: background-color var(--times-transition-colors) ease; padding: 8px 12px; border-radius: 5px; border: none; margin-right:8px; }
|
||||
#taskbar { z-index: 2; position: absolute; width:100%; bottom:0; left:0; height:auto; overflow:visible; display:flex; flex: 0 0 auto; min-width:0; align-items:center; padding:0 8px; box-sizing:border-box; }
|
||||
#start-btn { transition: background-color var(--times-transition-colors) ease; padding: 5px 12px; border-radius: 5px; border: none; margin-right:8px; }
|
||||
#taskbar-windows { display:flex; gap:6px; align-items:center; flex:1; overflow-y:hidden;overflow-x: auto; min-width: 0;scrollbar-width: thin; }
|
||||
.taskbar-item { display: flex; position: relative; padding:4px 10px; border-radius:4px; }
|
||||
.taskbar-item::before { content: ''; position: absolute; bottom:1px; left:50%; width:40%; height: 4px; border-radius:4px; transform:translateX(-50%) scaleX(0); transform-origin:center; transition:transform var(--times-transition-colors) ease; }
|
||||
@@ -59,7 +59,7 @@ body, html { margin:0; padding:0; height:100%; overflow: hidden; font-family: va
|
||||
.hidden { opacity: 0; pointer-events: none; }
|
||||
|
||||
/* Open submenu vertical */
|
||||
#start-menu { z-index: 2; transition: opacity var(--times-transition-opacity); display:flex; flex-direction:column; position: absolute; bottom: 50px; left: 8px; width: auto; min-width: 300px; border-radius: 8px; overflow: hidden; }
|
||||
#start-menu { z-index: 2; transition: opacity var(--times-transition-opacity); display:flex; flex-direction:column; position: absolute; bottom: auto; left: 8px; width: auto; min-width: 300px; border-radius: 8px; overflow: hidden; }
|
||||
.start-header { display: flex; align-items: center; padding: 8px; font-weight: 600; }
|
||||
.start-header > img { height: 24px; width: 24px; margin-right: 5px; }
|
||||
.start-list { list-style: none; margin: 0; padding: 8px 0; height: 60vh; overflow-y: auto; }
|
||||
|
||||
@@ -63,7 +63,7 @@ input {
|
||||
</head>
|
||||
<body>
|
||||
<!-- USERS -->
|
||||
<div class="container static" style="height:100vh;max-width:100vw;flex-direction:row;flex-wrap:wrap">
|
||||
<div class="container static" style="height:100vh;max-width:100vw;flex-direction:row;flex-wrap:wrap;">
|
||||
<div class="card" style="flex:1 1 auto;min-width:300px">
|
||||
Users <input id="newUserName" placeholder="sAMAccountName" /> <button class="bluebutton" onclick="createUser()">Create User</button>
|
||||
<div class="table-wrapper fit-table">
|
||||
@@ -109,13 +109,26 @@ input {
|
||||
|
||||
<!-- PERMISSIONS -->
|
||||
<div class="card" style="min-width:300px;flex:1 1 auto">
|
||||
<h3>Permissions</h3>
|
||||
|
||||
<input id="permScope" placeholder="Scope" />
|
||||
<input id="permResource" placeholder="Resource" />
|
||||
<input id="permAction" placeholder="Action" />
|
||||
<input id="permScope" placeholder="Scope" />.<input id="permResource" placeholder="Resource" />.<input id="permAction" placeholder="Action" />
|
||||
|
||||
<button class="bluebutton" onclick="createPermission()">Create Permission</button>
|
||||
|
||||
<div class="table-wrapper fit-table">
|
||||
<table id="rbacPermissionsTable" style="height:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-align:left"></th>
|
||||
<th class="text-align:left">ID</th>
|
||||
<th class="text-align:left">Scope</th>
|
||||
<th class="text-align:center">Resource</th>
|
||||
<th class="text-align:center">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td colspan="100%">BERECHTIGUNGEN WERDEN GELADEN . . .</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user