rbac outsourced
This commit is contained in:
116
src/services/rbacManager.js
Normal file
116
src/services/rbacManager.js
Normal file
@@ -0,0 +1,116 @@
|
||||
// rbac/RbacService.js
|
||||
|
||||
class RBACManager {
|
||||
constructor(databaseModel) {
|
||||
this.db = databaseModel;
|
||||
}
|
||||
|
||||
async resolvePermissions(objectGuid) {
|
||||
const AuthenticationGroups = this.db.get('authenticationGroupsModel');
|
||||
const GroupClosure = this.db.get('groupClosureModel');
|
||||
const AuthenticationRoles = this.db.get('authenticationRolesModel');
|
||||
const GroupRoles = this.db.get('groupRolesModel');
|
||||
const RolePermissions = this.db.get('rolePermissionsModel');
|
||||
const Permission = this.db.get('permissionModel');
|
||||
|
||||
// 1. USER GROUPS
|
||||
const userGroups = await AuthenticationGroups.findAll({
|
||||
where: { Authentication_ObjectGUID: objectGuid }
|
||||
});
|
||||
|
||||
const directGroupIds = userGroups.map(g => g.Group_ObjectGUID);
|
||||
|
||||
// 2. NESTED GROUPS
|
||||
let allGroupIds = [...directGroupIds];
|
||||
|
||||
if (directGroupIds.length) {
|
||||
const closure = await GroupClosure.findAll({
|
||||
where: { ParentGroup_ObjectGUID: directGroupIds }
|
||||
});
|
||||
|
||||
allGroupIds.push(...closure.map(c => c.ChildGroup_ObjectGUID));
|
||||
}
|
||||
|
||||
allGroupIds = [...new Set(allGroupIds)];
|
||||
|
||||
// 3. ROLES
|
||||
const userRoles = await AuthenticationRoles.findAll({
|
||||
where: { Authentication_ObjectGUID: objectGuid }
|
||||
});
|
||||
|
||||
const groupRoles = await GroupRoles.findAll({
|
||||
where: { Group_ObjectGUID: allGroupIds }
|
||||
});
|
||||
|
||||
const roleIds = [
|
||||
...new Set([
|
||||
...userRoles.map(r => r.Role_ID),
|
||||
...groupRoles.map(r => r.Role_ID)
|
||||
])
|
||||
];
|
||||
|
||||
// 4. PERMISSIONS
|
||||
const rolePerms = await RolePermissions.findAll({
|
||||
where: { Role_ID: roleIds }
|
||||
});
|
||||
|
||||
const permissionIds = rolePerms.map(r => r.Permission_ID);
|
||||
|
||||
const permissions = await Permission.findAll({
|
||||
where: { ID: permissionIds }
|
||||
});
|
||||
|
||||
return {
|
||||
groups: allGroupIds,
|
||||
roles: roleIds,
|
||||
permissions: permissions.map(p => ({
|
||||
id: p.ID,
|
||||
scope: p.Scope,
|
||||
resource: p.Resource,
|
||||
action: p.Action
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
// 🔥 SUPER CLEAN CHECK (wiederverwendbar überall)
|
||||
isSuperAdmin(permissions) {
|
||||
return permissions.some(p =>
|
||||
p.scope === 'SYSTEM' &&
|
||||
p.resource === 'ALL' &&
|
||||
p.action === 'ALL'
|
||||
);
|
||||
}
|
||||
|
||||
// 🔥 GENERIC CHECK FUNCTION (WICHTIG)
|
||||
hasPermission(userPerms, requiredPerms, isSuperAdmin = false) {
|
||||
if (isSuperAdmin) return true;
|
||||
|
||||
return userPerms.some(userPerm =>
|
||||
requiredPerms.some(required => {
|
||||
const scopeMatch = userPerm.scope === required.scope;
|
||||
|
||||
const actionMatch =
|
||||
userPerm.action === 'ALL' ||
|
||||
userPerm.action === required.action ||
|
||||
required.action === 'ALL';
|
||||
|
||||
const resourceMatch =
|
||||
!userPerm.resource ||
|
||||
userPerm.resource === 'ALL' ||
|
||||
userPerm.resource === required.resource;
|
||||
|
||||
return scopeMatch && actionMatch && resourceMatch;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
normalize(permissions) {
|
||||
return permissions.map(p => ({
|
||||
scope: p.scope,
|
||||
action: p.action,
|
||||
resource: p.resource || null
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RBACManager;
|
||||
Reference in New Issue
Block a user