mirror of https://github.com/nocodb/nocodb
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
698 lines
21 KiB
698 lines
21 KiB
3 years ago
|
/* tslint:disable:prefer-const */
|
||
|
import colors from 'colors';
|
||
|
import fs from 'fs';
|
||
|
import glob from 'glob';
|
||
|
import jsonfile from 'jsonfile';
|
||
|
import path from 'path';
|
||
|
import Util from '../util/Util';
|
||
|
|
||
|
import Table from 'cli-table3';
|
||
|
|
||
|
class PermissionsMgr {
|
||
|
|
||
|
public static async set(args) {
|
||
|
|
||
|
if (Util.isProjectGraphql()) {
|
||
|
try {
|
||
|
|
||
|
if (args._.length < 4) {
|
||
|
console.warn('Invalid arguments for : xc permissions.set')
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
// @ts-ignore
|
||
|
let [_, models, users, ...resolvers] = args._;
|
||
|
models = models.split('.');
|
||
|
users = users.split('.');
|
||
|
|
||
|
/* get all policies */
|
||
|
const policiesPath = path.join(process.cwd(), 'server', PermissionsMgr.getPolicyPath(), '**', '*.policy.js');
|
||
|
|
||
|
glob.sync(policiesPath).forEach((file) => {
|
||
|
|
||
|
const modelName = path.basename(file).split('.')[0];
|
||
|
|
||
|
if (models.includes(modelName) || models[0] === '$') {
|
||
|
const filePermissions = require(file);
|
||
|
|
||
|
const roles = this.extractUniqueGqlPolicyRoles(filePermissions);
|
||
|
|
||
|
if (users[0] === '$') {
|
||
|
for (const [route, rolesObj] of Object.entries(filePermissions)) {
|
||
|
|
||
|
if (resolvers[0] === '$=1') {
|
||
|
const permObj = roles.reduce((obj, role) => {
|
||
|
obj[role] = true;
|
||
|
return obj;
|
||
|
}, {});
|
||
|
|
||
|
Object.assign(rolesObj, permObj)
|
||
|
console.log(`Setting Permissions for model:${modelName} roles:${roles.join(', ')} resolver: ${route}`);
|
||
|
} else if (resolvers[0] === '$=0') {
|
||
|
const permObj = roles.reduce((obj, role) => {
|
||
|
obj[role] = false;
|
||
|
return obj;
|
||
|
}, {});
|
||
|
|
||
|
Object.assign(rolesObj, permObj)
|
||
|
console.log(`Setting Permissions for model:${modelName} roles:${roles.join(', ')} resolver: ${route}`);
|
||
|
} else {
|
||
|
resolvers.forEach(permission => {
|
||
|
const permTuple = permission.split('=')
|
||
|
if (route === permTuple[0]) {
|
||
|
const permObj = roles.reduce((obj, role) => {
|
||
|
const val = !!(permTuple.length === 1 ? 1 : +permTuple[1] || 0);
|
||
|
obj[role] = val;
|
||
|
return obj;
|
||
|
}, {});
|
||
|
Object.assign(rolesObj, permObj)
|
||
|
console.log(`Setting Permissions for model:${modelName} roles:${roles.join(', ')} , resolver: ${route}`);
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
|
||
|
for (const [route, rolesObj] of Object.entries(filePermissions)) {
|
||
|
resolvers.forEach(permission => {
|
||
|
const permTuple = permission.split('=')
|
||
|
if (route === permTuple[0] || permTuple[0] === '$') {
|
||
|
const permObj = users.reduce((obj, role) => {
|
||
|
const val = !!(permTuple.length === 1 ? 1 : +permTuple[1] || 0);
|
||
|
obj[role] = val;
|
||
|
return obj;
|
||
|
}, {});
|
||
|
Object.assign(rolesObj, permObj)
|
||
|
console.log(`Setting Permissions for model:${modelName} roles:${users} , resolver: ${route}`);
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const policyFileContent = `module.exports = ${JSON.stringify(filePermissions, null, 2)};\n`;
|
||
|
fs.writeFileSync(file, policyFileContent)
|
||
|
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
} catch (e) {
|
||
|
console.error(`Error in xc permissions.set`, e);
|
||
|
}
|
||
|
} else {
|
||
|
try {
|
||
|
if (args._.length < 4) {
|
||
|
console.warn('Invalid arguments for : xc permissions.set')
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// @ts-ignore
|
||
|
let [_, models, users, ...permissions] = args._;
|
||
|
|
||
|
models = models.split('.');
|
||
|
users = users.split('.');
|
||
|
|
||
|
/* get all policies */
|
||
|
const policiesPath = path.join(process.cwd(), 'server', PermissionsMgr.getPolicyPath(), '**', '*.routes.js');
|
||
|
|
||
|
glob.sync(policiesPath).forEach((file) => {
|
||
|
|
||
|
const modelName = path.basename(file).split('.')[0];
|
||
|
if (models.includes(modelName) || models[0] === '$') {
|
||
|
|
||
|
const routesList: Route[] = require(file);
|
||
|
const roles = this.extractUniqueRoles(routesList);
|
||
|
|
||
|
if (users[0] === '$') {
|
||
|
for (const route of routesList) {
|
||
|
|
||
|
if (permissions[0] === '$=1') {
|
||
|
const permObj = roles.reduce((obj, role) => {
|
||
|
obj[role] = true;
|
||
|
return obj;
|
||
|
}, {});
|
||
|
Object.assign(route.acl, permObj)
|
||
|
console.log(`Setting Permissions for model:${modelName} roles:${roles.join(', ')} method: ${route.type}=true, route: ${route.path}`);
|
||
|
} else if (permissions[0] === '$=0') {
|
||
|
const permObj = roles.reduce((obj, role) => {
|
||
|
obj[role] = false;
|
||
|
return obj;
|
||
|
}, {});
|
||
|
Object.assign(route.acl, permObj)
|
||
|
console.log(`Setting Permissions for model:${modelName} roles:${roles.join(', ')} method: ${route.type}=false, route: ${route.path}`);
|
||
|
} else {
|
||
|
permissions.forEach(permission => {
|
||
|
const permTuple = permission.split('=')
|
||
|
const val = !!(permTuple.length === 1 ? 1 : +permTuple[1] || 0);
|
||
|
const permObj = roles.reduce((obj, role) => {
|
||
|
obj[role] = val;
|
||
|
return obj;
|
||
|
}, {});
|
||
|
if (route.type === permTuple[0]) {
|
||
|
Object.assign(route.acl, permObj)
|
||
|
console.log(`Setting Permissions for model:${modelName} roles:${roles.join(', ')} method: ${permTuple[0]}=${val}, route: ${route.path}`);
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
for (const route of routesList) {
|
||
|
permissions.forEach(permission => {
|
||
|
const permTuple = permission.split('=')
|
||
|
const val = !!(permTuple.length === 1 ? 1 : +permTuple[1] || 0);
|
||
|
const permObj = users.reduce((obj, role) => {
|
||
|
obj[role] = val;
|
||
|
return obj;
|
||
|
}, {});
|
||
|
|
||
|
if (route.type === permTuple[0]) {
|
||
|
Object.assign(route.acl, permObj)
|
||
|
console.log(`Setting Permissions for model:${modelName} roles:${users.join(', ')} method: ${permTuple[0]}=${val}, route: ${route.path}`);
|
||
|
} else if (permTuple[0] === '*') {
|
||
|
Object.assign(route.acl, permObj)
|
||
|
console.log(`Setting Permissions for model:${modelName} roles:${users.join(', ')} method: ${route.type}=${val}, route: ${route.path}`);
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const policyFileContent = `module.exports = ${JSON.stringify(routesList, null, 2)};\n`;
|
||
|
fs.writeFileSync(file, policyFileContent)
|
||
|
|
||
|
}
|
||
|
});
|
||
|
} catch (e) {
|
||
|
console.error(`Error in xc permissions.set`, e);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static async get(args) {
|
||
|
|
||
|
if (Util.isProjectGraphql()) {
|
||
|
try {
|
||
|
if (args._.length < 2) {
|
||
|
console.warn('Invalid arguments for : xc permissions.get')
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
let {1: models} = args._;
|
||
|
models = models.split('.');
|
||
|
|
||
|
/* get all policies */
|
||
|
const policiesPath = path.join(process.cwd(), 'server', PermissionsMgr.getPolicyPath(), '**', '*.policy.js');
|
||
|
|
||
|
|
||
|
// instantiate
|
||
|
let rows: any[] = [];
|
||
|
let roles: any[] = [];
|
||
|
|
||
|
|
||
|
glob.sync(policiesPath).forEach((file) => {
|
||
|
// let filePermissions = require(file);
|
||
|
|
||
|
const modelName = path.basename(file).split('.')[0];
|
||
|
|
||
|
if (models.includes(modelName)) {
|
||
|
const filePermissions = require(file);
|
||
|
|
||
|
|
||
|
roles = this.extractUniqueGqlPolicyRoles(filePermissions);
|
||
|
|
||
|
rows.push([{
|
||
|
colSpan: roles.length + 1,
|
||
|
content: colors.green(file),
|
||
|
hAlign: 'center'
|
||
|
}])
|
||
|
|
||
|
for (const [route, methods] of Object.entries(filePermissions)) {
|
||
|
const row: any[] = [{content: route, vAlign: 'center'}];
|
||
|
for (const role of roles) {
|
||
|
row.push(methods[role] ? colors.green('✔') : colors.red('x'));
|
||
|
}
|
||
|
rows.push(row)
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
|
||
|
|
||
|
const table = new Table({
|
||
|
head: ['Route', ...roles]
|
||
|
});
|
||
|
|
||
|
table.push(...rows);
|
||
|
console.log(table.toString());
|
||
|
|
||
|
} catch (e) {
|
||
|
console.error(`Error in xc permissions.get`, e);
|
||
|
}
|
||
|
} else {
|
||
|
|
||
|
|
||
|
try {
|
||
|
|
||
|
if (args._.length < 2) {
|
||
|
console.warn('Invalid arguments for : xc permissions.get')
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
let {1: models} = args._;
|
||
|
models = models.split('.');
|
||
|
|
||
|
/* get all policies */
|
||
|
const policiesPath = path.join(process.cwd(), 'server', PermissionsMgr.getPolicyPath(), '**', '*.routes.js');
|
||
|
|
||
|
|
||
|
// instantiate
|
||
|
const table = new Table({
|
||
|
head: ['Route', 'Role', 'GET', 'POST', 'PUT', 'DELETE', 'PATCH']
|
||
|
});
|
||
|
|
||
|
|
||
|
glob.sync(policiesPath)
|
||
|
.sort(this.sortFiles)
|
||
|
.forEach((file) => {
|
||
|
const modelName = path.basename(file).split('.')[0];
|
||
|
|
||
|
if (models.includes(modelName)) {
|
||
|
const routesList: Route[] = require(file);
|
||
|
const groupedRoutes = this.groupRoutes(routesList);
|
||
|
|
||
|
|
||
|
// extract unique roles
|
||
|
const roles = this.extractUniqueRoles(routesList);
|
||
|
|
||
|
table.push([{
|
||
|
colSpan: 7,
|
||
|
content: colors.green(file),
|
||
|
hAlign: 'center'
|
||
|
}])
|
||
|
|
||
|
|
||
|
for (const [routePath, methods] of Object.entries(groupedRoutes)) {
|
||
|
let i = 0;
|
||
|
for (const role of roles) {
|
||
|
{
|
||
|
table.push([...(i++ ? [] : [{
|
||
|
content: routePath,
|
||
|
rowSpan: roles.length,
|
||
|
vAlign: 'center'
|
||
|
}]), role,
|
||
|
methods?.get?.acl?.[role] ? colors.green('✔') : colors.red('x'),
|
||
|
methods?.post?.acl?.[role] ? colors.green('✔') : colors.red('x'),
|
||
|
methods?.put?.acl?.[role] ? colors.green('✔') : colors.red('x'),
|
||
|
methods?.delete?.acl?.[role] ? colors.green('✔') : colors.red('x'),
|
||
|
methods?.patch?.acl?.[role] ? colors.green('✔') : colors.red('x'),
|
||
|
] as any)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
})
|
||
|
|
||
|
console.log(table.toString());
|
||
|
|
||
|
|
||
|
} catch (e) {
|
||
|
console.error(`Error in xc permissions.get`, e);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
public static async userAdd(args) {
|
||
|
|
||
|
if (Util.isProjectGraphql()) {
|
||
|
|
||
|
try {
|
||
|
if (args._.length < 2) {
|
||
|
console.warn('Invalid arguments for : xc permissions.userAdd')
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const {1: user} = args._;
|
||
|
|
||
|
/* get all policies */
|
||
|
const policiesPath = path.join(process.cwd(), 'server', PermissionsMgr.getPolicyPath(), '**', '*.policy.js');
|
||
|
|
||
|
glob.sync(policiesPath).forEach((file) => {
|
||
|
|
||
|
const modelName = path.basename(file).split('.')[0];
|
||
|
|
||
|
|
||
|
const filePermissions = require(file);
|
||
|
|
||
|
const roles = this.extractUniqueGqlPolicyRoles(filePermissions);
|
||
|
|
||
|
|
||
|
if (roles.includes(user)) {
|
||
|
console.warn(`${user} already exist in ${modelName} policy`);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (const roles1 of Object.values(filePermissions)) {
|
||
|
roles1[user] = true;
|
||
|
}
|
||
|
|
||
|
|
||
|
console.log(`Adding new role permission for model:${modelName} roles:${user}`);
|
||
|
|
||
|
|
||
|
const policyFileContent = `module.exports = ${JSON.stringify(filePermissions, null, 2)};\n`;
|
||
|
fs.writeFileSync(file, policyFileContent)
|
||
|
|
||
|
});
|
||
|
|
||
|
} catch (e) {
|
||
|
console.error(`Error in xc permissions.user.add`, e);
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
try {
|
||
|
if (args._.length < 2) {
|
||
|
console.warn('Invalid arguments for : xc permissions.userAdd')
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const {1: user} = args._;
|
||
|
|
||
|
/* get all policies */
|
||
|
const policiesPath = path.join(process.cwd(), 'server', PermissionsMgr.getPolicyPath(), '**', '*.routes.js');
|
||
|
|
||
|
glob.sync(policiesPath).forEach((file) => {
|
||
|
|
||
|
const modelName = path.basename(file).split('.')[0];
|
||
|
|
||
|
|
||
|
const routes: Route[] = require(file);
|
||
|
|
||
|
const roles = this.extractUniqueRoles(routes);
|
||
|
|
||
|
|
||
|
if (roles.includes(user)) {
|
||
|
console.warn(`${user} already exist in ${modelName} policy`);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (const route of routes) {
|
||
|
route.acl[user] = true;
|
||
|
}
|
||
|
|
||
|
|
||
|
console.log(`Adding new role permission for model:${modelName} roles:${user}`);
|
||
|
|
||
|
|
||
|
const policyFileContent = `module.exports = ${JSON.stringify(routes, null, 2)};\n`;
|
||
|
fs.writeFileSync(file, policyFileContent)
|
||
|
|
||
|
});
|
||
|
|
||
|
} catch (e) {
|
||
|
console.error(`Error in xc permissions.user.add`, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
public static async userDelete(args) {
|
||
|
|
||
|
if (Util.isProjectGraphql()) {
|
||
|
try {
|
||
|
if (args._.length < 2) {
|
||
|
console.warn('Invalid arguments for : xc permissions.userAdd')
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const {1: user} = args._;
|
||
|
|
||
|
/* get all policies */
|
||
|
const policiesPath = path.join(process.cwd(), 'server', PermissionsMgr.getPolicyPath(), '**', '*.policy.js');
|
||
|
|
||
|
glob.sync(policiesPath).forEach((file) => {
|
||
|
|
||
|
const modelName = path.basename(file).split('.')[0];
|
||
|
|
||
|
|
||
|
const filePermissions = require(file);
|
||
|
|
||
|
|
||
|
const roles = this.extractUniqueGqlPolicyRoles(filePermissions);
|
||
|
|
||
|
|
||
|
if (!roles.includes(user)) {
|
||
|
console.warn(`${user} not exist in ${modelName} policy`);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (const roles1 of Object.values(filePermissions)) {
|
||
|
delete roles1[user];
|
||
|
}
|
||
|
|
||
|
|
||
|
console.log(`Deleting user permission for model:${modelName} roles:${user}`);
|
||
|
|
||
|
|
||
|
const policyFileContent = `module.exports = ${JSON.stringify(filePermissions, null, 2)};\n`;
|
||
|
fs.writeFileSync(file, policyFileContent)
|
||
|
|
||
|
});
|
||
|
|
||
|
} catch (e) {
|
||
|
console.error(`Error in xc permissions.user.delete`, e);
|
||
|
}
|
||
|
} else {
|
||
|
try {
|
||
|
if (args._.length < 2) {
|
||
|
console.warn('Invalid arguments for : xc permissions.userAdd')
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const {1: user} = args._;
|
||
|
|
||
|
/* get all policies */
|
||
|
const policiesPath = path.join(process.cwd(), 'server', PermissionsMgr.getPolicyPath(), '**', '*.routes.js');
|
||
|
|
||
|
glob.sync(policiesPath).forEach((file) => {
|
||
|
|
||
|
const modelName = path.basename(file).split('.')[0];
|
||
|
|
||
|
|
||
|
const routes: Route[] = require(file);
|
||
|
|
||
|
|
||
|
const roles = this.extractUniqueRoles(routes)
|
||
|
|
||
|
|
||
|
if (!roles.includes(user)) {
|
||
|
console.warn(`${user} not exist in ${modelName} policy`);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (const route of routes) {
|
||
|
delete route.acl[user];
|
||
|
}
|
||
|
|
||
|
|
||
|
console.log(`Deleting user permission for model:${modelName} roles:${user}`);
|
||
|
|
||
|
|
||
|
const policyFileContent = `module.exports = ${JSON.stringify(routes, null, 2)};\n`;
|
||
|
fs.writeFileSync(file, policyFileContent)
|
||
|
|
||
|
});
|
||
|
|
||
|
} catch (e) {
|
||
|
console.error(`Error in xc permissions.user.delete`, e);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static async userRename(args) {
|
||
|
|
||
|
if (Util.isProjectGraphql()) {
|
||
|
try {
|
||
|
if (args._.length < 3) {
|
||
|
console.warn('Invalid arguments for : xc permissions.userAdd')
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const {1: oldUser, 2: newUser} = args._;
|
||
|
|
||
|
/* get all policies */
|
||
|
const policiesPath = path.join(process.cwd(), 'server', PermissionsMgr.getPolicyPath(), '**', '*.policy.js');
|
||
|
|
||
|
glob.sync(policiesPath).forEach((file) => {
|
||
|
|
||
|
const modelName = path.basename(file).split('.')[0];
|
||
|
|
||
|
|
||
|
const filePermissions = require(file);
|
||
|
|
||
|
const roles = this.extractUniqueGqlPolicyRoles(filePermissions);
|
||
|
|
||
|
|
||
|
if (!roles.includes(oldUser)) {
|
||
|
console.warn(`${oldUser} not exist in ${modelName} policy`);
|
||
|
return;
|
||
|
}
|
||
|
if (roles.includes(newUser)) {
|
||
|
console.warn(`${newUser} is already exist in ${modelName} policy`);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (const roles1 of Object.values(filePermissions)) {
|
||
|
roles1[newUser] = roles1[oldUser];
|
||
|
delete roles1[oldUser];
|
||
|
}
|
||
|
|
||
|
|
||
|
console.log(`Renaming user permission ${oldUser} to ${newUser} for model:${modelName}`);
|
||
|
const policyFileContent = `module.exports = ${JSON.stringify(filePermissions, null, 2)};\n`;
|
||
|
fs.writeFileSync(file, policyFileContent)
|
||
|
|
||
|
});
|
||
|
|
||
|
} catch (e) {
|
||
|
console.error(`Error in xc permissions.user.delete`, e);
|
||
|
}
|
||
|
} else {
|
||
|
try {
|
||
|
if (args._.length < 3) {
|
||
|
console.warn('Invalid arguments for : xc permissions.userAdd')
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const {1: oldUser, 2: newUser} = args._;
|
||
|
|
||
|
/* get all policies */
|
||
|
const policiesPath = path.join(process.cwd(), 'server', PermissionsMgr.getPolicyPath(), '**', '*.routes.js');
|
||
|
|
||
|
glob.sync(policiesPath).forEach((file) => {
|
||
|
|
||
|
const modelName = path.basename(file).split('.')[0];
|
||
|
|
||
|
|
||
|
const routes: Route[] = require(file);
|
||
|
|
||
|
const roles = this.extractUniqueRoles(routes);
|
||
|
|
||
|
if (!roles.includes(oldUser)) {
|
||
|
console.warn(`${oldUser} not exist in ${modelName} policy`);
|
||
|
return;
|
||
|
}
|
||
|
if (roles.includes(newUser)) {
|
||
|
console.warn(`${newUser} is already exist in ${modelName} policy`);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (const route of routes) {
|
||
|
route.acl[newUser] = route.acl[oldUser];
|
||
|
delete route.acl[oldUser];
|
||
|
}
|
||
|
|
||
|
|
||
|
console.log(`Renaming user permission ${oldUser} to ${newUser} for model:${modelName}`);
|
||
|
const policyFileContent = `module.exports = ${JSON.stringify(routes, null, 2)};\n`;
|
||
|
fs.writeFileSync(file, policyFileContent)
|
||
|
|
||
|
});
|
||
|
|
||
|
} catch (e) {
|
||
|
console.error(`Error in xc permissions.user.delete`, e);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static getPolicyPath() {
|
||
|
|
||
|
const projectConfig = jsonfile.readFileSync(path.join(process.cwd(), 'config.xc.json'));
|
||
|
return projectConfig.meta.projectType === 'rest' ? 'routers' : 'resolvers';
|
||
|
}
|
||
|
|
||
|
private static extractUniqueGqlPolicyRoles(filePermissions) {
|
||
|
return Object.values(filePermissions)
|
||
|
.flatMap(roles1 => Object.keys(roles1))
|
||
|
.filter((v, i, arr) => arr.indexOf(v) === i);
|
||
|
}
|
||
|
|
||
|
private static extractUniqueRoles(routesList: Route[]) {
|
||
|
const roles = routesList
|
||
|
.flatMap(
|
||
|
route => Object.keys(route.acl)
|
||
|
)
|
||
|
.filter((v, i, arr) => arr.indexOf(v) === i);
|
||
|
return roles;
|
||
|
}
|
||
|
|
||
|
|
||
|
private static groupRoutes(routes: Route[]): GroupedRoutes {
|
||
|
const groupedRoutes: GroupedRoutes = {};
|
||
|
for (const route of routes) {
|
||
|
groupedRoutes[route.path] = groupedRoutes[route.path] || {};
|
||
|
groupedRoutes[route.path][route.type] = route;
|
||
|
}
|
||
|
return groupedRoutes;
|
||
|
}
|
||
|
|
||
|
private static sortFiles(file1: string, file2: string): number {
|
||
|
return ((file1.indexOf('.bt.') > -1 ? 1 : 0) || (file1.indexOf('.hm.') > -1 ? 2 : 0))
|
||
|
- ((file2.indexOf('.bt.') > -1 ? 1 : 0) || (file2.indexOf('.hm.') > -1 ? 2 : 0));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
export default PermissionsMgr;
|
||
|
|
||
|
export interface Route {
|
||
|
type: string;
|
||
|
path: string;
|
||
|
acl: {
|
||
|
[key: string]: boolean
|
||
|
};
|
||
|
}
|
||
|
|
||
|
type httpMethods = 'get' | 'post' | 'patch' | 'put' | 'delete';
|
||
|
|
||
|
export interface GroupedRoutes {
|
||
|
[key: string]: {
|
||
|
[key in httpMethods]?: {
|
||
|
type: string;
|
||
|
path: string;
|
||
|
acl: {
|
||
|
[key: string]: boolean
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
|
||
|
*
|
||
|
* @author Naveen MR <oof1lab@gmail.com>
|
||
|
* @author Pranav C Balan <pranavxc@gmail.com>
|
||
|
*
|
||
|
* @license GNU AGPL version 3 or any later version
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU Affero General Public License as
|
||
|
* published by the Free Software Foundation, either version 3 of the
|
||
|
* License, or (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU Affero General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Affero General Public License
|
||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*
|
||
|
*/
|