forked from tsai/budibase
64 changed files with 911 additions and 814 deletions
@ -1,22 +1,13 @@ |
|||||
|
import { Screen } from "./utils/Screen" |
||||
|
|
||||
export default { |
export default { |
||||
name: `Create from scratch`, |
name: `Create from scratch`, |
||||
create: () => createScreen(), |
create: () => createScreen(), |
||||
} |
} |
||||
|
|
||||
const createScreen = () => ({ |
const createScreen = () => { |
||||
props: { |
return new Screen() |
||||
_id: "", |
.mainType("div") |
||||
_component: "@budibase/standard-components/container", |
.component("@budibase/standard-components/container") |
||||
_styles: { |
.json() |
||||
normal: {}, |
} |
||||
hover: {}, |
|
||||
active: {}, |
|
||||
selected: {}, |
|
||||
}, |
|
||||
type: "div", |
|
||||
_children: [], |
|
||||
_instanceName: "", |
|
||||
}, |
|
||||
route: "", |
|
||||
name: "screen-id", |
|
||||
}) |
|
||||
|
|||||
@ -1,22 +1,13 @@ |
|||||
|
import { Screen } from "./utils/Screen" |
||||
|
|
||||
export default { |
export default { |
||||
name: `New Row (Empty)`, |
name: `New Row (Empty)`, |
||||
create: () => createScreen(), |
create: () => createScreen(), |
||||
} |
} |
||||
|
|
||||
const createScreen = () => ({ |
const createScreen = () => { |
||||
props: { |
return new Screen() |
||||
_id: "", |
.component("@budibase/standard-components/newrow") |
||||
_component: "@budibase/standard-components/newrow", |
.table("") |
||||
_styles: { |
.json() |
||||
normal: {}, |
} |
||||
hover: {}, |
|
||||
active: {}, |
|
||||
selected: {}, |
|
||||
}, |
|
||||
_children: [], |
|
||||
_instanceName: "", |
|
||||
table: "", |
|
||||
}, |
|
||||
route: "", |
|
||||
name: "screen-id", |
|
||||
}) |
|
||||
|
|||||
@ -1,22 +1,13 @@ |
|||||
|
import { Screen } from "./utils/Screen" |
||||
|
|
||||
export default { |
export default { |
||||
name: `Row Detail (Empty)`, |
name: `Row Detail (Empty)`, |
||||
create: () => createScreen(), |
create: () => createScreen(), |
||||
} |
} |
||||
|
|
||||
const createScreen = () => ({ |
const createScreen = () => { |
||||
props: { |
return new Screen() |
||||
_id: "", |
.component("@budibase/standard-components/rowdetail") |
||||
_component: "@budibase/standard-components/rowdetail", |
.table("") |
||||
_styles: { |
.json() |
||||
normal: {}, |
} |
||||
hover: {}, |
|
||||
active: {}, |
|
||||
selected: {}, |
|
||||
}, |
|
||||
_children: [], |
|
||||
_instanceName: "", |
|
||||
table: "", |
|
||||
}, |
|
||||
route: "", |
|
||||
name: "screen-id", |
|
||||
}) |
|
||||
|
|||||
@ -0,0 +1,36 @@ |
|||||
|
import { cloneDeep } from "lodash/fp" |
||||
|
|
||||
|
export class BaseStructure { |
||||
|
constructor(isScreen) { |
||||
|
this._isScreen = isScreen |
||||
|
this._children = [] |
||||
|
this._json = { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
addChild(child) { |
||||
|
this._children.push(child) |
||||
|
return this |
||||
|
} |
||||
|
|
||||
|
customProps(props) { |
||||
|
for (let key of Object.keys(props)) { |
||||
|
this._json[key] = props[key] |
||||
|
} |
||||
|
return this |
||||
|
} |
||||
|
|
||||
|
json() { |
||||
|
const structure = cloneDeep(this._json) |
||||
|
if (this._children.length !== 0) { |
||||
|
for (let child of this._children) { |
||||
|
if (this._isScreen) { |
||||
|
structure.props._children.push(child.json()) |
||||
|
} else { |
||||
|
structure._children.push(child.json()) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return structure |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
import { cloneDeep } from "lodash/fp" |
||||
|
import { v4 } from "uuid" |
||||
|
import { BaseStructure } from "./BaseStructure" |
||||
|
|
||||
|
export class Component extends BaseStructure { |
||||
|
constructor(name) { |
||||
|
super(false) |
||||
|
this._children = [] |
||||
|
this._json = { |
||||
|
_id: v4(), |
||||
|
_component: name, |
||||
|
_styles: { |
||||
|
normal: {}, |
||||
|
hover: {}, |
||||
|
active: {}, |
||||
|
selected: {}, |
||||
|
}, |
||||
|
_code: "", |
||||
|
className: "", |
||||
|
onLoad: [], |
||||
|
type: "", |
||||
|
_instanceName: "", |
||||
|
_children: [], |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
type(type) { |
||||
|
this._json.type = type |
||||
|
return this |
||||
|
} |
||||
|
|
||||
|
normalStyle(styling) { |
||||
|
this._json._styles.normal = styling |
||||
|
return this |
||||
|
} |
||||
|
|
||||
|
hoverStyle(styling) { |
||||
|
this._json._styles.hover = styling |
||||
|
return this |
||||
|
} |
||||
|
|
||||
|
text(text) { |
||||
|
this._json.text = text |
||||
|
return this |
||||
|
} |
||||
|
|
||||
|
// TODO: do we need this
|
||||
|
instanceName(name) { |
||||
|
this._json._instanceName = name |
||||
|
return this |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,56 @@ |
|||||
|
import { BaseStructure } from "./BaseStructure" |
||||
|
|
||||
|
export class Screen extends BaseStructure { |
||||
|
constructor() { |
||||
|
super(true) |
||||
|
this._json = { |
||||
|
props: { |
||||
|
_id: "", |
||||
|
_component: "", |
||||
|
_styles: { |
||||
|
normal: {}, |
||||
|
hover: {}, |
||||
|
active: {}, |
||||
|
selected: {}, |
||||
|
}, |
||||
|
_children: [], |
||||
|
_instanceName: "", |
||||
|
}, |
||||
|
routing: { |
||||
|
route: "", |
||||
|
accessLevelId: "", |
||||
|
}, |
||||
|
name: "screen-id", |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
component(name) { |
||||
|
this._json.props._component = name |
||||
|
return this |
||||
|
} |
||||
|
|
||||
|
table(tableName) { |
||||
|
this._json.props.table = tableName |
||||
|
return this |
||||
|
} |
||||
|
|
||||
|
mainType(type) { |
||||
|
this._json.type = type |
||||
|
return this |
||||
|
} |
||||
|
|
||||
|
route(route) { |
||||
|
this._json.routing.route = route |
||||
|
return this |
||||
|
} |
||||
|
|
||||
|
name(name) { |
||||
|
this._json.name = name |
||||
|
return this |
||||
|
} |
||||
|
|
||||
|
instanceName(name) { |
||||
|
this._json.props._instanceName = name |
||||
|
return this |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
import { Component } from "./Component" |
||||
|
|
||||
|
export function linkComponent(tableName) { |
||||
|
return new Component("@budibase/standard-components/link") |
||||
|
.normalStyle({ |
||||
|
color: "#757575", |
||||
|
"text-transform": "capitalize", |
||||
|
}) |
||||
|
.hoverStyle({ |
||||
|
color: "#4285f4", |
||||
|
}) |
||||
|
.text(tableName) |
||||
|
.customProps({ |
||||
|
url: `/${tableName.toLowerCase()}`, |
||||
|
openInNewTab: false, |
||||
|
color: "", |
||||
|
hoverColor: "", |
||||
|
underline: false, |
||||
|
fontSize: "", |
||||
|
fontFamily: "initial", |
||||
|
}) |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
const { getRoutingInfo } = require("../../utilities/routing") |
||||
|
const { AccessController } = require("../../utilities/security/accessLevels") |
||||
|
|
||||
|
async function getRoutingStructure(appId) { |
||||
|
let baseRouting = await getRoutingInfo(appId) |
||||
|
return baseRouting |
||||
|
} |
||||
|
|
||||
|
exports.fetch = async ctx => { |
||||
|
ctx.body = await getRoutingStructure(ctx.appId) |
||||
|
} |
||||
|
|
||||
|
exports.clientFetch = async ctx => { |
||||
|
const routing = getRoutingStructure(ctx.appId) |
||||
|
// use the access controller to pick which access level is applicable to this user
|
||||
|
const accessController = new AccessController(ctx.appId) |
||||
|
} |
||||
@ -1,14 +1,18 @@ |
|||||
const Router = require("@koa/router") |
const Router = require("@koa/router") |
||||
const controller = require("../controllers/accesslevel") |
const controller = require("../controllers/accesslevel") |
||||
|
const authorized = require("../../middleware/authorized") |
||||
|
const { BUILDER } = require("../../utilities/security/permissions") |
||||
|
|
||||
const router = Router() |
const router = Router() |
||||
|
|
||||
router |
router |
||||
.post("/api/accesslevels", controller.create) |
.post("/api/accesslevels", authorized(BUILDER), controller.save) |
||||
.put("/api/accesslevels", controller.update) |
.get("/api/accesslevels", authorized(BUILDER), controller.fetch) |
||||
.get("/api/accesslevels", controller.fetch) |
.get("/api/accesslevels/:levelId", authorized(BUILDER), controller.find) |
||||
.get("/api/accesslevels/:levelId", controller.find) |
.delete( |
||||
.delete("/api/accesslevels/:levelId/:rev", controller.destroy) |
"/api/accesslevels/:levelId/:rev", |
||||
.patch("/api/accesslevels/:levelId", controller.patch) |
authorized(BUILDER), |
||||
|
controller.destroy |
||||
|
) |
||||
|
|
||||
module.exports = router |
module.exports = router |
||||
|
|||||
@ -0,0 +1,13 @@ |
|||||
|
const Router = require("@koa/router") |
||||
|
const authorized = require("../../middleware/authorized") |
||||
|
const { BUILDER } = require("../../utilities/security/permissions") |
||||
|
const controller = require("../controllers/routing") |
||||
|
|
||||
|
const router = Router() |
||||
|
|
||||
|
// gets the full structure, not just the correct screen ID for your access level
|
||||
|
router |
||||
|
.get("/api/routing", authorized(BUILDER), controller.fetch) |
||||
|
.get("/api/routing/client", controller.clientFetch) |
||||
|
|
||||
|
module.exports = router |
||||
@ -1,36 +0,0 @@ |
|||||
// Permissions
|
|
||||
module.exports.READ_TABLE = "read-table" |
|
||||
module.exports.WRITE_TABLE = "write-table" |
|
||||
module.exports.READ_VIEW = "read-view" |
|
||||
module.exports.EXECUTE_AUTOMATION = "execute-automation" |
|
||||
module.exports.EXECUTE_WEBHOOK = "execute-webhook" |
|
||||
module.exports.USER_MANAGEMENT = "user-management" |
|
||||
module.exports.BUILDER = "builder" |
|
||||
module.exports.LIST_USERS = "list-users" |
|
||||
// Access Level IDs
|
|
||||
module.exports.ADMIN_LEVEL_ID = "ADMIN" |
|
||||
module.exports.POWERUSER_LEVEL_ID = "POWER_USER" |
|
||||
module.exports.BUILDER_LEVEL_ID = "BUILDER" |
|
||||
module.exports.ANON_LEVEL_ID = "ANON" |
|
||||
module.exports.ACCESS_LEVELS = [ |
|
||||
module.exports.ADMIN_LEVEL_ID, |
|
||||
module.exports.POWERUSER_LEVEL_ID, |
|
||||
module.exports.BUILDER_LEVEL_ID, |
|
||||
module.exports.ANON_LEVEL_ID, |
|
||||
] |
|
||||
module.exports.PRETTY_ACCESS_LEVELS = { |
|
||||
[module.exports.ADMIN_LEVEL_ID]: "Admin", |
|
||||
[module.exports.POWERUSER_LEVEL_ID]: "Power user", |
|
||||
[module.exports.BUILDER_LEVEL_ID]: "Builder", |
|
||||
} |
|
||||
module.exports.adminPermissions = [ |
|
||||
{ |
|
||||
name: module.exports.USER_MANAGEMENT, |
|
||||
}, |
|
||||
] |
|
||||
|
|
||||
// to avoid circular dependencies this is included later, after exporting all enums
|
|
||||
const permissions = require("./permissions") |
|
||||
module.exports.generateAdminPermissions = permissions.generateAdminPermissions |
|
||||
module.exports.generatePowerUserPermissions = |
|
||||
permissions.generatePowerUserPermissions |
|
||||
@ -1,66 +0,0 @@ |
|||||
const viewController = require("../api/controllers/view") |
|
||||
const tableController = require("../api/controllers/table") |
|
||||
const automationController = require("../api/controllers/automation") |
|
||||
const accessLevels = require("./accessLevels") |
|
||||
|
|
||||
// this has been broken out to reduce risk of circular dependency from utilities, no enums defined here
|
|
||||
const generateAdminPermissions = async appId => [ |
|
||||
...accessLevels.adminPermissions, |
|
||||
...(await generatePowerUserPermissions(appId)), |
|
||||
] |
|
||||
|
|
||||
const generatePowerUserPermissions = async appId => { |
|
||||
const fetchTablesCtx = { |
|
||||
user: { |
|
||||
appId, |
|
||||
}, |
|
||||
} |
|
||||
await tableController.fetch(fetchTablesCtx) |
|
||||
const tables = fetchTablesCtx.body |
|
||||
|
|
||||
const fetchViewsCtx = { |
|
||||
user: { |
|
||||
appId, |
|
||||
}, |
|
||||
} |
|
||||
await viewController.fetch(fetchViewsCtx) |
|
||||
const views = fetchViewsCtx.body |
|
||||
|
|
||||
const fetchAutomationsCtx = { |
|
||||
user: { |
|
||||
appId, |
|
||||
}, |
|
||||
} |
|
||||
await automationController.fetch(fetchAutomationsCtx) |
|
||||
const automations = fetchAutomationsCtx.body |
|
||||
|
|
||||
const readTablePermissions = tables.map(m => ({ |
|
||||
itemId: m._id, |
|
||||
name: accessLevels.READ_TABLE, |
|
||||
})) |
|
||||
|
|
||||
const writeTablePermissions = tables.map(m => ({ |
|
||||
itemId: m._id, |
|
||||
name: accessLevels.WRITE_TABLE, |
|
||||
})) |
|
||||
|
|
||||
const viewPermissions = views.map(v => ({ |
|
||||
itemId: v.name, |
|
||||
name: accessLevels.READ_VIEW, |
|
||||
})) |
|
||||
|
|
||||
const executeAutomationPermissions = automations.map(w => ({ |
|
||||
itemId: w._id, |
|
||||
name: accessLevels.EXECUTE_AUTOMATION, |
|
||||
})) |
|
||||
|
|
||||
return [ |
|
||||
...readTablePermissions, |
|
||||
...writeTablePermissions, |
|
||||
...viewPermissions, |
|
||||
...executeAutomationPermissions, |
|
||||
{ name: accessLevels.LIST_USERS }, |
|
||||
] |
|
||||
} |
|
||||
module.exports.generateAdminPermissions = generateAdminPermissions |
|
||||
module.exports.generatePowerUserPermissions = generatePowerUserPermissions |
|
||||
@ -0,0 +1,24 @@ |
|||||
|
const CouchDB = require("../../db") |
||||
|
const { createRoutingView } = require("./routingUtils") |
||||
|
const { ViewNames, getQueryIndex, UNICODE_MAX } = require("../../db/utils") |
||||
|
|
||||
|
exports.getRoutingInfo = async appId => { |
||||
|
const db = new CouchDB(appId) |
||||
|
try { |
||||
|
const allRouting = await db.query(getQueryIndex(ViewNames.ROUTING), { |
||||
|
startKey: "", |
||||
|
endKey: UNICODE_MAX, |
||||
|
}) |
||||
|
return allRouting.rows.map(row => row.value) |
||||
|
} catch (err) { |
||||
|
// check if the view doesn't exist, it should for all new instances
|
||||
|
if (err != null && err.name === "not_found") { |
||||
|
await createRoutingView(appId) |
||||
|
return exports.getRoutingInfo(appId) |
||||
|
} else { |
||||
|
throw err |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
exports.createRoutingView = createRoutingView |
||||
@ -0,0 +1,24 @@ |
|||||
|
const CouchDB = require("../../db") |
||||
|
const { DocumentTypes, SEPARATOR, ViewNames } = require("../../db/utils") |
||||
|
const SCREEN_PREFIX = DocumentTypes.SCREEN + SEPARATOR |
||||
|
|
||||
|
exports.createRoutingView = async appId => { |
||||
|
const db = new CouchDB(appId) |
||||
|
const designDoc = await db.get("_design/database") |
||||
|
const view = { |
||||
|
// if using variables in a map function need to inject them before use
|
||||
|
map: `function(doc) {
|
||||
|
if (doc._id.startsWith("${SCREEN_PREFIX}")) { |
||||
|
emit(doc._id, { |
||||
|
id: doc._id, |
||||
|
routing: doc.routing, |
||||
|
}) |
||||
|
} |
||||
|
}`,
|
||||
|
} |
||||
|
designDoc.views = { |
||||
|
...designDoc.views, |
||||
|
[ViewNames.ROUTING]: view, |
||||
|
} |
||||
|
await db.put(designDoc) |
||||
|
} |
||||
@ -0,0 +1,112 @@ |
|||||
|
const CouchDB = require("../../db") |
||||
|
|
||||
|
const BUILTIN_IDS = { |
||||
|
ADMIN: "ADMIN", |
||||
|
POWER: "POWER_USER", |
||||
|
BASIC: "BASIC", |
||||
|
ANON: "ANON", |
||||
|
BUILDER: "BUILDER", |
||||
|
} |
||||
|
|
||||
|
function AccessLevel(id, name, inherits = null) { |
||||
|
this._id = id |
||||
|
this.name = name |
||||
|
if (inherits) { |
||||
|
this.inherits = inherits |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
exports.BUILTIN_LEVELS = { |
||||
|
ADMIN: new AccessLevel(BUILTIN_IDS.ADMIN, "Admin", BUILTIN_IDS.POWER), |
||||
|
POWER: new AccessLevel(BUILTIN_IDS.POWER, "Admin", BUILTIN_IDS.BASIC), |
||||
|
BASIC: new AccessLevel(BUILTIN_IDS.BASIC, "Basic", BUILTIN_IDS.ANON), |
||||
|
ANON: new AccessLevel(BUILTIN_IDS.ANON, "Anonymous"), |
||||
|
BUILDER: new AccessLevel(BUILTIN_IDS.BUILDER, "Builder"), |
||||
|
} |
||||
|
|
||||
|
exports.BUILTIN_LEVEL_ID_ARRAY = Object.values(exports.BUILTIN_LEVELS).map( |
||||
|
level => level._id |
||||
|
) |
||||
|
|
||||
|
exports.BUILTIN_LEVEL_NAME_ARRAY = Object.values(exports.BUILTIN_LEVELS).map( |
||||
|
level => level.name |
||||
|
) |
||||
|
|
||||
|
function isBuiltin(accessLevel) { |
||||
|
return exports.BUILTIN_LEVEL_ID_ARRAY.indexOf(accessLevel) !== -1 |
||||
|
} |
||||
|
|
||||
|
class AccessController { |
||||
|
constructor(appId) { |
||||
|
this.appId = appId |
||||
|
this.accessLevels = {} |
||||
|
} |
||||
|
|
||||
|
async getAccessLevel(accessLevelId) { |
||||
|
if (this.accessLevels[accessLevelId]) { |
||||
|
return this.accessLevels[accessLevelId] |
||||
|
} |
||||
|
let accessLevel |
||||
|
if (isBuiltin(accessLevelId)) { |
||||
|
accessLevel = Object.values(exports.BUILTIN_LEVELS).find( |
||||
|
level => level._id === accessLevelId |
||||
|
) |
||||
|
} else { |
||||
|
const db = new CouchDB(this.appId) |
||||
|
accessLevel = await db.get(accessLevelId) |
||||
|
} |
||||
|
this.accessLevels[accessLevelId] = accessLevel |
||||
|
return accessLevel |
||||
|
} |
||||
|
|
||||
|
async hasAccess(tryingAccessLevelId, userAccessLevelId) { |
||||
|
// special cases, the screen has no access level, the access levels are the same or the user
|
||||
|
// is currently in the builder
|
||||
|
if ( |
||||
|
tryingAccessLevelId == null || |
||||
|
tryingAccessLevelId === "" || |
||||
|
tryingAccessLevelId === userAccessLevelId || |
||||
|
userAccessLevelId === BUILTIN_IDS.BUILDER |
||||
|
) { |
||||
|
return true |
||||
|
} |
||||
|
let userAccess = await this.getAccessLevel(userAccessLevelId) |
||||
|
// check if inherited makes it possible
|
||||
|
while (userAccess.inherits) { |
||||
|
if (tryingAccessLevelId === userAccess.inherits) { |
||||
|
return true |
||||
|
} |
||||
|
// go to get the inherited incase it inherits anything
|
||||
|
userAccess = await this.getAccessLevel(userAccess.inherits) |
||||
|
} |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
async checkScreensAccess(screens, userAccessLevelId) { |
||||
|
let accessibleScreens = [] |
||||
|
// don't want to handle this with Promise.all as this would mean all custom access levels would be
|
||||
|
// retrieved at same time, it is likely a custom levels will be re-used and therefore want
|
||||
|
// to work in sync for performance save
|
||||
|
for (let screen of screens) { |
||||
|
const accessible = await this.checkScreenAccess(screen, userAccessLevelId) |
||||
|
if (accessible) { |
||||
|
accessibleScreens.push(accessible) |
||||
|
} |
||||
|
} |
||||
|
return accessibleScreens |
||||
|
} |
||||
|
|
||||
|
async checkScreenAccess(screen, userAccessLevelId) { |
||||
|
const accessLevelId = |
||||
|
screen && screen.routing ? screen.routing.accessLevelId : null |
||||
|
if (await this.hasAccess(accessLevelId, userAccessLevelId)) { |
||||
|
return screen |
||||
|
} |
||||
|
return null |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
exports.AccessController = AccessController |
||||
|
exports.BUILTIN_LEVEL_IDS = BUILTIN_IDS |
||||
|
exports.isBuiltin = isBuiltin |
||||
|
exports.AccessLevel = AccessLevel |
||||
@ -0,0 +1,113 @@ |
|||||
|
const { flatten } = require("lodash") |
||||
|
|
||||
|
const PermissionLevels = { |
||||
|
READ: "read", |
||||
|
WRITE: "write", |
||||
|
EXECUTE: "execute", |
||||
|
ADMIN: "admin", |
||||
|
} |
||||
|
|
||||
|
const PermissionTypes = { |
||||
|
TABLE: "table", |
||||
|
USER: "user", |
||||
|
AUTOMATION: "automation", |
||||
|
WEBHOOK: "webhook", |
||||
|
BUILDER: "builder", |
||||
|
VIEW: "view", |
||||
|
} |
||||
|
|
||||
|
function Permission(type, level) { |
||||
|
this.level = level |
||||
|
this.type = type |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Given the specified permission level for the user return the levels they are allowed to carry out. |
||||
|
* @param {string} userPermLevel The permission level of the user. |
||||
|
* @return {string[]} All the permission levels this user is allowed to carry out. |
||||
|
*/ |
||||
|
function getAllowedLevels(userPermLevel) { |
||||
|
switch (userPermLevel) { |
||||
|
case PermissionLevels.READ: |
||||
|
return [PermissionLevels.READ] |
||||
|
case PermissionLevels.WRITE: |
||||
|
return [PermissionLevels.READ, PermissionLevels.WRITE] |
||||
|
case PermissionLevels.EXECUTE: |
||||
|
return [PermissionLevels.EXECUTE] |
||||
|
case PermissionLevels.ADMIN: |
||||
|
return [ |
||||
|
PermissionLevels.READ, |
||||
|
PermissionLevels.WRITE, |
||||
|
PermissionLevels.EXECUTE, |
||||
|
] |
||||
|
default: |
||||
|
return [] |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
exports.BUILTIN_PERMISSION_NAMES = { |
||||
|
READ_ONLY: "read_only", |
||||
|
WRITE: "write", |
||||
|
ADMIN: "admin", |
||||
|
POWER: "power", |
||||
|
} |
||||
|
|
||||
|
exports.BUILTIN_PERMISSIONS = { |
||||
|
READ_ONLY: { |
||||
|
name: exports.BUILTIN_PERMISSION_NAMES.READ_ONLY, |
||||
|
permissions: [ |
||||
|
new Permission(PermissionTypes.TABLE, PermissionLevels.READ), |
||||
|
new Permission(PermissionTypes.VIEW, PermissionLevels.READ), |
||||
|
], |
||||
|
}, |
||||
|
WRITE: { |
||||
|
name: exports.BUILTIN_PERMISSION_NAMES.WRITE, |
||||
|
permissions: [ |
||||
|
new Permission(PermissionTypes.TABLE, PermissionLevels.WRITE), |
||||
|
new Permission(PermissionTypes.VIEW, PermissionLevels.READ), |
||||
|
], |
||||
|
}, |
||||
|
POWER: { |
||||
|
name: exports.BUILTIN_PERMISSION_NAMES.POWER, |
||||
|
permissions: [ |
||||
|
new Permission(PermissionTypes.TABLE, PermissionLevels.WRITE), |
||||
|
new Permission(PermissionTypes.USER, PermissionLevels.READ), |
||||
|
new Permission(PermissionTypes.AUTOMATION, PermissionLevels.EXECUTE), |
||||
|
new Permission(PermissionTypes.VIEW, PermissionLevels.READ), |
||||
|
new Permission(PermissionTypes.WEBHOOK, PermissionLevels.READ), |
||||
|
], |
||||
|
}, |
||||
|
ADMIN: { |
||||
|
name: exports.BUILTIN_PERMISSION_NAMES.ADMIN, |
||||
|
permissions: [ |
||||
|
new Permission(PermissionTypes.TABLE, PermissionLevels.ADMIN), |
||||
|
new Permission(PermissionTypes.USER, PermissionLevels.ADMIN), |
||||
|
new Permission(PermissionTypes.AUTOMATION, PermissionLevels.ADMIN), |
||||
|
new Permission(PermissionTypes.VIEW, PermissionLevels.ADMIN), |
||||
|
new Permission(PermissionTypes.WEBHOOK, PermissionLevels.READ), |
||||
|
], |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
exports.doesHavePermission = (permType, permLevel, userPermissionNames) => { |
||||
|
const builtins = Object.values(exports.BUILTIN_PERMISSIONS) |
||||
|
let permissions = flatten( |
||||
|
builtins |
||||
|
.filter(builtin => userPermissionNames.indexOf(builtin.name) !== -1) |
||||
|
.map(builtin => builtin.permissions) |
||||
|
) |
||||
|
for (let permission of permissions) { |
||||
|
if ( |
||||
|
permission.type === permType && |
||||
|
getAllowedLevels(permission.level).indexOf(permLevel) !== -1 |
||||
|
) { |
||||
|
return true |
||||
|
} |
||||
|
} |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
// utility as a lot of things need simply the builder permission
|
||||
|
exports.BUILDER = PermissionTypes.BUILDER |
||||
|
exports.PermissionTypes = PermissionTypes |
||||
|
exports.PermissionLevels = PermissionLevels |
||||
Loading…
Reference in new issue