Updating role constraints and making sure roles can't be deleted if they are in use.

This commit is contained in:
mike12345567 2020-12-07 15:21:06 +00:00
parent 5e61deb489
commit c56bdd0751
3 changed files with 57 additions and 8 deletions

View File

@ -4,7 +4,40 @@ const {
Role, Role,
getRole, getRole,
} = require("../../utilities/security/roles") } = require("../../utilities/security/roles")
const { generateRoleID, getRoleParams } = require("../../db/utils") const {
generateRoleID,
getRoleParams,
getUserParams,
ViewNames,
} = require("../../db/utils")
const UpdateRolesOptions = {
CREATED: "created",
REMOVED: "removed",
}
async function updateRolesOnUserTable(db, roleId, updateOption) {
const table = await db.get(ViewNames.USERS)
const schema = table.schema
const remove = updateOption === UpdateRolesOptions.REMOVED
let updated = false
for (let prop of Object.keys(schema)) {
if (prop === "roleId") {
updated = true
const constraints = schema[prop].constraints
const indexOf = constraints.inclusion.indexOf(roleId)
if (remove && indexOf !== -1) {
constraints.inclusion.splice(indexOf, 1)
} else if (!remove && indexOf === -1) {
constraints.inclusion.push(roleId)
}
break
}
}
if (updated) {
await db.put(table)
}
}
exports.fetch = async function(ctx) { exports.fetch = async function(ctx) {
const db = new CouchDB(ctx.user.appId) const db = new CouchDB(ctx.user.appId)
@ -42,6 +75,7 @@ exports.save = async function(ctx) {
role._rev = ctx.request.body._rev role._rev = ctx.request.body._rev
} }
const result = await db.put(role) const result = await db.put(role)
await updateRolesOnUserTable(db, _id, UpdateRolesOptions.CREATED)
role._rev = result.rev role._rev = result.rev
ctx.body = role ctx.body = role
ctx.message = `Role '${role.name}' created successfully.` ctx.message = `Role '${role.name}' created successfully.`
@ -49,7 +83,26 @@ exports.save = async function(ctx) {
exports.destroy = async function(ctx) { exports.destroy = async function(ctx) {
const db = new CouchDB(ctx.user.appId) const db = new CouchDB(ctx.user.appId)
await db.remove(ctx.params.roleId, ctx.params.rev) const roleId = ctx.params.roleId
// first check no users actively attached to role
const users = (
await db.allDocs(
getUserParams(null, {
include_docs: true,
})
)
).rows.map(row => row.doc)
const usersWithRole = users.filter(user => user.roleId === roleId)
if (usersWithRole.length !== 0) {
ctx.throw("Cannot delete role when it is in use.")
}
await db.remove(roleId, ctx.params.rev)
await updateRolesOnUserTable(
db,
ctx.params.roleId,
UpdateRolesOptions.REMOVED
)
ctx.message = `Role ${ctx.params.roleId} deleted successfully` ctx.message = `Role ${ctx.params.roleId} deleted successfully`
ctx.status = 200 ctx.status = 200
} }

View File

@ -6,7 +6,7 @@ const { getRole } = require("../../utilities/security/roles")
exports.fetch = async function(ctx) { exports.fetch = async function(ctx) {
const database = new CouchDB(ctx.user.appId) const database = new CouchDB(ctx.user.appId)
const data = await database.allDocs( const data = await database.allDocs(
getUserParams("", { getUserParams(null, {
include_docs: true, include_docs: true,
}) })
) )

View File

@ -102,11 +102,7 @@ exports.generateRowID = tableId => {
* Gets parameters for retrieving users, this is a utility function for the getDocParams function. * Gets parameters for retrieving users, this is a utility function for the getDocParams function.
*/ */
exports.getUserParams = (username = "", otherProps = {}) => { exports.getUserParams = (username = "", otherProps = {}) => {
return getDocParams( return exports.getRowParams(ViewNames.USERS, username, otherProps)
DocumentTypes.ROW,
`${ViewNames.USERS}${SEPARATOR}${DocumentTypes.USER}${SEPARATOR}${username}`,
otherProps
)
} }
/** /**