71 lines
2.2 KiB
JavaScript
71 lines
2.2 KiB
JavaScript
const {
|
|
getUserRoleHierarchy,
|
|
getRequiredResourceRole,
|
|
BUILTIN_ROLE_IDS,
|
|
} = require("@budibase/backend-core/roles")
|
|
const {
|
|
PermissionTypes,
|
|
doesHaveBasePermission,
|
|
} = require("@budibase/backend-core/permissions")
|
|
const builderMiddleware = require("./builder")
|
|
const { isWebhookEndpoint } = require("./utils")
|
|
|
|
function hasResource(ctx) {
|
|
return ctx.resourceId != null
|
|
}
|
|
|
|
module.exports =
|
|
(permType, permLevel = null) =>
|
|
async (ctx, next) => {
|
|
// webhooks don't need authentication, each webhook unique
|
|
// also internal requests (between services) don't need authorized
|
|
if (isWebhookEndpoint(ctx) || ctx.internal) {
|
|
return next()
|
|
}
|
|
|
|
if (!ctx.user) {
|
|
return ctx.throw(403, "No user info found")
|
|
}
|
|
|
|
// check general builder stuff, this middleware is a good way
|
|
// to find API endpoints which are builder focused
|
|
await builderMiddleware(ctx, permType)
|
|
|
|
const isAuthed = ctx.isAuthenticated
|
|
// builders for now have permission to do anything
|
|
let isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global
|
|
const isBuilderApi = permType === PermissionTypes.BUILDER
|
|
if (isBuilder) {
|
|
return next()
|
|
} else if (isBuilderApi && !isBuilder) {
|
|
return ctx.throw(403, "Not Authorized")
|
|
}
|
|
|
|
// need to check this first, in-case public access, don't check authed until last
|
|
const roleId = ctx.roleId || BUILTIN_ROLE_IDS.PUBLIC
|
|
const hierarchy = await getUserRoleHierarchy(ctx.appId, roleId, {
|
|
idOnly: false,
|
|
})
|
|
const permError = "User does not have permission"
|
|
let possibleRoleIds = []
|
|
if (hasResource(ctx)) {
|
|
possibleRoleIds = await getRequiredResourceRole(ctx.appId, permLevel, ctx)
|
|
}
|
|
// check if we found a role, if not fallback to base permissions
|
|
if (possibleRoleIds.length > 0) {
|
|
const found = hierarchy.find(
|
|
role => possibleRoleIds.indexOf(role._id) !== -1
|
|
)
|
|
return found ? next() : ctx.throw(403, permError)
|
|
} else if (!doesHaveBasePermission(permType, permLevel, hierarchy)) {
|
|
ctx.throw(403, permError)
|
|
}
|
|
|
|
// if they are not authed, then anything using the authorized middleware will fail
|
|
if (!isAuthed) {
|
|
ctx.throw(403, "Session not authenticated")
|
|
}
|
|
|
|
return next()
|
|
}
|