mirror of https://github.com/Budibase/budibase.git
29 changed files with 263 additions and 150 deletions
@ -1,14 +1,20 @@ |
|||
const Router = require("@koa/router") |
|||
const controller = require("../controllers/accesslevel") |
|||
const authorized = require("../../middleware/authorized") |
|||
const { BUILDER } = require("../../utilities/security/permissions") |
|||
|
|||
const router = Router() |
|||
|
|||
router |
|||
.post("/api/accesslevels", controller.create) |
|||
.put("/api/accesslevels", controller.update) |
|||
.get("/api/accesslevels", controller.fetch) |
|||
.get("/api/accesslevels/:levelId", controller.find) |
|||
.delete("/api/accesslevels/:levelId/:rev", controller.destroy) |
|||
.patch("/api/accesslevels/:levelId", controller.patch) |
|||
.post("/api/accesslevels", authorized(BUILDER), controller.create) |
|||
.put("/api/accesslevels", authorized(BUILDER), controller.update) |
|||
.get("/api/accesslevels", authorized(BUILDER), controller.fetch) |
|||
.get("/api/accesslevels/:levelId", authorized(BUILDER), controller.find) |
|||
.delete( |
|||
"/api/accesslevels/:levelId/:rev", |
|||
authorized(BUILDER), |
|||
controller.destroy |
|||
) |
|||
.patch("/api/accesslevels/:levelId", authorized(BUILDER), controller.patch) |
|||
|
|||
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 |
|||
@ -0,0 +1,44 @@ |
|||
const { DocumentTypes, SEPARATOR } = require("../../db/utils") |
|||
|
|||
function makeAccessLevelId(baseId) { |
|||
return `${DocumentTypes.ACCESS_LEVEL}${SEPARATOR}${baseId}` |
|||
} |
|||
|
|||
// Permissions
|
|||
exports.READ_TABLE = "read-table" |
|||
exports.WRITE_TABLE = "write-table" |
|||
exports.READ_VIEW = "read-view" |
|||
exports.EXECUTE_AUTOMATION = "execute-automation" |
|||
exports.EXECUTE_WEBHOOK = "execute-webhook" |
|||
exports.USER_MANAGEMENT = "user-management" |
|||
exports.BUILDER = "builder" |
|||
exports.LIST_USERS = "list-users" |
|||
// Access Level IDs
|
|||
exports.ADMIN_LEVEL_ID = "ADMIN" |
|||
exports.POWERUSER_LEVEL_ID = "POWER_USER" |
|||
exports.BUILDER_LEVEL_ID = "BUILDER" |
|||
exports.ANON_LEVEL_ID = "ANON" |
|||
exports.BUILTIN_LEVELS = { |
|||
admin: { _id: makeAccessLevelId("ADMIN"), name: "Admin" }, |
|||
power: { _id: makeAccessLevelId("POWER_USER"), name: "Power user" }, |
|||
builder: { _id: makeAccessLevelId("BUILDER"), name: "Builder" }, |
|||
anon: { _id: makeAccessLevelId("ANON"), name: "Anonymous" }, |
|||
} |
|||
exports.BUILTIN_LEVEL_IDS = Object.values(exports.BUILTIN_LEVELS).map( |
|||
level => level._id |
|||
) |
|||
exports.PRETTY_ACCESS_LEVELS = { |
|||
[exports.ADMIN_LEVEL_ID]: "Admin", |
|||
[exports.POWERUSER_LEVEL_ID]: "Power user", |
|||
[exports.BUILDER_LEVEL_ID]: "Builder", |
|||
} |
|||
exports.adminPermissions = [ |
|||
{ |
|||
name: exports.USER_MANAGEMENT, |
|||
}, |
|||
] |
|||
|
|||
// to avoid circular dependencies this is included later, after exporting all enums
|
|||
const permissions = require("../permissions") |
|||
exports.generateAdminPermissions = permissions.generateAdminPermissions |
|||
exports.generatePowerUserPermissions = permissions.generatePowerUserPermissions |
|||
@ -0,0 +1,101 @@ |
|||
const { flatten } = require("lodash") |
|||
|
|||
exports.READ_TABLE = "read-table" |
|||
exports.WRITE_TABLE = "write-table" |
|||
exports.READ_VIEW = "read-view" |
|||
exports.EXECUTE_AUTOMATION = "execute-automation" |
|||
exports.EXECUTE_WEBHOOK = "execute-webhook" |
|||
exports.USER_MANAGEMENT = "user-management" |
|||
exports.BUILDER = "builder" |
|||
exports.LIST_USERS = "list-users" |
|||
|
|||
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 [] |
|||
} |
|||
} |
|||
|
|||
// TODO: need to expand on this
|
|||
exports.BUILTIN_PERMISSION_NAMES = { |
|||
READ_ONLY: "read_only", |
|||
WRITE: "write", |
|||
} |
|||
|
|||
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), |
|||
], |
|||
}, |
|||
} |
|||
|
|||
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