Tests failing but starting to progress.
This commit is contained in:
parent
7cc0a9ca33
commit
6148128554
|
@ -1,9 +1,8 @@
|
||||||
const CouchDB = require("../../db")
|
const CouchDB = require("../../db")
|
||||||
|
const { BUILTIN_LEVELS } = require("../../utilities/security/accessLevels")
|
||||||
const {
|
const {
|
||||||
generateAdminPermissions,
|
BUILTIN_PERMISSION_NAMES,
|
||||||
generatePowerUserPermissions,
|
} = require("../../utilities/security/permissions")
|
||||||
BUILTIN_LEVELS,
|
|
||||||
} = require("../../utilities/security/accessLevels")
|
|
||||||
const {
|
const {
|
||||||
generateAccessLevelID,
|
generateAccessLevelID,
|
||||||
getAccessLevelParams,
|
getAccessLevelParams,
|
||||||
|
@ -21,11 +20,11 @@ exports.fetch = async function(ctx) {
|
||||||
const staticAccessLevels = [
|
const staticAccessLevels = [
|
||||||
{
|
{
|
||||||
...BUILTIN_LEVELS.admin,
|
...BUILTIN_LEVELS.admin,
|
||||||
permissions: await generateAdminPermissions(ctx.user.appId),
|
permissions: [BUILTIN_PERMISSION_NAMES.ADMIN],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...BUILTIN_LEVELS.power,
|
...BUILTIN_LEVELS.power,
|
||||||
permissions: await generatePowerUserPermissions(ctx.user.appId),
|
permissions: [BUILTIN_PERMISSION_NAMES.POWER],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -59,22 +58,13 @@ exports.patch = async function(ctx) {
|
||||||
|
|
||||||
if (removedPermissions) {
|
if (removedPermissions) {
|
||||||
level.permissions = level.permissions.filter(
|
level.permissions = level.permissions.filter(
|
||||||
p =>
|
permission => removedPermissions.indexOf(permission) === -1
|
||||||
!removedPermissions.some(
|
|
||||||
rem => rem.name === p.name && rem.itemId === p.itemId
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addedPermissions) {
|
if (addedPermissions) {
|
||||||
level.permissions = [
|
level.permissions = [
|
||||||
...level.permissions.filter(
|
...new Set([...addedPermissions, ...level.permissions]),
|
||||||
p =>
|
|
||||||
!addedPermissions.some(
|
|
||||||
add => add.name === p.name && add.itemId === p.itemId
|
|
||||||
)
|
|
||||||
),
|
|
||||||
...addedPermissions,
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ exports.authenticate = async ctx => {
|
||||||
userId: dbUser._id,
|
userId: dbUser._id,
|
||||||
accessLevelId: dbUser.accessLevelId,
|
accessLevelId: dbUser.accessLevelId,
|
||||||
version: app.version,
|
version: app.version,
|
||||||
|
permissions: dbUser.permissions || [],
|
||||||
}
|
}
|
||||||
// if in cloud add the user api key
|
// if in cloud add the user api key
|
||||||
if (env.CLOUD) {
|
if (env.CLOUD) {
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
exports.fetch = async ctx => {
|
||||||
|
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
const CouchDB = require("../../db")
|
const CouchDB = require("../../db")
|
||||||
const bcrypt = require("../../utilities/bcrypt")
|
const bcrypt = require("../../utilities/bcrypt")
|
||||||
const { generateUserID, getUserParams } = require("../../db/utils")
|
const { generateUserID, getUserParams } = require("../../db/utils")
|
||||||
|
const { BUILTIN_LEVEL_IDS } = require("../../utilities/security/accessLevels")
|
||||||
const {
|
const {
|
||||||
BUILTIN_LEVELS_IDS,
|
BUILTIN_PERMISSION_NAMES,
|
||||||
} = require("../../utilities/security/accessLevels")
|
} = require("../../utilities/security/permissions")
|
||||||
|
|
||||||
exports.fetch = async function(ctx) {
|
exports.fetch = async function(ctx) {
|
||||||
const database = new CouchDB(ctx.user.appId)
|
const database = new CouchDB(ctx.user.appId)
|
||||||
|
@ -17,7 +18,13 @@ exports.fetch = async function(ctx) {
|
||||||
|
|
||||||
exports.create = async function(ctx) {
|
exports.create = async function(ctx) {
|
||||||
const db = new CouchDB(ctx.user.appId)
|
const db = new CouchDB(ctx.user.appId)
|
||||||
const { username, password, name, accessLevelId } = ctx.request.body
|
const {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
name,
|
||||||
|
accessLevelId,
|
||||||
|
permissions,
|
||||||
|
} = ctx.request.body
|
||||||
|
|
||||||
if (!username || !password) {
|
if (!username || !password) {
|
||||||
ctx.throw(400, "Username and Password Required.")
|
ctx.throw(400, "Username and Password Required.")
|
||||||
|
@ -34,6 +41,7 @@ exports.create = async function(ctx) {
|
||||||
name: name || username,
|
name: name || username,
|
||||||
type: "user",
|
type: "user",
|
||||||
accessLevelId,
|
accessLevelId,
|
||||||
|
permissions: permissions || [BUILTIN_PERMISSION_NAMES.POWER],
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -88,7 +96,7 @@ exports.find = async function(ctx) {
|
||||||
|
|
||||||
const checkAccessLevel = async (db, accessLevelId) => {
|
const checkAccessLevel = async (db, accessLevelId) => {
|
||||||
if (!accessLevelId) return
|
if (!accessLevelId) return
|
||||||
if (BUILTIN_LEVELS_IDS.indexOf(accessLevelId) !== -1) {
|
if (BUILTIN_LEVEL_IDS.indexOf(accessLevelId) !== -1) {
|
||||||
return {
|
return {
|
||||||
_id: accessLevelId,
|
_id: accessLevelId,
|
||||||
name: accessLevelId,
|
name: accessLevelId,
|
||||||
|
|
|
@ -22,6 +22,7 @@ const {
|
||||||
templatesRoutes,
|
templatesRoutes,
|
||||||
analyticsRoutes,
|
analyticsRoutes,
|
||||||
webhookRoutes,
|
webhookRoutes,
|
||||||
|
routingRoutes,
|
||||||
} = require("./routes")
|
} = require("./routes")
|
||||||
|
|
||||||
const router = new Router()
|
const router = new Router()
|
||||||
|
@ -121,6 +122,9 @@ router.use(analyticsRoutes.allowedMethods())
|
||||||
router.use(staticRoutes.routes())
|
router.use(staticRoutes.routes())
|
||||||
router.use(staticRoutes.allowedMethods())
|
router.use(staticRoutes.allowedMethods())
|
||||||
|
|
||||||
|
router.use(routingRoutes.routes())
|
||||||
|
router.use(routingRoutes.allowedMethods())
|
||||||
|
|
||||||
router.redirect("/", "/_builder")
|
router.redirect("/", "/_builder")
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router
|
||||||
|
|
|
@ -15,6 +15,7 @@ const deployRoutes = require("./deploy")
|
||||||
const apiKeysRoutes = require("./apikeys")
|
const apiKeysRoutes = require("./apikeys")
|
||||||
const templatesRoutes = require("./templates")
|
const templatesRoutes = require("./templates")
|
||||||
const analyticsRoutes = require("./analytics")
|
const analyticsRoutes = require("./analytics")
|
||||||
|
const routingRoutes = require("./routing")
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
deployRoutes,
|
deployRoutes,
|
||||||
|
@ -34,4 +35,5 @@ module.exports = {
|
||||||
templatesRoutes,
|
templatesRoutes,
|
||||||
analyticsRoutes,
|
analyticsRoutes,
|
||||||
webhookRoutes,
|
webhookRoutes,
|
||||||
|
routingRoutes,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
const Router = require("@koa/router")
|
||||||
|
const authorized = require("../../middleware/authorized")
|
||||||
|
const { BUILDER } = require("../../utilities/security/permissions")
|
||||||
|
const controller = require("../controllers/routing")
|
||||||
|
|
||||||
|
const router = Router()
|
||||||
|
|
||||||
|
router.post("/api/routing", authorized(BUILDER), controller.fetch)
|
||||||
|
|
||||||
|
module.exports = router
|
|
@ -6,11 +6,7 @@ const {
|
||||||
defaultHeaders
|
defaultHeaders
|
||||||
} = require("./couchTestUtils")
|
} = require("./couchTestUtils")
|
||||||
const {
|
const {
|
||||||
generateAdminPermissions,
|
|
||||||
generatePowerUserPermissions,
|
|
||||||
BUILTIN_LEVELS,
|
BUILTIN_LEVELS,
|
||||||
READ_TABLE,
|
|
||||||
WRITE_TABLE,
|
|
||||||
} = require("../../../utilities/security/accessLevels")
|
} = require("../../../utilities/security/accessLevels")
|
||||||
const { BUILTIN_PERMISSION_NAMES } = require("../../../utilities/security/permissions")
|
const { BUILTIN_PERMISSION_NAMES } = require("../../../utilities/security/permissions")
|
||||||
|
|
||||||
|
@ -76,14 +72,14 @@ describe("/accesslevels", () => {
|
||||||
|
|
||||||
const adminLevel = res.body.find(r => r._id === BUILTIN_LEVELS.admin._id)
|
const adminLevel = res.body.find(r => r._id === BUILTIN_LEVELS.admin._id)
|
||||||
expect(adminLevel).toBeDefined()
|
expect(adminLevel).toBeDefined()
|
||||||
expect(adminLevel.permissions).toEqual(await generateAdminPermissions(appId))
|
expect(adminLevel.permissions).toEqual([BUILTIN_PERMISSION_NAMES.ADMIN])
|
||||||
|
|
||||||
const powerUserLevel = res.body.find(r => r._id === BUILTIN_LEVELS.power._id)
|
const powerUserLevel = res.body.find(r => r._id === BUILTIN_LEVELS.power._id)
|
||||||
expect(powerUserLevel).toBeDefined()
|
expect(powerUserLevel).toBeDefined()
|
||||||
expect(powerUserLevel.permissions).toEqual(await generatePowerUserPermissions(appId))
|
expect(powerUserLevel.permissions).toEqual([BUILTIN_PERMISSION_NAMES.POWER])
|
||||||
|
|
||||||
const customLevelFetched = res.body.find(r => r._id === customLevel._id)
|
const customLevelFetched = res.body.find(r => r._id === customLevel._id)
|
||||||
expect(customLevelFetched.permissions).toEqual(customLevel.permissions)
|
expect(customLevelFetched.permissions).toEqual([BUILTIN_PERMISSION_NAMES.READ_ONLY])
|
||||||
})
|
})
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -126,7 +122,7 @@ describe("/accesslevels", () => {
|
||||||
.patch(`/api/accesslevels/${customLevel._id}`)
|
.patch(`/api/accesslevels/${customLevel._id}`)
|
||||||
.send({
|
.send({
|
||||||
_rev: customLevel._rev,
|
_rev: customLevel._rev,
|
||||||
addedPermissions: [ { itemId: table._id, name: WRITE_TABLE } ]
|
addedPermissions: [ BUILTIN_PERMISSION_NAMES.WRITE ]
|
||||||
})
|
})
|
||||||
.set(defaultHeaders(appId))
|
.set(defaultHeaders(appId))
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
|
@ -138,8 +134,8 @@ describe("/accesslevels", () => {
|
||||||
.expect(200)
|
.expect(200)
|
||||||
|
|
||||||
expect(finalRes.body.permissions.length).toBe(2)
|
expect(finalRes.body.permissions.length).toBe(2)
|
||||||
expect(finalRes.body.permissions.some(p => p.name === WRITE_TABLE)).toBe(true)
|
expect(finalRes.body.permissions.indexOf(BUILTIN_PERMISSION_NAMES.WRITE)).not.toBe(-1)
|
||||||
expect(finalRes.body.permissions.some(p => p.name === READ_TABLE)).toBe(true)
|
expect(finalRes.body.permissions.indexOf(BUILTIN_PERMISSION_NAMES.READ_ONLY)).not.toBe(-1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should remove given permissions", async () => {
|
it("should remove given permissions", async () => {
|
||||||
|
@ -147,9 +143,9 @@ describe("/accesslevels", () => {
|
||||||
.post(`/api/accesslevels`)
|
.post(`/api/accesslevels`)
|
||||||
.send({
|
.send({
|
||||||
name: "user",
|
name: "user",
|
||||||
permissions: [
|
permissions: [
|
||||||
{ itemId: table._id, name: READ_TABLE },
|
BUILTIN_PERMISSION_NAMES.READ_ONLY,
|
||||||
{ itemId: table._id, name: WRITE_TABLE },
|
BUILTIN_PERMISSION_NAMES.WRITE,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.set(defaultHeaders(appId))
|
.set(defaultHeaders(appId))
|
||||||
|
@ -162,7 +158,7 @@ describe("/accesslevels", () => {
|
||||||
.patch(`/api/accesslevels/${customLevel._id}`)
|
.patch(`/api/accesslevels/${customLevel._id}`)
|
||||||
.send({
|
.send({
|
||||||
_rev: customLevel._rev,
|
_rev: customLevel._rev,
|
||||||
removedPermissions: [ { itemId: table._id, name: WRITE_TABLE }]
|
removedPermissions: [BUILTIN_PERMISSION_NAMES.WRITE]
|
||||||
})
|
})
|
||||||
.set(defaultHeaders(appId))
|
.set(defaultHeaders(appId))
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
|
@ -174,7 +170,7 @@ describe("/accesslevels", () => {
|
||||||
.expect(200)
|
.expect(200)
|
||||||
|
|
||||||
expect(finalRes.body.permissions.length).toBe(1)
|
expect(finalRes.body.permissions.length).toBe(1)
|
||||||
expect(finalRes.body.permissions.some(p => p.name === READ_TABLE)).toBe(true)
|
expect(finalRes.body.permissions.indexOf(BUILTIN_PERMISSION_NAMES.READ_ONLY)).not.toBe(-1)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
const CouchDB = require("../../../db")
|
const CouchDB = require("../../../db")
|
||||||
const supertest = require("supertest")
|
const supertest = require("supertest")
|
||||||
const {
|
const {
|
||||||
POWERUSER_LEVEL_ID,
|
BUILTIN_LEVELS,
|
||||||
ANON_LEVEL_ID,
|
|
||||||
BUILDER_LEVEL_ID,
|
|
||||||
generateAdminPermissions,
|
|
||||||
} = require("../../../utilities/security/accessLevels")
|
} = require("../../../utilities/security/accessLevels")
|
||||||
|
const {
|
||||||
|
BUILTIN_PERMISSION_NAMES,
|
||||||
|
} = require("../../../utilities/security/permissions")
|
||||||
const packageJson = require("../../../../package")
|
const packageJson = require("../../../../package")
|
||||||
const jwt = require("jsonwebtoken")
|
const jwt = require("jsonwebtoken")
|
||||||
const env = require("../../../environment")
|
const env = require("../../../environment")
|
||||||
|
@ -26,7 +26,7 @@ exports.supertest = async () => {
|
||||||
exports.defaultHeaders = appId => {
|
exports.defaultHeaders = appId => {
|
||||||
const builderUser = {
|
const builderUser = {
|
||||||
userId: "BUILDER",
|
userId: "BUILDER",
|
||||||
accessLevelId: BUILDER_LEVEL_ID,
|
accessLevelId: BUILTIN_LEVELS.builder._id,
|
||||||
}
|
}
|
||||||
|
|
||||||
const builderToken = jwt.sign(builderUser, env.JWT_SECRET)
|
const builderToken = jwt.sign(builderUser, env.JWT_SECRET)
|
||||||
|
@ -126,21 +126,13 @@ exports.createUser = async (
|
||||||
name: "Bill",
|
name: "Bill",
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
accessLevelId: POWERUSER_LEVEL_ID,
|
accessLevelId: BUILTIN_LEVELS.power._id,
|
||||||
})
|
})
|
||||||
return res.body
|
return res.body
|
||||||
}
|
}
|
||||||
|
|
||||||
const createUserWithOnePermission = async (
|
const createUserWithOnePermission = async (request, appId, permName) => {
|
||||||
request,
|
let permissions = [permName]
|
||||||
appId,
|
|
||||||
permName,
|
|
||||||
itemId
|
|
||||||
) => {
|
|
||||||
let permissions = await generateAdminPermissions(appId)
|
|
||||||
permissions = permissions.filter(
|
|
||||||
p => p.name === permName && p.itemId === itemId
|
|
||||||
)
|
|
||||||
|
|
||||||
return await createUserWithPermissions(
|
return await createUserWithPermissions(
|
||||||
request,
|
request,
|
||||||
|
@ -151,7 +143,7 @@ const createUserWithOnePermission = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
const createUserWithAdminPermissions = async (request, appId) => {
|
const createUserWithAdminPermissions = async (request, appId) => {
|
||||||
let permissions = await generateAdminPermissions(appId)
|
let permissions = [BUILTIN_PERMISSION_NAMES.ADMIN]
|
||||||
|
|
||||||
return await createUserWithPermissions(
|
return await createUserWithPermissions(
|
||||||
request,
|
request,
|
||||||
|
@ -164,13 +156,9 @@ const createUserWithAdminPermissions = async (request, appId) => {
|
||||||
const createUserWithAllPermissionExceptOne = async (
|
const createUserWithAllPermissionExceptOne = async (
|
||||||
request,
|
request,
|
||||||
appId,
|
appId,
|
||||||
permName,
|
permName
|
||||||
itemId
|
|
||||||
) => {
|
) => {
|
||||||
let permissions = await generateAdminPermissions(appId)
|
let permissions = [permName]
|
||||||
permissions = permissions.filter(
|
|
||||||
p => !(p.name === permName && p.itemId === itemId)
|
|
||||||
)
|
|
||||||
|
|
||||||
return await createUserWithPermissions(
|
return await createUserWithPermissions(
|
||||||
request,
|
request,
|
||||||
|
@ -186,11 +174,6 @@ const createUserWithPermissions = async (
|
||||||
permissions,
|
permissions,
|
||||||
username
|
username
|
||||||
) => {
|
) => {
|
||||||
const accessRes = await request
|
|
||||||
.post(`/api/accesslevels`)
|
|
||||||
.send({ name: "TestLevel", permissions })
|
|
||||||
.set(exports.defaultHeaders(appId))
|
|
||||||
|
|
||||||
const password = `password_${username}`
|
const password = `password_${username}`
|
||||||
await request
|
await request
|
||||||
.post(`/api/users`)
|
.post(`/api/users`)
|
||||||
|
@ -199,12 +182,13 @@ const createUserWithPermissions = async (
|
||||||
name: username,
|
name: username,
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
accessLevelId: accessRes.body._id,
|
accessLevelId: BUILTIN_LEVELS.power._id,
|
||||||
|
permissions,
|
||||||
})
|
})
|
||||||
|
|
||||||
const anonUser = {
|
const anonUser = {
|
||||||
userId: "ANON",
|
userId: "ANON",
|
||||||
accessLevelId: ANON_LEVEL_ID,
|
accessLevelId: BUILTIN_LEVELS.anon._id,
|
||||||
appId: appId,
|
appId: appId,
|
||||||
version: packageJson.version,
|
version: packageJson.version,
|
||||||
}
|
}
|
||||||
|
@ -233,13 +217,11 @@ exports.testPermissionsForEndpoint = async ({
|
||||||
body,
|
body,
|
||||||
appId,
|
appId,
|
||||||
permissionName,
|
permissionName,
|
||||||
itemId,
|
|
||||||
}) => {
|
}) => {
|
||||||
const headers = await createUserWithOnePermission(
|
const headers = await createUserWithOnePermission(
|
||||||
request,
|
request,
|
||||||
appId,
|
appId,
|
||||||
permissionName,
|
permissionName
|
||||||
itemId
|
|
||||||
)
|
)
|
||||||
|
|
||||||
await createRequest(request, method, url, body)
|
await createRequest(request, method, url, body)
|
||||||
|
@ -249,8 +231,7 @@ exports.testPermissionsForEndpoint = async ({
|
||||||
const noPermsHeaders = await createUserWithAllPermissionExceptOne(
|
const noPermsHeaders = await createUserWithAllPermissionExceptOne(
|
||||||
request,
|
request,
|
||||||
appId,
|
appId,
|
||||||
permissionName,
|
permissionName
|
||||||
itemId
|
|
||||||
)
|
)
|
||||||
|
|
||||||
await createRequest(request, method, url, body)
|
await createRequest(request, method, url, body)
|
||||||
|
|
|
@ -5,10 +5,11 @@ const {
|
||||||
createUser,
|
createUser,
|
||||||
testPermissionsForEndpoint,
|
testPermissionsForEndpoint,
|
||||||
} = require("./couchTestUtils")
|
} = require("./couchTestUtils")
|
||||||
const {
|
const {
|
||||||
POWERUSER_LEVEL_ID,
|
BUILTIN_PERMISSION_NAMES,
|
||||||
LIST_USERS,
|
} = require("../../../utilities/security/permissions")
|
||||||
USER_MANAGEMENT
|
const {
|
||||||
|
BUILTIN_LEVELS
|
||||||
} = require("../../../utilities/security/accessLevels")
|
} = require("../../../utilities/security/accessLevels")
|
||||||
|
|
||||||
describe("/users", () => {
|
describe("/users", () => {
|
||||||
|
@ -53,7 +54,7 @@ describe("/users", () => {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
url: `/api/users`,
|
url: `/api/users`,
|
||||||
appId: appId,
|
appId: appId,
|
||||||
permissionName: LIST_USERS,
|
permissionName: BUILTIN_PERMISSION_NAMES.WRITE,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -65,7 +66,7 @@ describe("/users", () => {
|
||||||
const res = await request
|
const res = await request
|
||||||
.post(`/api/users`)
|
.post(`/api/users`)
|
||||||
.set(defaultHeaders(appId))
|
.set(defaultHeaders(appId))
|
||||||
.send({ name: "Bill", username: "bill", password: "bills_password", accessLevelId: POWERUSER_LEVEL_ID })
|
.send({ name: "Bill", username: "bill", password: "bills_password", accessLevelId: BUILTIN_LEVELS.power._id })
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
|
|
||||||
|
@ -77,10 +78,10 @@ describe("/users", () => {
|
||||||
await testPermissionsForEndpoint({
|
await testPermissionsForEndpoint({
|
||||||
request,
|
request,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: { name: "brandNewUser", username: "brandNewUser", password: "yeeooo", accessLevelId: POWERUSER_LEVEL_ID },
|
body: { name: "brandNewUser", username: "brandNewUser", password: "yeeooo", accessLevelId: BUILTIN_LEVELS.power._id },
|
||||||
url: `/api/users`,
|
url: `/api/users`,
|
||||||
appId: appId,
|
appId: appId,
|
||||||
permissionName: USER_MANAGEMENT,
|
permissionName: BUILTIN_PERMISSION_NAMES.WRITE,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ module.exports.definition = {
|
||||||
type: "ACTION",
|
type: "ACTION",
|
||||||
stepId: "CREATE_USER",
|
stepId: "CREATE_USER",
|
||||||
inputs: {
|
inputs: {
|
||||||
accessLevelId: accessLevels.POWERUSER_LEVEL_ID,
|
accessLevelId: accessLevels.BUILTIN_LEVELS.power._id,
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
inputs: {
|
inputs: {
|
||||||
|
@ -29,7 +29,7 @@ module.exports.definition = {
|
||||||
type: "string",
|
type: "string",
|
||||||
title: "Access Level",
|
title: "Access Level",
|
||||||
enum: accessLevels.BUILTIN_LEVELS,
|
enum: accessLevels.BUILTIN_LEVELS,
|
||||||
pretty: Object.values(accessLevels.PRETTY_ACCESS_LEVELS),
|
pretty: accessLevels.BUILTIN_LEVEL_NAMES,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
required: ["username", "password", "accessLevelId"],
|
required: ["username", "password", "accessLevelId"],
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
const { BUILTIN_LEVELS } = require("../utilities/security/accessLevels")
|
const { BUILTIN_LEVELS } = require("../utilities/security/accessLevels")
|
||||||
const { PermissionTypes } = require("../utilities/security/permissions")
|
const {
|
||||||
|
PermissionTypes,
|
||||||
|
doesHavePermission,
|
||||||
|
} = require("../utilities/security/permissions")
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
const { apiKeyTable } = require("../db/dynamoClient")
|
const { apiKeyTable } = require("../db/dynamoClient")
|
||||||
const { AuthTypes } = require("../constants")
|
const { AuthTypes } = require("../constants")
|
||||||
|
@ -44,18 +47,21 @@ module.exports = (permType, permLevel = null) => async (ctx, next) => {
|
||||||
ctx.throw(403, "User not found")
|
ctx.throw(403, "User not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ADMIN_PERMS.indexOf(ctx.user.accessLevel._id) !== -1) {
|
const accessLevel = ctx.user.accessLevel
|
||||||
|
const permissions = ctx.user.permissions
|
||||||
|
if (ADMIN_PERMS.indexOf(accessLevel._id) !== -1) {
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: need to handle routing security
|
||||||
|
|
||||||
if (permType === PermissionTypes.BUILDER) {
|
if (permType === PermissionTypes.BUILDER) {
|
||||||
ctx.throw(403, "Not Authorized")
|
ctx.throw(403, "Not Authorized")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Replace the old permissions system here, check whether
|
if (!doesHavePermission(permType, permLevel, permissions)) {
|
||||||
// user has permission to use endpoint they are trying to access
|
ctx.throw(403, "User does not have permission")
|
||||||
return next()
|
}
|
||||||
|
|
||||||
//ctx.throw(403, "Not Authorized")
|
return next()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const { BUILDER_LEVEL_ID } = require("../security/accessLevels")
|
const { BUILTIN_LEVELS } = require("../security/accessLevels")
|
||||||
|
const { BUILTIN_PERMISSION_NAMES } = require("../security/permissions")
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const CouchDB = require("../../db")
|
const CouchDB = require("../../db")
|
||||||
const jwt = require("jsonwebtoken")
|
const jwt = require("jsonwebtoken")
|
||||||
|
@ -9,7 +10,8 @@ const APP_PREFIX = DocumentTypes.APP + SEPARATOR
|
||||||
module.exports = async (ctx, appId, version) => {
|
module.exports = async (ctx, appId, version) => {
|
||||||
const builderUser = {
|
const builderUser = {
|
||||||
userId: "BUILDER",
|
userId: "BUILDER",
|
||||||
accessLevelId: BUILDER_LEVEL_ID,
|
accessLevelId: BUILTIN_LEVELS.builder._id,
|
||||||
|
permissions: [BUILTIN_PERMISSION_NAMES.ADMIN],
|
||||||
version,
|
version,
|
||||||
}
|
}
|
||||||
if (env.BUDIBASE_API_KEY) {
|
if (env.BUDIBASE_API_KEY) {
|
||||||
|
|
|
@ -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("./security/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
|
|
|
@ -1,44 +1,14 @@
|
||||||
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 = {
|
exports.BUILTIN_LEVELS = {
|
||||||
admin: { _id: makeAccessLevelId("ADMIN"), name: "Admin" },
|
admin: { _id: "ADMIN", name: "Admin" },
|
||||||
power: { _id: makeAccessLevelId("POWER_USER"), name: "Power user" },
|
power: { _id: "POWER_USER", name: "Power user" },
|
||||||
builder: { _id: makeAccessLevelId("BUILDER"), name: "Builder" },
|
builder: { _id: "BUILDER", name: "Builder" },
|
||||||
anon: { _id: makeAccessLevelId("ANON"), name: "Anonymous" },
|
anon: { _id: "ANON", name: "Anonymous" },
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.BUILTIN_LEVEL_IDS = Object.values(exports.BUILTIN_LEVELS).map(
|
exports.BUILTIN_LEVEL_IDS = Object.values(exports.BUILTIN_LEVELS).map(
|
||||||
level => level._id
|
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
|
exports.BUILTIN_LEVEL_NAMES = Object.values(exports.BUILTIN_LEVELS).map(
|
||||||
const permissions = require("../permissions")
|
level => level.name
|
||||||
exports.generateAdminPermissions = permissions.generateAdminPermissions
|
)
|
||||||
exports.generatePowerUserPermissions = permissions.generatePowerUserPermissions
|
|
||||||
|
|
|
@ -1,14 +1,5 @@
|
||||||
const { flatten } = require("lodash")
|
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 = {
|
const PermissionLevels = {
|
||||||
READ: "read",
|
READ: "read",
|
||||||
WRITE: "write",
|
WRITE: "write",
|
||||||
|
@ -54,10 +45,11 @@ function getAllowedLevels(userPermLevel) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: need to expand on this
|
|
||||||
exports.BUILTIN_PERMISSION_NAMES = {
|
exports.BUILTIN_PERMISSION_NAMES = {
|
||||||
READ_ONLY: "read_only",
|
READ_ONLY: "read_only",
|
||||||
WRITE: "write",
|
WRITE: "write",
|
||||||
|
ADMIN: "admin",
|
||||||
|
POWER: "power",
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.BUILTIN_PERMISSIONS = {
|
exports.BUILTIN_PERMISSIONS = {
|
||||||
|
@ -75,6 +67,26 @@ exports.BUILTIN_PERMISSIONS = {
|
||||||
new Permission(PermissionTypes.VIEW, PermissionLevels.READ),
|
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) => {
|
exports.doesHavePermission = (permType, permLevel, userPermissionNames) => {
|
||||||
|
|
Loading…
Reference in New Issue