296 lines
8.8 KiB
JavaScript
296 lines
8.8 KiB
JavaScript
const { exec } = require('child_process');
|
|
const path = require('path');
|
|
const { permission } = require('process');
|
|
const { dirname } = require('path');
|
|
const { File: HotReload } = require(`@services/hotReload.js`);
|
|
const { service } = require(`@root/server.js`);
|
|
// let integratedStartmenuItems = require('@models/integratedStartmenuItems');
|
|
|
|
|
|
global.path = {
|
|
root: dirname(require.main.filename),
|
|
source:`${dirname(require.main.filename)}/src`,
|
|
public: `${dirname(require.main.filename)}/public`,
|
|
plugins: `${dirname(require.main.filename)}/plugins`
|
|
};
|
|
|
|
|
|
global.json = {
|
|
releaseNotes: new HotReload(path.join(global.path.source, 'models', 'releasenotes.json')),
|
|
configuration: new HotReload(path.join(global.path.source, 'models', 'configuration.json')),
|
|
stylesheet: new HotReload(path.join(global.path.source, 'models', 'stylesheet.json')),
|
|
indexRoutes: new HotReload(path.join(global.path.source, 'routes', 'indexRoutes.js'), { historyLimit: 50, fileType: 'js' }),
|
|
startMenuItems: new HotReload(path.join(global.path.source, 'models', 'integratedStartMenuItems.json'))
|
|
}
|
|
|
|
module.exports = startMenuItems = async function (app, objectGuid, debug = false) {
|
|
|
|
function safeClone(obj) {
|
|
return JSON.parse(JSON.stringify(obj));
|
|
}
|
|
|
|
const log = (...args) => {
|
|
if (debug) console.log('[RBAC DEBUG]', ...args);
|
|
};
|
|
|
|
// =========================
|
|
// Load menu sources
|
|
// =========================
|
|
const integratedStartmenuItems =
|
|
service.get('fileSystemManager')
|
|
.loadJSON(global.json.startMenuItems.filePath) || [];
|
|
|
|
const plugins = service
|
|
.get('pluginManager')
|
|
.getStatus()
|
|
.map(({ config, ...plugin }) => ({
|
|
...safeClone(plugin),
|
|
section: 'Plugin'
|
|
}));
|
|
|
|
let allPlugins = [...plugins, ...integratedStartmenuItems];
|
|
|
|
// =========================
|
|
// Load user permissions
|
|
// =========================
|
|
const authManager = service.get('authenticationManager');
|
|
|
|
const userPermissions =
|
|
(await authManager.resolvePermissions(objectGuid))
|
|
?.permissions || [];
|
|
|
|
const normalizedPermissions = userPermissions.map(p => ({
|
|
scope: p.scope,
|
|
action: p.action,
|
|
resource: p.resource || null
|
|
}));
|
|
|
|
log('USER OBJECTGUID:', objectGuid);
|
|
log('PERMISSIONS:', normalizedPermissions);
|
|
|
|
// =========================
|
|
// SUPER ADMIN CHECK
|
|
// =========================
|
|
const isSuperAdmin = normalizedPermissions.some(p =>
|
|
p.scope === 'SYSTEM' &&
|
|
p.resource === 'ALL' &&
|
|
p.action === 'ALL'
|
|
);
|
|
|
|
log('SUPER ADMIN:', isSuperAdmin);
|
|
|
|
// =========================
|
|
// BUILD MENU
|
|
// =========================
|
|
for (const plugin of allPlugins) {
|
|
|
|
plugin.menu.items = (plugin.menu.items || []).map(item => {
|
|
|
|
const resource = item.label;
|
|
const requiredPermissions = item.permissions || [];
|
|
|
|
const debugTrace = [];
|
|
|
|
const authorized = isSuperAdmin
|
|
? (debugTrace.push('SUPERADMIN OVERRIDE'), true)
|
|
: normalizedPermissions.some(userPerm => {
|
|
|
|
return requiredPermissions.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 === resource;
|
|
|
|
const result = scopeMatch && actionMatch && resourceMatch;
|
|
|
|
if (debug) {
|
|
debugTrace.push({
|
|
userPerm,
|
|
required,
|
|
scopeMatch,
|
|
actionMatch,
|
|
resourceMatch,
|
|
result
|
|
});
|
|
}
|
|
|
|
return result;
|
|
});
|
|
});
|
|
|
|
if (debug) {
|
|
log(`\n--- MENU ITEM: ${item.label} ---`);
|
|
log('AUTHORIZED:', authorized);
|
|
log('TRACE:', debugTrace);
|
|
}
|
|
|
|
return {
|
|
...safeClone(item),
|
|
authorized
|
|
};
|
|
});
|
|
|
|
plugin.onlyAdministration =
|
|
plugin.menu.items.every(i => !i.authorized);
|
|
|
|
if (debug) {
|
|
log(`PLUGIN: ${plugin.name}`);
|
|
log('VISIBLE:', !plugin.onlyAdministration);
|
|
}
|
|
}
|
|
|
|
// =========================
|
|
// FILTER FINAL MENU
|
|
// =========================
|
|
allPlugins = allPlugins
|
|
.filter(p => !p.onlyAdministration)
|
|
.filter(p => p.active);
|
|
app.locals.startMenuItems = allPlugins;
|
|
return allPlugins;
|
|
};
|
|
|
|
// module.exports = startMenuItems = async function (app, sAMAccountName) {
|
|
|
|
// function safeClone(obj) {
|
|
// return JSON.parse(JSON.stringify(obj));
|
|
// }
|
|
|
|
// const integratedStartmenuItems = safeClone(service.get('fileSystemManager').loadJSON(global.json.startMenuItems.filePath));
|
|
|
|
// const plugins = service
|
|
// .get('pluginManager')
|
|
// .getStatus()
|
|
// .map(({ config, ...plugin }) => ({
|
|
// ...safeClone(plugin),
|
|
// section: 'Plugin'
|
|
// }));
|
|
|
|
// let getAllPlugins = [...plugins, ...integratedStartmenuItems];
|
|
|
|
// for (const plugin of getAllPlugins) {
|
|
|
|
// plugin.menu.items = await Promise.all(
|
|
// (plugin.menu.items || []).map(async item => {
|
|
|
|
// const authorized =
|
|
// item.label === 'hr' ||
|
|
// item.permissions.includes('Administration')
|
|
// ? global.json.configuration.live.administration.some(
|
|
// name => name.toLowerCase() === sAMAccountName.toLowerCase()
|
|
// )
|
|
// : item.permissions.includes('*') ||
|
|
// (
|
|
// await Promise.all(
|
|
// item.permissions.map(async permission =>
|
|
// (await service.get('activeDirectoryManager').getGroup(permission)) &&
|
|
// (await service.get('activeDirectoryManager').isUserMemberOfRecursive(
|
|
// sAMAccountName,
|
|
// permission
|
|
// ))
|
|
// )
|
|
// )
|
|
// ).some(Boolean);
|
|
|
|
// return {
|
|
// ...safeClone(item),
|
|
// authorized
|
|
// };
|
|
// })
|
|
// );
|
|
|
|
// plugin.onlyAdministration =
|
|
// plugin.menu.items.every(item => !item.authorized) &&
|
|
// !global.json.configuration.live.administration.includes(sAMAccountName);
|
|
// }
|
|
|
|
// getAllPlugins = getAllPlugins
|
|
// .filter(plugin => !plugin.onlyAdministration)
|
|
// .filter(plugin => plugin.active);
|
|
|
|
// app.locals.startMenuItems = getAllPlugins;
|
|
|
|
// return [...getAllPlugins];
|
|
// };
|
|
|
|
|
|
|
|
/**
|
|
* Convert date into custom dateformat
|
|
* @param {any} date - Valid date as datetype or string
|
|
* @param {string} [format] - (optional) date characters are lowercase, time characters are uppercase; If is null, format will be "dd.mm.yyyy HH:MM:SS"
|
|
*/
|
|
module.exports = dateFormat = function(date, format = null) {
|
|
format = (format == null ? "dd.mm.yyyy HH:MM:SS" : format);
|
|
const finish_date = new Date(date);
|
|
|
|
return format
|
|
.replace('yyyy', finish_date.getFullYear())
|
|
.replace('yy', finish_date.getFullYear().toString().slice(-2))
|
|
.replace('mm', ("0" + (finish_date.getMonth() + 1)).slice(-2))
|
|
.replace('dd', ("0" + finish_date.getDate()).slice(-2))
|
|
.replace('HH', ("0" + finish_date.getHours()).slice(-2))
|
|
.replace('MM', ("0" + finish_date.getMinutes()).slice(-2))
|
|
.replace('SS', ("0" + finish_date.getSeconds()).slice(-2));
|
|
}
|
|
|
|
|
|
/**
|
|
* Limits the number of functions that can be executed in parallel.
|
|
*/
|
|
// module.exports = createLimiter = function(max) {
|
|
// let active = 0;
|
|
// const queue = [];
|
|
|
|
// const runNext = () => {
|
|
// if (active >= max || queue.length === 0) return;
|
|
|
|
// active++;
|
|
// const { fn, resolve, reject } = queue.shift();
|
|
|
|
// fn()
|
|
// .then(resolve)
|
|
// .catch(reject)
|
|
// .finally(() => {
|
|
// active--;
|
|
// runNext();
|
|
// });
|
|
// };
|
|
|
|
// return fn =>
|
|
// new Promise((resolve, reject) => {
|
|
// queue.push({ fn, resolve, reject });
|
|
// runNext();
|
|
// });
|
|
// }
|
|
|
|
|
|
|
|
|
|
/**
|
|
* try to call an existing host by name or ip adress
|
|
* @param {string} hostname - Valid hostname or ip adress
|
|
* @param {string} [format] - (optional) date characters are lowercase, time characters are uppercase; If is null, format will be "dd.mm.yyyy HH:MM:SS"
|
|
*/
|
|
module.exports = ping = function(hostname, cbErr, cb, ttl = 1) {
|
|
exec(`ping ${hostname} -c 1 -W ${ttl}`, function (err, stdout, stderr) {
|
|
if(err) {
|
|
cbErr(err);
|
|
} else {
|
|
cb(stdout);
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
module.exports = isObject = function(param) {
|
|
return param !== null && typeof param === 'object' && !Array.isArray(param);
|
|
} |