2020-12-03 06:08:25 +13:00
|
|
|
const {
|
|
|
|
BUILTIN_ROLE_IDS,
|
2021-02-09 06:52:22 +13:00
|
|
|
getUserPermissions,
|
2020-12-03 06:08:25 +13:00
|
|
|
} = require("../utilities/security/roles")
|
2020-11-13 06:06:55 +13:00
|
|
|
const {
|
|
|
|
PermissionTypes,
|
2021-02-09 06:52:22 +13:00
|
|
|
doesHaveResourcePermission,
|
|
|
|
doesHaveBasePermission,
|
2020-11-13 06:06:55 +13:00
|
|
|
} = require("../utilities/security/permissions")
|
2020-10-29 09:35:06 +13:00
|
|
|
const env = require("../environment")
|
2020-12-10 06:10:53 +13:00
|
|
|
const { isAPIKeyValid } = require("../utilities/security/apikey")
|
2020-10-14 09:33:56 +13:00
|
|
|
const { AuthTypes } = require("../constants")
|
2020-05-28 04:23:01 +12:00
|
|
|
|
2020-12-03 02:20:56 +13:00
|
|
|
const ADMIN_ROLES = [BUILTIN_ROLE_IDS.ADMIN, BUILTIN_ROLE_IDS.BUILDER]
|
2020-11-12 06:34:15 +13:00
|
|
|
|
2021-02-09 06:52:22 +13:00
|
|
|
function hasResource(ctx) {
|
|
|
|
return ctx.resourceId != null
|
|
|
|
}
|
|
|
|
|
2020-11-12 06:34:15 +13:00
|
|
|
module.exports = (permType, permLevel = null) => async (ctx, next) => {
|
2021-03-25 07:21:23 +13:00
|
|
|
if (env.isProd() && ctx.headers["x-api-key"] && ctx.headers["x-instanceid"]) {
|
2020-10-12 23:57:37 +13:00
|
|
|
// api key header passed by external webhook
|
2020-12-10 06:10:53 +13:00
|
|
|
if (await isAPIKeyValid(ctx.headers["x-api-key"])) {
|
2020-10-13 01:32:52 +13:00
|
|
|
ctx.auth = {
|
2020-10-14 09:33:56 +13:00
|
|
|
authenticated: AuthTypes.EXTERNAL,
|
2020-10-13 01:32:52 +13:00
|
|
|
apiKey: ctx.headers["x-api-key"],
|
|
|
|
}
|
2020-10-12 23:57:37 +13:00
|
|
|
ctx.user = {
|
2020-10-29 23:28:27 +13:00
|
|
|
appId: ctx.headers["x-instanceid"],
|
2020-10-12 23:57:37 +13:00
|
|
|
}
|
|
|
|
return next()
|
|
|
|
}
|
|
|
|
|
2021-03-10 00:27:12 +13:00
|
|
|
return ctx.throw(403, "API key invalid")
|
2020-10-12 23:57:37 +13:00
|
|
|
}
|
|
|
|
|
2020-06-19 03:59:31 +12:00
|
|
|
if (!ctx.user) {
|
2021-03-10 00:27:12 +13:00
|
|
|
return ctx.throw(403, "No user info found")
|
2020-06-19 03:59:31 +12:00
|
|
|
}
|
|
|
|
|
2020-12-03 02:20:56 +13:00
|
|
|
const role = ctx.user.role
|
2021-03-23 05:39:11 +13:00
|
|
|
const isAdmin = ADMIN_ROLES.includes(role._id)
|
|
|
|
const isAuthed = ctx.auth.authenticated
|
|
|
|
|
2021-02-09 06:52:22 +13:00
|
|
|
const { basePermissions, permissions } = await getUserPermissions(
|
|
|
|
ctx.appId,
|
|
|
|
role._id
|
|
|
|
)
|
2020-05-28 04:23:01 +12:00
|
|
|
|
2021-02-10 06:24:36 +13:00
|
|
|
// this may need to change in the future, right now only admins
|
|
|
|
// can have access to builder features, this is hard coded into
|
|
|
|
// our rules
|
|
|
|
if (isAdmin && isAuthed) {
|
|
|
|
return next()
|
|
|
|
} else if (permType === PermissionTypes.BUILDER) {
|
2021-03-10 00:27:12 +13:00
|
|
|
return ctx.throw(403, "Not Authorized")
|
2020-05-28 04:23:01 +12:00
|
|
|
}
|
|
|
|
|
2021-02-10 05:01:02 +13:00
|
|
|
if (
|
|
|
|
hasResource(ctx) &&
|
|
|
|
doesHaveResourcePermission(permissions, permLevel, ctx)
|
|
|
|
) {
|
|
|
|
return next()
|
|
|
|
}
|
2021-02-09 06:52:22 +13:00
|
|
|
|
2021-02-10 06:24:36 +13:00
|
|
|
if (!isAuthed) {
|
|
|
|
ctx.throw(403, "Session not authenticated")
|
|
|
|
}
|
|
|
|
|
2021-02-09 06:52:22 +13:00
|
|
|
if (!doesHaveBasePermission(permType, permLevel, basePermissions)) {
|
2020-11-13 06:06:55 +13:00
|
|
|
ctx.throw(403, "User does not have permission")
|
|
|
|
}
|
2020-05-28 04:23:01 +12:00
|
|
|
|
2020-11-13 06:06:55 +13:00
|
|
|
return next()
|
2020-05-28 04:23:01 +12:00
|
|
|
}
|