Some updates to RBAC backend, try to make switch to object support level -> roleID.
This commit is contained in:
parent
a3ae17be8e
commit
091b4ee95d
|
@ -4,11 +4,13 @@ const {
|
||||||
PermissionTypes,
|
PermissionTypes,
|
||||||
higherPermission,
|
higherPermission,
|
||||||
getBuiltinPermissionByID,
|
getBuiltinPermissionByID,
|
||||||
|
isPermissionLevelHigherThanRead,
|
||||||
} = require("../../utilities/security/permissions")
|
} = require("../../utilities/security/permissions")
|
||||||
const {
|
const {
|
||||||
isBuiltin,
|
isBuiltin,
|
||||||
getDBRoleID,
|
getDBRoleID,
|
||||||
getExternalRoleID,
|
getExternalRoleID,
|
||||||
|
lowerBuiltinRoleID,
|
||||||
BUILTIN_ROLES,
|
BUILTIN_ROLES,
|
||||||
} = require("../../utilities/security/roles")
|
} = require("../../utilities/security/roles")
|
||||||
const { getRoleParams, DocumentTypes } = require("../../db/utils")
|
const { getRoleParams, DocumentTypes } = require("../../db/utils")
|
||||||
|
@ -20,33 +22,31 @@ const PermissionUpdateType = {
|
||||||
ADD: "add",
|
ADD: "add",
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBasePermissions(resourceId) {
|
const SUPPORTED_LEVELS = [PermissionLevels.WRITE, PermissionLevels.READ]
|
||||||
|
|
||||||
|
function getPermissionType(resourceId) {
|
||||||
const docType = DocumentTypes.filter(docType =>
|
const docType = DocumentTypes.filter(docType =>
|
||||||
resourceId.startsWith(docType)
|
resourceId.startsWith(docType)
|
||||||
)[0]
|
)[0]
|
||||||
const levelsToFind = [PermissionLevels.WRITE, PermissionLevels.READ]
|
|
||||||
let type
|
|
||||||
switch (docType) {
|
switch (docType) {
|
||||||
case DocumentTypes.TABLE:
|
case DocumentTypes.TABLE:
|
||||||
case DocumentTypes.ROW:
|
case DocumentTypes.ROW:
|
||||||
type = PermissionTypes.TABLE
|
return PermissionTypes.TABLE
|
||||||
break
|
|
||||||
case DocumentTypes.AUTOMATION:
|
case DocumentTypes.AUTOMATION:
|
||||||
type = PermissionTypes.AUTOMATION
|
return PermissionTypes.AUTOMATION
|
||||||
break
|
|
||||||
case DocumentTypes.WEBHOOK:
|
case DocumentTypes.WEBHOOK:
|
||||||
type = PermissionTypes.WEBHOOK
|
return PermissionTypes.WEBHOOK
|
||||||
break
|
|
||||||
case DocumentTypes.QUERY:
|
case DocumentTypes.QUERY:
|
||||||
case DocumentTypes.DATASOURCE:
|
case DocumentTypes.DATASOURCE:
|
||||||
type = PermissionTypes.QUERY
|
return PermissionTypes.QUERY
|
||||||
break
|
|
||||||
default:
|
default:
|
||||||
// views don't have an ID, will end up here
|
// views don't have an ID, will end up here
|
||||||
type = PermissionTypes.VIEW
|
return PermissionTypes.VIEW
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getBasePermissions(resourceId) {
|
||||||
|
const type = getPermissionType(resourceId)
|
||||||
const permissions = {}
|
const permissions = {}
|
||||||
for (let [roleId, role] of Object.entries(BUILTIN_ROLES)) {
|
for (let [roleId, role] of Object.entries(BUILTIN_ROLES)) {
|
||||||
if (!role.permissionId) {
|
if (!role.permissionId) {
|
||||||
|
@ -55,10 +55,17 @@ function getBasePermissions(resourceId) {
|
||||||
const perms = getBuiltinPermissionByID(role.permissionId)
|
const perms = getBuiltinPermissionByID(role.permissionId)
|
||||||
const typedPermission = perms.permissions.find(perm => perm.type === type)
|
const typedPermission = perms.permissions.find(perm => perm.type === type)
|
||||||
if (typedPermission) {
|
if (typedPermission) {
|
||||||
// TODO: need to get the lowest role
|
const level = typedPermission.level
|
||||||
// TODO: store the read/write with the lowest role
|
permissions[level] = lowerBuiltinRoleID(permissions[level], roleId)
|
||||||
|
if (isPermissionLevelHigherThanRead(level)) {
|
||||||
|
permissions[PermissionLevels.READ] = lowerBuiltinRoleID(
|
||||||
|
permissions[PermissionLevels.READ],
|
||||||
|
roleId
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return permissions
|
||||||
}
|
}
|
||||||
|
|
||||||
// utility function to stop this repetition - permissions always stored under roles
|
// utility function to stop this repetition - permissions always stored under roles
|
||||||
|
@ -132,7 +139,7 @@ exports.fetchBuiltin = function(ctx) {
|
||||||
|
|
||||||
exports.fetchLevels = function(ctx) {
|
exports.fetchLevels = function(ctx) {
|
||||||
// for now only provide the read/write perms externally
|
// for now only provide the read/write perms externally
|
||||||
ctx.body = [PermissionLevels.WRITE, PermissionLevels.READ]
|
ctx.body = SUPPORTED_LEVELS
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.fetch = async function(ctx) {
|
exports.fetch = async function(ctx) {
|
||||||
|
@ -167,11 +174,12 @@ exports.getResourcePerms = async function(ctx) {
|
||||||
)
|
)
|
||||||
const roles = body.rows.map(row => row.doc)
|
const roles = body.rows.map(row => row.doc)
|
||||||
const resourcePerms = {}
|
const resourcePerms = {}
|
||||||
for (let role of roles) {
|
for (let level of SUPPORTED_LEVELS) {
|
||||||
|
for (let role of roles)
|
||||||
// update the various roleIds in the resource permissions
|
// update the various roleIds in the resource permissions
|
||||||
if (role.permissions && role.permissions[resourceId]) {
|
if (role.permissions && role.permissions[resourceId]) {
|
||||||
const roleId = getExternalRoleID(role._id)
|
const roleId = getExternalRoleID(role._id)
|
||||||
resourcePerms[roleId] = higherPermission(
|
resourcePerms[level] = higherPermission(
|
||||||
resourcePerms[roleId],
|
resourcePerms[roleId],
|
||||||
role.permissions[resourceId]
|
role.permissions[resourceId]
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,6 +23,22 @@ function Permission(type, level) {
|
||||||
this.type = type
|
this.type = type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function levelToNumber(perm) {
|
||||||
|
switch (perm) {
|
||||||
|
// not everything has execute privileges
|
||||||
|
case PermissionLevels.EXECUTE:
|
||||||
|
return 0
|
||||||
|
case PermissionLevels.READ:
|
||||||
|
return 1
|
||||||
|
case PermissionLevels.WRITE:
|
||||||
|
return 2
|
||||||
|
case PermissionLevels.ADMIN:
|
||||||
|
return 3
|
||||||
|
default:
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the specified permission level for the user return the levels they are allowed to carry out.
|
* 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.
|
* @param {string} userPermLevel The permission level of the user.
|
||||||
|
@ -149,22 +165,11 @@ exports.doesHaveBasePermission = (permType, permLevel, permissionIds) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.higherPermission = (perm1, perm2) => {
|
exports.higherPermission = (perm1, perm2) => {
|
||||||
function toNum(perm) {
|
return levelToNumber(perm1) > levelToNumber(perm2) ? perm1 : perm2
|
||||||
switch (perm) {
|
}
|
||||||
// not everything has execute privileges
|
|
||||||
case PermissionLevels.EXECUTE:
|
exports.isPermissionLevelHigherThanRead = level => {
|
||||||
return 0
|
return levelToNumber(level) > 1
|
||||||
case PermissionLevels.READ:
|
|
||||||
return 1
|
|
||||||
case PermissionLevels.WRITE:
|
|
||||||
return 2
|
|
||||||
case PermissionLevels.ADMIN:
|
|
||||||
return 3
|
|
||||||
default:
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return toNum(perm1) > toNum(perm2) ? perm1 : perm2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// utility as a lot of things need simply the builder permission
|
// utility as a lot of things need simply the builder permission
|
||||||
|
|
|
@ -222,6 +222,31 @@ exports.getExternalRoleID = roleId => {
|
||||||
return roleId
|
return roleId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whichever roleID is lower.
|
||||||
|
*/
|
||||||
|
exports.lowerRoleID = async (appId, roleId1, roleId2) => {
|
||||||
|
// TODO: need to make this function work
|
||||||
|
const MAX = Object.values(BUILTIN_IDS).length + 1
|
||||||
|
async function toNum(id) {
|
||||||
|
if (id === BUILTIN_IDS.ADMIN || id === BUILTIN_IDS.BUILDER) {
|
||||||
|
return MAX
|
||||||
|
}
|
||||||
|
let role = await exports.getRole(appId, id),
|
||||||
|
count = 0
|
||||||
|
do {
|
||||||
|
if (!role) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
role = exports.BUILTIN_ROLES[role.inherits]
|
||||||
|
count++
|
||||||
|
} while (role !== null)
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
const [num1, num2] = Promise.all([toNum(roleId1), toNum(roleId2)])
|
||||||
|
return num1 > num2 ? roleId2 : roleId1
|
||||||
|
}
|
||||||
|
|
||||||
exports.AccessController = AccessController
|
exports.AccessController = AccessController
|
||||||
exports.BUILTIN_ROLE_IDS = BUILTIN_IDS
|
exports.BUILTIN_ROLE_IDS = BUILTIN_IDS
|
||||||
exports.isBuiltin = isBuiltin
|
exports.isBuiltin = isBuiltin
|
||||||
|
|
Loading…
Reference in New Issue