Some more fixes after testing permissions a bit further.
This commit is contained in:
parent
ec5f9788c5
commit
9fb4c14835
|
@ -18,6 +18,16 @@ const PermissionUpdateType = {
|
||||||
ADD: "add",
|
ADD: "add",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// utility function to stop this repetition - permissions always stored under roles
|
||||||
|
async function getAllDBRoles(db) {
|
||||||
|
const body = await db.allDocs(
|
||||||
|
getRoleParams(null, {
|
||||||
|
include_docs: true,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return body.rows.map(row => row.doc)
|
||||||
|
}
|
||||||
|
|
||||||
async function updatePermissionOnRole(
|
async function updatePermissionOnRole(
|
||||||
appId,
|
appId,
|
||||||
{ roleId, resourceId, level },
|
{ roleId, resourceId, level },
|
||||||
|
@ -27,12 +37,7 @@ async function updatePermissionOnRole(
|
||||||
const remove = updateType === PermissionUpdateType.REMOVE
|
const remove = updateType === PermissionUpdateType.REMOVE
|
||||||
const isABuiltin = isBuiltin(roleId)
|
const isABuiltin = isBuiltin(roleId)
|
||||||
const dbRoleId = getDBRoleID(roleId)
|
const dbRoleId = getDBRoleID(roleId)
|
||||||
const body = await db.allDocs(
|
const dbRoles = await getAllDBRoles(db)
|
||||||
getRoleParams(null, {
|
|
||||||
include_docs: true,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
const dbRoles = body.rows.map(row => row.doc)
|
|
||||||
const docUpdates = []
|
const docUpdates = []
|
||||||
|
|
||||||
// the permission is for a built in, make sure it exists
|
// the permission is for a built in, make sure it exists
|
||||||
|
@ -87,6 +92,28 @@ exports.fetchLevels = function(ctx) {
|
||||||
ctx.body = [PermissionLevels.WRITE, PermissionLevels.READ]
|
ctx.body = [PermissionLevels.WRITE, PermissionLevels.READ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.fetch = async function(ctx) {
|
||||||
|
const db = new CouchDB(ctx.appId)
|
||||||
|
const roles = await getAllDBRoles(db)
|
||||||
|
let permissions = {}
|
||||||
|
// create an object with structure role ID -> resource ID -> level
|
||||||
|
for (let role of roles) {
|
||||||
|
if (role.permissions) {
|
||||||
|
const roleId = getExternalRoleID(role._id)
|
||||||
|
if (permissions[roleId] == null) {
|
||||||
|
permissions[roleId] = {}
|
||||||
|
}
|
||||||
|
for (let [resource, level] of Object.entries(role.permissions)) {
|
||||||
|
permissions[roleId][resource] = higherPermission(
|
||||||
|
permissions[roleId][resource],
|
||||||
|
level
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.body = permissions
|
||||||
|
}
|
||||||
|
|
||||||
exports.getResourcePerms = async function(ctx) {
|
exports.getResourcePerms = async function(ctx) {
|
||||||
const resourceId = ctx.params.resourceId
|
const resourceId = ctx.params.resourceId
|
||||||
const db = new CouchDB(ctx.appId)
|
const db = new CouchDB(ctx.appId)
|
||||||
|
|
|
@ -23,6 +23,7 @@ function generateValidator() {
|
||||||
router
|
router
|
||||||
.get("/api/permission/builtin", authorized(BUILDER), controller.fetchBuiltin)
|
.get("/api/permission/builtin", authorized(BUILDER), controller.fetchBuiltin)
|
||||||
.get("/api/permission/levels", authorized(BUILDER), controller.fetchLevels)
|
.get("/api/permission/levels", authorized(BUILDER), controller.fetchLevels)
|
||||||
|
.get("/api/permission", authorized(BUILDER), controller.fetch)
|
||||||
.get(
|
.get(
|
||||||
"/api/permission/:resourceId",
|
"/api/permission/:resourceId",
|
||||||
authorized(BUILDER),
|
authorized(BUILDER),
|
||||||
|
|
|
@ -73,6 +73,22 @@ exports.createTable = async (request, appId, table, removeId = true) => {
|
||||||
return res.body
|
return res.body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.createRow = async (request, appId, tableId, row = null) => {
|
||||||
|
row = row || {
|
||||||
|
name: "Test Contact",
|
||||||
|
description: "original description",
|
||||||
|
status: "new",
|
||||||
|
tableId: tableId,
|
||||||
|
}
|
||||||
|
const res = await request
|
||||||
|
.post(`/api/${tableId}/rows`)
|
||||||
|
.send(row)
|
||||||
|
.set(exports.defaultHeaders(appId))
|
||||||
|
.expect("Content-Type", /json/)
|
||||||
|
.expect(200)
|
||||||
|
return res.body
|
||||||
|
}
|
||||||
|
|
||||||
exports.createRole = async (request, appId) => {
|
exports.createRole = async (request, appId) => {
|
||||||
const roleBody = {
|
const roleBody = {
|
||||||
name: "NewRole",
|
name: "NewRole",
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
const {
|
const {
|
||||||
createApplication,
|
createApplication,
|
||||||
createTable,
|
createTable,
|
||||||
|
createRow,
|
||||||
supertest,
|
supertest,
|
||||||
defaultHeaders,
|
defaultHeaders,
|
||||||
addPermission,
|
addPermission,
|
||||||
} = require("./couchTestUtils")
|
} = require("./couchTestUtils")
|
||||||
const { BUILTIN_ROLE_IDS } = require("../../../utilities/security/roles")
|
const { BUILTIN_ROLE_IDS } = require("../../../utilities/security/roles")
|
||||||
|
|
||||||
|
const HIGHER_ROLE_ID = BUILTIN_ROLE_IDS.BASIC
|
||||||
const STD_ROLE_ID = BUILTIN_ROLE_IDS.PUBLIC
|
const STD_ROLE_ID = BUILTIN_ROLE_IDS.PUBLIC
|
||||||
|
|
||||||
describe("/permission", () => {
|
describe("/permission", () => {
|
||||||
|
@ -15,6 +17,7 @@ describe("/permission", () => {
|
||||||
let appId
|
let appId
|
||||||
let table
|
let table
|
||||||
let perms
|
let perms
|
||||||
|
let row
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
;({ request, server } = await supertest())
|
;({ request, server } = await supertest())
|
||||||
|
@ -29,8 +32,17 @@ describe("/permission", () => {
|
||||||
appId = app.instance._id
|
appId = app.instance._id
|
||||||
table = await createTable(request, appId)
|
table = await createTable(request, appId)
|
||||||
perms = await addPermission(request, appId, STD_ROLE_ID, table._id)
|
perms = await addPermission(request, appId, STD_ROLE_ID, table._id)
|
||||||
|
row = await createRow(request, appId, table._id)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
async function getTablePermissions() {
|
||||||
|
return request
|
||||||
|
.get(`/api/permission/${table._id}`)
|
||||||
|
.set(defaultHeaders(appId))
|
||||||
|
.expect("Content-Type", /json/)
|
||||||
|
.expect(200)
|
||||||
|
}
|
||||||
|
|
||||||
describe("levels", () => {
|
describe("levels", () => {
|
||||||
it("should be able to get levels", async () => {
|
it("should be able to get levels", async () => {
|
||||||
const res = await request
|
const res = await request
|
||||||
|
@ -45,7 +57,7 @@ describe("/permission", () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("test", () => {
|
describe("add", () => {
|
||||||
it("should be able to add permission to a role for the table", async () => {
|
it("should be able to add permission to a role for the table", async () => {
|
||||||
expect(perms.length).toEqual(1)
|
expect(perms.length).toEqual(1)
|
||||||
expect(perms[0]._id).toEqual(`${STD_ROLE_ID}`)
|
expect(perms[0]._id).toEqual(`${STD_ROLE_ID}`)
|
||||||
|
@ -57,6 +69,40 @@ describe("/permission", () => {
|
||||||
.set(defaultHeaders(appId))
|
.set(defaultHeaders(appId))
|
||||||
.expect("Content-Type", /json/)
|
.expect("Content-Type", /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
|
expect(res.body[STD_ROLE_ID]).toEqual("read")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should get resource permissions with multiple roles", async () => {
|
||||||
|
perms = await addPermission(request, appId, HIGHER_ROLE_ID, table._id, "write")
|
||||||
|
const res = await getTablePermissions()
|
||||||
|
expect(res.body[HIGHER_ROLE_ID]).toEqual("write")
|
||||||
|
expect(res.body[STD_ROLE_ID]).toEqual("read")
|
||||||
|
const allRes = await request
|
||||||
|
.get(`/api/permission`)
|
||||||
|
.set(defaultHeaders(appId))
|
||||||
|
.expect("Content-Type", /json/)
|
||||||
|
.expect(200)
|
||||||
|
expect(allRes.body[HIGHER_ROLE_ID][table._id]).toEqual("write")
|
||||||
|
expect(allRes.body[STD_ROLE_ID][table._id]).toEqual("read")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("remove", () => {
|
||||||
|
it("should be able to remove the permission", async () => {
|
||||||
|
const res = await request
|
||||||
|
.delete(`/api/permission/${STD_ROLE_ID}/${table._id}/read`)
|
||||||
|
.set(defaultHeaders(appId))
|
||||||
|
.expect("Content-Type", /json/)
|
||||||
|
.expect(200)
|
||||||
|
expect(res.body[0]._id).toEqual(STD_ROLE_ID)
|
||||||
|
const permsRes = await getTablePermissions()
|
||||||
|
expect(permsRes.body[STD_ROLE_ID]).toBeUndefined()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("check public user allowed", () => {
|
||||||
|
it("should be able to read the row", async () => {
|
||||||
|
// TODO
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -64,12 +64,12 @@ module.exports = (permType, permLevel = null) => async (ctx, next) => {
|
||||||
ctx.throw(403, "Not Authorized")
|
ctx.throw(403, "Not Authorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (
|
if (
|
||||||
// hasResource(ctx) &&
|
hasResource(ctx) &&
|
||||||
// doesHaveResourcePermission(permissions, permLevel, ctx)
|
doesHaveResourcePermission(permissions, permLevel, ctx)
|
||||||
// ) {
|
) {
|
||||||
// return next()
|
return next()
|
||||||
// }
|
}
|
||||||
|
|
||||||
if (!doesHaveBasePermission(permType, permLevel, basePermissions)) {
|
if (!doesHaveBasePermission(permType, permLevel, basePermissions)) {
|
||||||
ctx.throw(403, "User does not have permission")
|
ctx.throw(403, "User does not have permission")
|
||||||
|
|
Loading…
Reference in New Issue