WIP - this is working towards the permissions system but stopping here for the night, this is currently not functional.
This commit is contained in:
parent
5b26fce1ea
commit
1f4e27eb13
|
@ -2,9 +2,8 @@ const CouchDB = require("../../db")
|
||||||
const {
|
const {
|
||||||
generateAdminPermissions,
|
generateAdminPermissions,
|
||||||
generatePowerUserPermissions,
|
generatePowerUserPermissions,
|
||||||
POWERUSER_LEVEL_ID,
|
BUILTIN_LEVELS,
|
||||||
ADMIN_LEVEL_ID,
|
} = require("../../utilities/security/accessLevels")
|
||||||
} = require("../../utilities/accessLevels")
|
|
||||||
const {
|
const {
|
||||||
generateAccessLevelID,
|
generateAccessLevelID,
|
||||||
getAccessLevelParams,
|
getAccessLevelParams,
|
||||||
|
@ -21,13 +20,11 @@ exports.fetch = async function(ctx) {
|
||||||
|
|
||||||
const staticAccessLevels = [
|
const staticAccessLevels = [
|
||||||
{
|
{
|
||||||
_id: ADMIN_LEVEL_ID,
|
...BUILTIN_LEVELS.admin,
|
||||||
name: "Admin",
|
|
||||||
permissions: await generateAdminPermissions(ctx.user.appId),
|
permissions: await generateAdminPermissions(ctx.user.appId),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_id: POWERUSER_LEVEL_ID,
|
...BUILTIN_LEVELS.power,
|
||||||
name: "Power User",
|
|
||||||
permissions: await generatePowerUserPermissions(ctx.user.appId),
|
permissions: await generatePowerUserPermissions(ctx.user.appId),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -2,9 +2,8 @@ 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 {
|
const {
|
||||||
POWERUSER_LEVEL_ID,
|
BUILTIN_LEVELS_IDS,
|
||||||
ADMIN_LEVEL_ID,
|
} = require("../../utilities/security/accessLevels")
|
||||||
} = require("../../utilities/accessLevels")
|
|
||||||
|
|
||||||
exports.fetch = async function(ctx) {
|
exports.fetch = async function(ctx) {
|
||||||
const database = new CouchDB(ctx.user.appId)
|
const database = new CouchDB(ctx.user.appId)
|
||||||
|
@ -89,10 +88,7 @@ exports.find = async function(ctx) {
|
||||||
|
|
||||||
const checkAccessLevel = async (db, accessLevelId) => {
|
const checkAccessLevel = async (db, accessLevelId) => {
|
||||||
if (!accessLevelId) return
|
if (!accessLevelId) return
|
||||||
if (
|
if (BUILTIN_LEVELS_IDS.indexOf(accessLevelId) !== -1) {
|
||||||
accessLevelId === POWERUSER_LEVEL_ID ||
|
|
||||||
accessLevelId === ADMIN_LEVEL_ID
|
|
||||||
) {
|
|
||||||
return {
|
return {
|
||||||
_id: accessLevelId,
|
_id: accessLevelId,
|
||||||
name: accessLevelId,
|
name: accessLevelId,
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const controller = require("../controllers/accesslevel")
|
const controller = require("../controllers/accesslevel")
|
||||||
|
const authorized = require("../../middleware/authorized")
|
||||||
|
const { BUILDER } = require("../../utilities/security/permissions")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
router
|
router
|
||||||
.post("/api/accesslevels", controller.create)
|
.post("/api/accesslevels", authorized(BUILDER), controller.create)
|
||||||
.put("/api/accesslevels", controller.update)
|
.put("/api/accesslevels", authorized(BUILDER), controller.update)
|
||||||
.get("/api/accesslevels", controller.fetch)
|
.get("/api/accesslevels", authorized(BUILDER), controller.fetch)
|
||||||
.get("/api/accesslevels/:levelId", controller.find)
|
.get("/api/accesslevels/:levelId", authorized(BUILDER), controller.find)
|
||||||
.delete("/api/accesslevels/:levelId/:rev", controller.destroy)
|
.delete(
|
||||||
.patch("/api/accesslevels/:levelId", controller.patch)
|
"/api/accesslevels/:levelId/:rev",
|
||||||
|
authorized(BUILDER),
|
||||||
|
controller.destroy
|
||||||
|
)
|
||||||
|
.patch("/api/accesslevels/:levelId", authorized(BUILDER), controller.patch)
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const { BUILDER } = require("../../utilities/accessLevels")
|
|
||||||
const controller = require("../controllers/analytics")
|
const controller = require("../controllers/analytics")
|
||||||
|
const { BUILDER } = require("../../utilities/security/permissions")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const controller = require("../controllers/apikeys")
|
const controller = require("../controllers/apikeys")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const { BUILDER } = require("../../utilities/accessLevels")
|
const { BUILDER } = require("../../utilities/security/permissions")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const controller = require("../controllers/application")
|
const controller = require("../controllers/application")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const { BUILDER } = require("../../utilities/accessLevels")
|
const { BUILDER } = require("../../utilities/security/permissions")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,11 @@ const Router = require("@koa/router")
|
||||||
const controller = require("../controllers/automation")
|
const controller = require("../controllers/automation")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const joiValidator = require("../../middleware/joi-validator")
|
const joiValidator = require("../../middleware/joi-validator")
|
||||||
const { BUILDER, EXECUTE_AUTOMATION } = require("../../utilities/accessLevels")
|
const {
|
||||||
|
BUILDER,
|
||||||
|
PermissionLevels,
|
||||||
|
PermissionTypes,
|
||||||
|
} = require("../../utilities/security/permissions")
|
||||||
const Joi = require("joi")
|
const Joi = require("joi")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
@ -75,7 +79,7 @@ router
|
||||||
)
|
)
|
||||||
.post(
|
.post(
|
||||||
"/api/automations/:id/trigger",
|
"/api/automations/:id/trigger",
|
||||||
authorized(EXECUTE_AUTOMATION),
|
authorized(PermissionTypes.AUTOMATION, PermissionLevels.EXECUTE),
|
||||||
controller.trigger
|
controller.trigger
|
||||||
)
|
)
|
||||||
.delete("/api/automations/:id/:rev", authorized(BUILDER), controller.destroy)
|
.delete("/api/automations/:id/:rev", authorized(BUILDER), controller.destroy)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const controller = require("../controllers/component")
|
const controller = require("../controllers/component")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const { BUILDER } = require("../../utilities/accessLevels")
|
const { BUILDER } = require("../../utilities/security/permissions")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const controller = require("../controllers/deploy")
|
const controller = require("../controllers/deploy")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const { BUILDER } = require("../../utilities/accessLevels")
|
const { BUILDER } = require("../../utilities/security/permissions")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const { BUILDER } = require("../../utilities/accessLevels")
|
const { BUILDER } = require("../../utilities/security/permissions")
|
||||||
const controller = require("../controllers/page")
|
const controller = require("../controllers/page")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
|
@ -2,46 +2,49 @@ const Router = require("@koa/router")
|
||||||
const rowController = require("../controllers/row")
|
const rowController = require("../controllers/row")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const usage = require("../../middleware/usageQuota")
|
const usage = require("../../middleware/usageQuota")
|
||||||
const { READ_TABLE, WRITE_TABLE } = require("../../utilities/accessLevels")
|
const {
|
||||||
|
PermissionLevels,
|
||||||
|
PermissionTypes,
|
||||||
|
} = require("../../utilities/security/permissions")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
router
|
router
|
||||||
.get(
|
.get(
|
||||||
"/api/:tableId/:rowId/enrich",
|
"/api/:tableId/:rowId/enrich",
|
||||||
authorized(READ_TABLE, ctx => ctx.params.tableId),
|
authorized(PermissionTypes.TABLE, PermissionLevels.READ),
|
||||||
rowController.fetchEnrichedRow
|
rowController.fetchEnrichedRow
|
||||||
)
|
)
|
||||||
.get(
|
.get(
|
||||||
"/api/:tableId/rows",
|
"/api/:tableId/rows",
|
||||||
authorized(READ_TABLE, ctx => ctx.params.tableId),
|
authorized(PermissionTypes.TABLE, PermissionLevels.READ),
|
||||||
rowController.fetchTableRows
|
rowController.fetchTableRows
|
||||||
)
|
)
|
||||||
.get(
|
.get(
|
||||||
"/api/:tableId/rows/:rowId",
|
"/api/:tableId/rows/:rowId",
|
||||||
authorized(READ_TABLE, ctx => ctx.params.tableId),
|
authorized(PermissionTypes.TABLE, PermissionLevels.READ),
|
||||||
rowController.find
|
rowController.find
|
||||||
)
|
)
|
||||||
.post("/api/rows/search", rowController.search)
|
.post("/api/rows/search", rowController.search)
|
||||||
.post(
|
.post(
|
||||||
"/api/:tableId/rows",
|
"/api/:tableId/rows",
|
||||||
authorized(WRITE_TABLE, ctx => ctx.params.tableId),
|
authorized(PermissionTypes.TABLE, PermissionLevels.WRITE),
|
||||||
usage,
|
usage,
|
||||||
rowController.save
|
rowController.save
|
||||||
)
|
)
|
||||||
.patch(
|
.patch(
|
||||||
"/api/:tableId/rows/:id",
|
"/api/:tableId/rows/:id",
|
||||||
authorized(WRITE_TABLE, ctx => ctx.params.tableId),
|
authorized(PermissionTypes.TABLE, PermissionLevels.WRITE),
|
||||||
rowController.patch
|
rowController.patch
|
||||||
)
|
)
|
||||||
.post(
|
.post(
|
||||||
"/api/:tableId/rows/validate",
|
"/api/:tableId/rows/validate",
|
||||||
authorized(WRITE_TABLE, ctx => ctx.params.tableId),
|
authorized(PermissionTypes.TABLE, PermissionLevels.WRITE),
|
||||||
rowController.validate
|
rowController.validate
|
||||||
)
|
)
|
||||||
.delete(
|
.delete(
|
||||||
"/api/:tableId/rows/:rowId/:revId",
|
"/api/:tableId/rows/:rowId/:revId",
|
||||||
authorized(WRITE_TABLE, ctx => ctx.params.tableId),
|
authorized(PermissionTypes.TABLE, PermissionLevels.WRITE),
|
||||||
usage,
|
usage,
|
||||||
rowController.destroy
|
rowController.destroy
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const controller = require("../controllers/screen")
|
const controller = require("../controllers/screen")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const { BUILDER } = require("../../utilities/accessLevels")
|
const { BUILDER } = require("../../utilities/security/permissions")
|
||||||
const joiValidator = require("../../middleware/joi-validator")
|
const joiValidator = require("../../middleware/joi-validator")
|
||||||
const Joi = require("joi")
|
const Joi = require("joi")
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ const controller = require("../controllers/static")
|
||||||
const { budibaseTempDir } = require("../../utilities/budibaseDir")
|
const { budibaseTempDir } = require("../../utilities/budibaseDir")
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const { BUILDER } = require("../../utilities/accessLevels")
|
const { BUILDER } = require("../../utilities/security/permissions")
|
||||||
const usage = require("../../middleware/usageQuota")
|
const usage = require("../../middleware/usageQuota")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const tableController = require("../controllers/table")
|
const tableController = require("../controllers/table")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const { BUILDER, READ_TABLE } = require("../../utilities/accessLevels")
|
const {
|
||||||
|
BUILDER,
|
||||||
|
PermissionLevels,
|
||||||
|
PermissionTypes,
|
||||||
|
} = require("../../utilities/security/permissions")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
|
@ -9,7 +13,7 @@ router
|
||||||
.get("/api/tables", authorized(BUILDER), tableController.fetch)
|
.get("/api/tables", authorized(BUILDER), tableController.fetch)
|
||||||
.get(
|
.get(
|
||||||
"/api/tables/:id",
|
"/api/tables/:id",
|
||||||
authorized(READ_TABLE, ctx => ctx.params.id),
|
authorized(PermissionTypes.TABLE, PermissionLevels.READ),
|
||||||
tableController.find
|
tableController.find
|
||||||
)
|
)
|
||||||
.post("/api/tables", authorized(BUILDER), tableController.save)
|
.post("/api/tables", authorized(BUILDER), tableController.save)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const controller = require("../controllers/templates")
|
const controller = require("../controllers/templates")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const { BUILDER } = require("../../utilities/accessLevels")
|
const { BUILDER } = require("../../utilities/security/permissions")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,11 @@ const {
|
||||||
const {
|
const {
|
||||||
generateAdminPermissions,
|
generateAdminPermissions,
|
||||||
generatePowerUserPermissions,
|
generatePowerUserPermissions,
|
||||||
POWERUSER_LEVEL_ID,
|
BUILTIN_LEVELS,
|
||||||
ADMIN_LEVEL_ID,
|
|
||||||
READ_TABLE,
|
READ_TABLE,
|
||||||
WRITE_TABLE,
|
WRITE_TABLE,
|
||||||
} = require("../../../utilities/accessLevels")
|
} = require("../../../utilities/security/accessLevels")
|
||||||
|
const { BUILTIN_PERMISSION_NAMES } = require("../../../utilities/security/permissions")
|
||||||
|
|
||||||
describe("/accesslevels", () => {
|
describe("/accesslevels", () => {
|
||||||
let server
|
let server
|
||||||
|
@ -59,7 +59,7 @@ describe("/accesslevels", () => {
|
||||||
it("should list custom levels, plus 2 default levels", async () => {
|
it("should list custom levels, plus 2 default levels", async () => {
|
||||||
const createRes = await request
|
const createRes = await request
|
||||||
.post(`/api/accesslevels`)
|
.post(`/api/accesslevels`)
|
||||||
.send({ name: "user", permissions: [ { itemId: table._id, name: READ_TABLE }] })
|
.send({ name: "user", permissions: [BUILTIN_PERMISSION_NAMES.READ_ONLY] })
|
||||||
.set(defaultHeaders(appId))
|
.set(defaultHeaders(appId))
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
|
@ -74,11 +74,11 @@ describe("/accesslevels", () => {
|
||||||
|
|
||||||
expect(res.body.length).toBe(3)
|
expect(res.body.length).toBe(3)
|
||||||
|
|
||||||
const adminLevel = res.body.find(r => r._id === ADMIN_LEVEL_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(await generateAdminPermissions(appId))
|
||||||
|
|
||||||
const powerUserLevel = res.body.find(r => r._id === POWERUSER_LEVEL_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(await generatePowerUserPermissions(appId))
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ describe("/accesslevels", () => {
|
||||||
it("should delete custom access level", async () => {
|
it("should delete custom access level", async () => {
|
||||||
const createRes = await request
|
const createRes = await request
|
||||||
.post(`/api/accesslevels`)
|
.post(`/api/accesslevels`)
|
||||||
.send({ name: "user", permissions: [ { itemId: table._id, name: READ_TABLE } ] })
|
.send({ name: "user", permissions: [BUILTIN_PERMISSION_NAMES.READ_ONLY] })
|
||||||
.set(defaultHeaders(appId))
|
.set(defaultHeaders(appId))
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
|
@ -115,7 +115,7 @@ describe("/accesslevels", () => {
|
||||||
it("should add given permissions", async () => {
|
it("should add given permissions", async () => {
|
||||||
const createRes = await request
|
const createRes = await request
|
||||||
.post(`/api/accesslevels`)
|
.post(`/api/accesslevels`)
|
||||||
.send({ name: "user", permissions: [ { itemId: table._id, name: READ_TABLE }] })
|
.send({ name: "user", permissions: [BUILTIN_PERMISSION_NAMES.READ_ONLY] })
|
||||||
.set(defaultHeaders(appId))
|
.set(defaultHeaders(appId))
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
|
|
|
@ -5,7 +5,7 @@ const {
|
||||||
ANON_LEVEL_ID,
|
ANON_LEVEL_ID,
|
||||||
BUILDER_LEVEL_ID,
|
BUILDER_LEVEL_ID,
|
||||||
generateAdminPermissions,
|
generateAdminPermissions,
|
||||||
} = require("../../../utilities/accessLevels")
|
} = require("../../../utilities/security/accessLevels")
|
||||||
const packageJson = require("../../../../package")
|
const packageJson = require("../../../../package")
|
||||||
const jwt = require("jsonwebtoken")
|
const jwt = require("jsonwebtoken")
|
||||||
const env = require("../../../environment")
|
const env = require("../../../environment")
|
||||||
|
|
|
@ -9,7 +9,7 @@ const {
|
||||||
POWERUSER_LEVEL_ID,
|
POWERUSER_LEVEL_ID,
|
||||||
LIST_USERS,
|
LIST_USERS,
|
||||||
USER_MANAGEMENT
|
USER_MANAGEMENT
|
||||||
} = require("../../../utilities/accessLevels")
|
} = require("../../../utilities/security/accessLevels")
|
||||||
|
|
||||||
describe("/users", () => {
|
describe("/users", () => {
|
||||||
let request
|
let request
|
||||||
|
|
|
@ -1,19 +1,39 @@
|
||||||
const Router = require("@koa/router")
|
const Router = require("@koa/router")
|
||||||
const controller = require("../controllers/user")
|
const controller = require("../controllers/user")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const { USER_MANAGEMENT, LIST_USERS } = require("../../utilities/accessLevels")
|
const {
|
||||||
|
PermissionLevels,
|
||||||
|
PermissionTypes,
|
||||||
|
} = require("../../utilities/security/permissions")
|
||||||
const usage = require("../../middleware/usageQuota")
|
const usage = require("../../middleware/usageQuota")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
router
|
router
|
||||||
.get("/api/users", authorized(LIST_USERS), controller.fetch)
|
.get(
|
||||||
.get("/api/users/:username", authorized(USER_MANAGEMENT), controller.find)
|
"/api/users",
|
||||||
.put("/api/users/", authorized(USER_MANAGEMENT), controller.update)
|
authorized(PermissionTypes.USER, PermissionLevels.READ),
|
||||||
.post("/api/users", authorized(USER_MANAGEMENT), usage, controller.create)
|
controller.fetch
|
||||||
|
)
|
||||||
|
.get(
|
||||||
|
"/api/users/:username",
|
||||||
|
authorized(PermissionTypes.USER, PermissionLevels.READ),
|
||||||
|
controller.find
|
||||||
|
)
|
||||||
|
.put(
|
||||||
|
"/api/users/",
|
||||||
|
authorized(PermissionTypes.USER, PermissionLevels.WRITE),
|
||||||
|
controller.update
|
||||||
|
)
|
||||||
|
.post(
|
||||||
|
"/api/users",
|
||||||
|
authorized(PermissionTypes.USER, PermissionLevels.WRITE),
|
||||||
|
usage,
|
||||||
|
controller.create
|
||||||
|
)
|
||||||
.delete(
|
.delete(
|
||||||
"/api/users/:username",
|
"/api/users/:username",
|
||||||
authorized(USER_MANAGEMENT),
|
authorized(PermissionTypes.USER, PermissionLevels.WRITE),
|
||||||
usage,
|
usage,
|
||||||
controller.destroy
|
controller.destroy
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,7 +2,11 @@ const Router = require("@koa/router")
|
||||||
const viewController = require("../controllers/view")
|
const viewController = require("../controllers/view")
|
||||||
const rowController = require("../controllers/row")
|
const rowController = require("../controllers/row")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const { BUILDER, READ_VIEW } = require("../../utilities/accessLevels")
|
const {
|
||||||
|
BUILDER,
|
||||||
|
PermissionTypes,
|
||||||
|
PermissionLevels,
|
||||||
|
} = require("../../utilities/security/permissions")
|
||||||
const usage = require("../../middleware/usageQuota")
|
const usage = require("../../middleware/usageQuota")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
@ -10,7 +14,7 @@ const router = Router()
|
||||||
router
|
router
|
||||||
.get(
|
.get(
|
||||||
"/api/views/:viewName",
|
"/api/views/:viewName",
|
||||||
authorized(READ_VIEW, ctx => ctx.params.viewName),
|
authorized(PermissionTypes.VIEW, PermissionLevels.READ),
|
||||||
rowController.fetchView
|
rowController.fetchView
|
||||||
)
|
)
|
||||||
.get("/api/views", authorized(BUILDER), viewController.fetch)
|
.get("/api/views", authorized(BUILDER), viewController.fetch)
|
||||||
|
|
|
@ -2,7 +2,11 @@ const Router = require("@koa/router")
|
||||||
const controller = require("../controllers/webhook")
|
const controller = require("../controllers/webhook")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
const joiValidator = require("../../middleware/joi-validator")
|
const joiValidator = require("../../middleware/joi-validator")
|
||||||
const { BUILDER, EXECUTE_WEBHOOK } = require("../../utilities/accessLevels")
|
const {
|
||||||
|
BUILDER,
|
||||||
|
PermissionTypes,
|
||||||
|
PermissionLevels,
|
||||||
|
} = require("../../utilities/security/permissions")
|
||||||
const Joi = require("joi")
|
const Joi = require("joi")
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
@ -38,7 +42,7 @@ router
|
||||||
)
|
)
|
||||||
.post(
|
.post(
|
||||||
"/api/webhooks/trigger/:instance/:id",
|
"/api/webhooks/trigger/:instance/:id",
|
||||||
authorized(EXECUTE_WEBHOOK),
|
authorized(PermissionTypes.WEBHOOK, PermissionLevels.EXECUTE),
|
||||||
controller.trigger
|
controller.trigger
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const accessLevels = require("../../utilities/accessLevels")
|
const accessLevels = require("../../utilities/security/accessLevels")
|
||||||
const userController = require("../../api/controllers/user")
|
const userController = require("../../api/controllers/user")
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const usage = require("../../utilities/usageQuota")
|
const usage = require("../../utilities/usageQuota")
|
||||||
|
@ -28,7 +28,7 @@ module.exports.definition = {
|
||||||
accessLevelId: {
|
accessLevelId: {
|
||||||
type: "string",
|
type: "string",
|
||||||
title: "Access Level",
|
title: "Access Level",
|
||||||
enum: accessLevels.ACCESS_LEVELS,
|
enum: accessLevels.BUILTIN_LEVELS,
|
||||||
pretty: Object.values(accessLevels.PRETTY_ACCESS_LEVELS),
|
pretty: Object.values(accessLevels.PRETTY_ACCESS_LEVELS),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,11 +2,8 @@ const jwt = require("jsonwebtoken")
|
||||||
const STATUS_CODES = require("../utilities/statusCodes")
|
const STATUS_CODES = require("../utilities/statusCodes")
|
||||||
const accessLevelController = require("../api/controllers/accesslevel")
|
const accessLevelController = require("../api/controllers/accesslevel")
|
||||||
const {
|
const {
|
||||||
ADMIN_LEVEL_ID,
|
BUILTIN_LEVEL_IDS,
|
||||||
POWERUSER_LEVEL_ID,
|
} = require("../utilities/security/accessLevels")
|
||||||
BUILDER_LEVEL_ID,
|
|
||||||
ANON_LEVEL_ID,
|
|
||||||
} = require("../utilities/accessLevels")
|
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
const { AuthTypes } = require("../constants")
|
const { AuthTypes } = require("../constants")
|
||||||
const { getAppId, getCookieName, setCookie } = require("../utilities")
|
const { getAppId, getCookieName, setCookie } = require("../utilities")
|
||||||
|
@ -74,12 +71,7 @@ module.exports = async (ctx, next) => {
|
||||||
* @param {*} accessLevelId - the id of the users access level
|
* @param {*} accessLevelId - the id of the users access level
|
||||||
*/
|
*/
|
||||||
const getAccessLevel = async (appId, accessLevelId) => {
|
const getAccessLevel = async (appId, accessLevelId) => {
|
||||||
if (
|
if (BUILTIN_LEVEL_IDS.indexOf(accessLevelId) !== -1) {
|
||||||
accessLevelId === POWERUSER_LEVEL_ID ||
|
|
||||||
accessLevelId === ADMIN_LEVEL_ID ||
|
|
||||||
accessLevelId === BUILDER_LEVEL_ID ||
|
|
||||||
accessLevelId === ANON_LEVEL_ID
|
|
||||||
) {
|
|
||||||
return {
|
return {
|
||||||
_id: accessLevelId,
|
_id: accessLevelId,
|
||||||
name: accessLevelId,
|
name: accessLevelId,
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
const {
|
const { BUILTIN_LEVELS } = require("../utilities/security/accessLevels")
|
||||||
adminPermissions,
|
const { PermissionTypes } = require("../utilities/security/permissions")
|
||||||
ADMIN_LEVEL_ID,
|
|
||||||
POWERUSER_LEVEL_ID,
|
|
||||||
BUILDER_LEVEL_ID,
|
|
||||||
BUILDER,
|
|
||||||
} = require("../utilities/accessLevels")
|
|
||||||
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")
|
||||||
|
|
||||||
|
const ADMIN_PERMS = [BUILTIN_LEVELS.admin._id, BUILTIN_LEVELS.builder._id]
|
||||||
|
|
||||||
const LOCAL_PASS = new RegExp(["webhooks/trigger", "webhooks/schema"].join("|"))
|
const LOCAL_PASS = new RegExp(["webhooks/trigger", "webhooks/schema"].join("|"))
|
||||||
|
|
||||||
module.exports = (permName, getItemId) => async (ctx, next) => {
|
module.exports = (permType, permLevel = null) => async (ctx, next) => {
|
||||||
// webhooks can pass locally
|
// webhooks can pass locally
|
||||||
if (!env.CLOUD && LOCAL_PASS.test(ctx.request.url)) {
|
if (!env.CLOUD && LOCAL_PASS.test(ctx.request.url)) {
|
||||||
return next()
|
return next()
|
||||||
|
@ -37,7 +34,7 @@ module.exports = (permName, getItemId) => async (ctx, next) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't expose builder endpoints in the cloud
|
// don't expose builder endpoints in the cloud
|
||||||
if (env.CLOUD && permName === BUILDER) return
|
if (env.CLOUD && permType === PermissionTypes.BUILDER) return
|
||||||
|
|
||||||
if (!ctx.auth.authenticated) {
|
if (!ctx.auth.authenticated) {
|
||||||
ctx.throw(403, "Session not authenticated")
|
ctx.throw(403, "Session not authenticated")
|
||||||
|
@ -47,41 +44,18 @@ module.exports = (permName, getItemId) => async (ctx, next) => {
|
||||||
ctx.throw(403, "User not found")
|
ctx.throw(403, "User not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.user.accessLevel._id === ADMIN_LEVEL_ID) {
|
if (ADMIN_PERMS.indexOf(ctx.user.accessLevel._id) !== -1) {
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.user.accessLevel._id === BUILDER_LEVEL_ID) {
|
if (permType === PermissionTypes.BUILDER) {
|
||||||
return next()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (permName === BUILDER) {
|
|
||||||
ctx.throw(403, "Not Authorized")
|
ctx.throw(403, "Not Authorized")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const permissionId = ({ name, itemId }) => name + (itemId ? `-${itemId}` : "")
|
// TODO: Replace the old permissions system here, check whether
|
||||||
|
// user has permission to use endpoint they are trying to access
|
||||||
const thisPermissionId = permissionId({
|
|
||||||
name: permName,
|
|
||||||
itemId: getItemId && getItemId(ctx),
|
|
||||||
})
|
|
||||||
|
|
||||||
// power user has everything, except the admin specific perms
|
|
||||||
if (
|
|
||||||
ctx.user.accessLevel._id === POWERUSER_LEVEL_ID &&
|
|
||||||
!adminPermissions.map(permissionId).includes(thisPermissionId)
|
|
||||||
) {
|
|
||||||
return next()
|
return next()
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
//ctx.throw(403, "Not Authorized")
|
||||||
ctx.user.accessLevel.permissions
|
|
||||||
.map(permissionId)
|
|
||||||
.includes(thisPermissionId)
|
|
||||||
) {
|
|
||||||
return next()
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.throw(403, "Not Authorized")
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
|
@ -1,4 +1,4 @@
|
||||||
const { BUILDER_LEVEL_ID } = require("../accessLevels")
|
const { BUILDER_LEVEL_ID } = require("../security/accessLevels")
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const CouchDB = require("../../db")
|
const CouchDB = require("../../db")
|
||||||
const jwt = require("jsonwebtoken")
|
const jwt = require("jsonwebtoken")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const viewController = require("../api/controllers/view")
|
const viewController = require("../api/controllers/view")
|
||||||
const tableController = require("../api/controllers/table")
|
const tableController = require("../api/controllers/table")
|
||||||
const automationController = require("../api/controllers/automation")
|
const automationController = require("../api/controllers/automation")
|
||||||
const accessLevels = require("./accessLevels")
|
const accessLevels = require("./security/accessLevels")
|
||||||
|
|
||||||
// this has been broken out to reduce risk of circular dependency from utilities, no enums defined here
|
// this has been broken out to reduce risk of circular dependency from utilities, no enums defined here
|
||||||
const generateAdminPermissions = async appId => [
|
const generateAdminPermissions = async appId => [
|
||||||
|
|
|
@ -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