bugfix rbac
This commit is contained in:
18
dbcreate.sql
18
dbcreate.sql
@@ -149,7 +149,7 @@ CREATE TABLE dbo.GroupClosure (
|
||||
Depth INT,
|
||||
PRIMARY KEY (ParentGroup_ObjectGUID, ChildGroup_ObjectGUID)
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
/* =========================================================
|
||||
RBAC
|
||||
@@ -160,25 +160,28 @@ CREATE TABLE dbo.AuthenticationRoles (
|
||||
Role_ID INT,
|
||||
PRIMARY KEY (Authentication_ObjectGUID, Role_ID)
|
||||
);
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.AuthenticationGroups (
|
||||
Authentication_ObjectGUID UNIQUEIDENTIFIER,
|
||||
Group_ObjectGUID UNIQUEIDENTIFIER,
|
||||
PRIMARY KEY (Authentication_ObjectGUID, Group_ObjectGUID)
|
||||
);
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.GroupRoles (
|
||||
Group_ObjectGUID UNIQUEIDENTIFIER,
|
||||
Role_ID INT,
|
||||
PRIMARY KEY (Group_ObjectGUID, Role_ID)
|
||||
);
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.RolePermissions (
|
||||
Role_ID INT,
|
||||
Permission_ID INT,
|
||||
PRIMARY KEY (Role_ID, Permission_ID)
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
/* =========================================================
|
||||
EVENT SYSTEM
|
||||
@@ -215,6 +218,7 @@ CREATE TABLE dbo.NotifyTrayObjects (
|
||||
CreatedAt DATETIME2,
|
||||
ExpiresAt DATETIME2
|
||||
);
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.NotifyTray (
|
||||
ID INT IDENTITY(1,1) PRIMARY KEY,
|
||||
@@ -222,7 +226,7 @@ CREATE TABLE dbo.NotifyTray (
|
||||
NotifyTrayObject_ID INT,
|
||||
SeenAt DATETIME2
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
/* =========================================================
|
||||
SECURITY VIEWS
|
||||
@@ -241,7 +245,7 @@ FROM dbo.Authentication a
|
||||
JOIN dbo.AuthenticationGroups ag ON ag.Authentication_ObjectGUID = a.ObjectGUID
|
||||
JOIN dbo.GroupRoles gr ON gr.Group_ObjectGUID = ag.Group_ObjectGUID
|
||||
JOIN dbo.[Role] r ON r.ID = gr.Role_ID;
|
||||
|
||||
GO
|
||||
|
||||
CREATE VIEW dbo.vAuthenticationEffectivePermissions AS
|
||||
SELECT DISTINCT
|
||||
@@ -254,7 +258,7 @@ FROM dbo.Authentication a
|
||||
JOIN dbo.vAuthenticationRoles r ON r.ObjectGUID = a.ObjectGUID
|
||||
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)
|
||||
@@ -308,7 +312,7 @@ CREATE VIEW dbo.vAuthentications AS
|
||||
SELECT a.*, os.Name AS ObjectSource
|
||||
FROM dbo.Authentication a
|
||||
LEFT JOIN dbo.ObjectSource os ON os.ID = a.ObjectSource_ID;
|
||||
|
||||
GO
|
||||
|
||||
/* =========================================================
|
||||
GROUP VIEW
|
||||
@@ -316,7 +320,7 @@ LEFT JOIN dbo.ObjectSource os ON os.ID = a.ObjectSource_ID;
|
||||
|
||||
CREATE VIEW dbo.vGroupHierarchy AS
|
||||
SELECT * FROM dbo.GroupClosure;
|
||||
|
||||
GO
|
||||
|
||||
/* =========================================================
|
||||
NOTIFY VIEWS
|
||||
|
||||
@@ -135,8 +135,8 @@ const server = https.createServer(httpsOptions, app);
|
||||
databaseModel.set('roleModel', require(`@models/roleModel`)(service.get('sqlManager').getInstance('main')));
|
||||
databaseModel.set('rolePermissionsModel', require(`@models/rolePermissionsModel`)(service.get('sqlManager').getInstance('main')));
|
||||
|
||||
service.set('authenticationManager', new AuthenticationManager(databaseModel.get('authentication'), app.locals.configuration.integration.token.secret));
|
||||
service.set('rbacManager', new RBACManager(databaseModel));
|
||||
service.set('authenticationManager', new AuthenticationManager(databaseModel.get('authentication'), app.locals.configuration.integration.token.secret));
|
||||
|
||||
service.set('activeDirectoryManager', new ActiveDirectory(app.locals.configuration.integration.activedirectory))
|
||||
|
||||
@@ -228,7 +228,7 @@ const server = https.createServer(httpsOptions, app);
|
||||
require(`${app.locals.path.source}/routes/adminRoutes.js`).route(app, service); // #3 - token security always enabled
|
||||
//#endregion
|
||||
|
||||
app.use(service.get('authenticationManager').authenticate());
|
||||
app.use(service.get('rbacManager').authenticate());
|
||||
|
||||
//#region Implements sockets
|
||||
require(`${app.locals.path.source}/sockets/mainSocket.js`)(
|
||||
|
||||
@@ -40,7 +40,7 @@ module.exports = {
|
||||
|
||||
|
||||
// Geschützte Route
|
||||
app.get('/me', service.get('authenticationManager').authenticate(), (req, res) => {
|
||||
app.get('/me', service.get('rbacManager').authenticate(), (req, res) => {
|
||||
res.json(JSON.stringify({
|
||||
user: {
|
||||
name: req.user
|
||||
@@ -63,7 +63,7 @@ module.exports = {
|
||||
});
|
||||
|
||||
// Logout
|
||||
app.post('/logout', service.get('authenticationManager').authenticate(), async (req, res) => {
|
||||
app.post('/logout', service.get('rbacManager').authenticate(), async (req, res) => {
|
||||
const logout = await service.get('authenticationManager').logout(req.user.sAMAccountName);
|
||||
|
||||
// socketManager.sendTo('/', req.user.objectGuid, 'login_status', { levelId: logout.levelId, message: logout.message } )
|
||||
|
||||
@@ -2,6 +2,7 @@ const jwt = require('jsonwebtoken');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
class AuthenticationManager {
|
||||
|
||||
constructor(model, secretKey) {
|
||||
this.Authentication = model;
|
||||
this.SECRET_KEY = secretKey;
|
||||
@@ -113,81 +114,6 @@ class AuthenticationManager {
|
||||
return { valid: false, levelId: 4 };
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 🔥 MIDDLEWARE BLEIBT HIER
|
||||
// =========================================================
|
||||
authenticate() {
|
||||
return async (req, res, next) => {
|
||||
|
||||
try {
|
||||
|
||||
// =====================================================
|
||||
// 🔥 GLOBAL PUBLIC ROUTE BYPASS (ROBUST)
|
||||
// =====================================================
|
||||
|
||||
const url = req.originalUrl.split('?')[0];
|
||||
|
||||
const publicRoutes = [
|
||||
'/login',
|
||||
'/public'
|
||||
];
|
||||
|
||||
const isPublicRoute = publicRoutes.some(route =>
|
||||
url === route || url.startsWith(route + '/')
|
||||
);
|
||||
|
||||
if (isPublicRoute) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// 🔐 AUTH FLOW
|
||||
// =====================================================
|
||||
|
||||
const sAMAccountName = req.cookies?.sAMAccountName;
|
||||
|
||||
if (!sAMAccountName) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
const user = await this.findUser(sAMAccountName);
|
||||
|
||||
if (!user || !user.active) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
let payload;
|
||||
|
||||
try {
|
||||
payload = jwt.verify(user.refreshtoken, this.SECRET_KEY);
|
||||
} catch {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
const rbac = await this.rbac.resolvePermissions(user.ObjectGUID);
|
||||
|
||||
const normalized = this.rbac.normalize(rbac.permissions);
|
||||
const isSuperAdmin = this.rbac.isSuperAdmin(normalized);
|
||||
|
||||
req.user = {
|
||||
...user.toJSON(),
|
||||
jwt: payload,
|
||||
groups: rbac.groups,
|
||||
roles: rbac.roles,
|
||||
permissions: normalized,
|
||||
isSuperAdmin
|
||||
};
|
||||
|
||||
next();
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return res.redirect('/login');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = AuthenticationManager;
|
||||
@@ -151,6 +151,82 @@ class RBACManager {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// =========================================================
|
||||
// 🔥 MIDDLEWARE BLEIBT HIER
|
||||
// =========================================================
|
||||
authenticate() {
|
||||
return async (req, res, next) => {
|
||||
|
||||
try {
|
||||
|
||||
// =====================================================
|
||||
// 🔥 GLOBAL PUBLIC ROUTE BYPASS (ROBUST)
|
||||
// =====================================================
|
||||
|
||||
const url = req.originalUrl.split('?')[0];
|
||||
|
||||
const publicRoutes = [
|
||||
'/login',
|
||||
'/public'
|
||||
];
|
||||
|
||||
const isPublicRoute = publicRoutes.some(route =>
|
||||
url === route || url.startsWith(route + '/')
|
||||
);
|
||||
|
||||
if (isPublicRoute) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// 🔐 AUTH FLOW
|
||||
// =====================================================
|
||||
|
||||
const sAMAccountName = req.cookies?.sAMAccountName;
|
||||
|
||||
if (!sAMAccountName) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
const user = await this.db.get('authentication').findOne( { where: { sAMAccountName } } );
|
||||
|
||||
if (!user || !user.active) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
let payload;
|
||||
|
||||
try {
|
||||
payload = jwt.verify(user.refreshtoken, this.SECRET_KEY);
|
||||
} catch {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
const rbac = await this.resolvePermissions(user.ObjectGUID);
|
||||
|
||||
const normalized = this.normalize(rbac.permissions);
|
||||
const isSuperAdmin = this.isSuperAdmin(normalized);
|
||||
|
||||
req.user = {
|
||||
...user.toJSON(),
|
||||
jwt: payload,
|
||||
groups: rbac.groups,
|
||||
roles: rbac.roles,
|
||||
permissions: normalized,
|
||||
isSuperAdmin
|
||||
};
|
||||
|
||||
next();
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return res.redirect('/login');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
normalize(permissions) {
|
||||
return permissions.map(p => ({
|
||||
scope: p.scope,
|
||||
|
||||
5
utils.js
5
utils.js
@@ -54,10 +54,7 @@ module.exports = startMenuItems = async function (app, objectGuid, debug = false
|
||||
// Load user permissions
|
||||
// =========================
|
||||
const rbacManager = service.get('rbacManager');
|
||||
|
||||
const userPermissions =
|
||||
(await rbacManager.resolvePermissions(objectGuid))
|
||||
?.permissions || [];
|
||||
const userPermissions = objectGuid === undefined ? [] : (await rbacManager.resolvePermissions(objectGuid))?.permissions;
|
||||
|
||||
const normalizedPermissions = userPermissions.map(p => ({
|
||||
scope: p.scope,
|
||||
|
||||
Reference in New Issue
Block a user