Added migration utils for removing a permission

- this will drop the link between a role and a permission, and then
  delete the permission
- required minor refactoring to aid in creating migrations for dropping
  the links and permission
This commit is contained in:
Daniel Lockyer 2022-05-10 13:10:22 +01:00
parent bf28721844
commit b7b4f8d1d1

View File

@ -10,6 +10,54 @@ const messages = {
permissionRoleActionError: 'Cannot {action} permission({permission}) with role({role}) - {resource} does not exist'
};
async function addPermissionHelper(connection, config) {
const existingPermission = await connection('permissions').where({
name: config.name,
action_type: config.action,
object_type: config.object
}).first();
if (existingPermission) {
logging.warn(`Permission for ${config.action}:${config.object} already added`);
return;
}
logging.info(`Adding permission for ${config.action}:${config.object}`);
const date = connection.raw('CURRENT_TIMESTAMP');
await connection('permissions').insert({
id: ObjectId().toHexString(),
name: config.name,
action_type: config.action,
object_type: config.object,
created_at: date,
created_by: MIGRATION_USER,
updated_at: date,
updated_by: MIGRATION_USER
});
}
async function removePermissionHelper(connection, config) {
const existingPermission = await connection('permissions').where({
name: config.name,
action_type: config.action,
object_type: config.object
}).first();
if (!existingPermission) {
logging.warn(`Permission for ${config.action}:${config.object} already removed`);
return;
}
logging.info(`Removing permission for ${config.action}:${config.object}`);
await connection('permissions').where({
action_type: config.action,
object_type: config.object
}).del();
}
/**
* Creates a migration which will add a permission to the database
*
@ -23,54 +71,120 @@ const messages = {
function addPermission(config) {
return createTransactionalMigration(
async function up(connection) {
const existingPermission = await connection('permissions').where({
name: config.name,
action_type: config.action,
object_type: config.object
}).first();
if (existingPermission) {
logging.warn(`Permission for ${config.action}:${config.object} already added`);
return;
}
logging.info(`Adding permission for ${config.action}:${config.object}`);
const date = connection.raw('CURRENT_TIMESTAMP');
await connection('permissions').insert({
id: ObjectId().toHexString(),
name: config.name,
action_type: config.action,
object_type: config.object,
created_at: date,
created_by: MIGRATION_USER,
updated_at: date,
updated_by: MIGRATION_USER
});
await addPermissionHelper(connection, config);
},
async function down(connection) {
const existingPermission = await connection('permissions').where({
name: config.name,
action_type: config.action,
object_type: config.object
}).first();
if (!existingPermission) {
logging.warn(`Permission for ${config.action}:${config.object} already removed`);
return;
}
logging.info(`Removing permission for ${config.action}:${config.object}`);
await connection('permissions').where({
action_type: config.action,
object_type: config.object
}).del();
await removePermissionHelper(connection, config);
}
);
}
/**
* Creates a migration which will remove a permission from the database
*
* @param {Object} config
* @param {string} config.name - The name of the permission
* @param {string} config.action - The action_type of the permission
* @param {string} config.object - The object_type of the permission
*
* @returns {Migration}
*/
function removePermission(config) {
return createTransactionalMigration(
async function up(connection) {
await removePermissionHelper(connection, config);
},
async function down(connection) {
await addPermissionHelper(connection, config);
}
);
}
async function addPermissionToRoleHelper(connection, config) {
const permission = await connection('permissions').where({
name: config.permission
}).first();
if (!permission) {
throw new errors.InternalServerError({
message: tpl(messages.permissionRoleActionError, {
action: 'add',
permission: config.permission,
role: config.role,
resource: 'permission'
})
});
}
const role = await connection('roles').where({
name: config.role
}).first();
if (!role) {
throw new errors.InternalServerError({
message: tpl(messages.permissionRoleActionError, {
action: 'add',
permission: config.permission,
role: config.role,
resource: 'role'
})
});
}
const existingRelation = await connection('permissions_roles').where({
permission_id: permission.id,
role_id: role.id
}).first();
if (existingRelation) {
logging.warn(`Adding permission(${config.permission}) to role(${config.role}) - already exists`);
return;
}
logging.info(`Adding permission(${config.permission}) to role(${config.role})`);
await connection('permissions_roles').insert({
id: ObjectId().toHexString(),
permission_id: permission.id,
role_id: role.id
});
}
async function removePermissionFromRoleHelper(connection, config) {
const permission = await connection('permissions').where({
name: config.permission
}).first();
if (!permission) {
logging.warn(`Removing permission(${config.permission}) from role(${config.role}) - Permission not found.`);
return;
}
const role = await connection('roles').where({
name: config.role
}).first();
if (!role) {
logging.warn(`Removing permission(${config.permission}) from role(${config.role}) - Role not found.`);
return;
}
const existingRelation = await connection('permissions_roles').where({
permission_id: permission.id,
role_id: role.id
}).first();
if (!existingRelation) {
logging.warn(`Removing permission(${config.permission}) from role(${config.role}) - already removed`);
return;
}
logging.info(`Removing permission(${config.permission}) from role(${config.role})`);
await connection('permissions_roles').where({
permission_id: permission.id,
role_id: role.id
}).del();
}
/**
* Creates a migration which will link a permission to a role in the database
*
@ -83,87 +197,30 @@ function addPermission(config) {
function addPermissionToRole(config) {
return createTransactionalMigration(
async function up(connection) {
const permission = await connection('permissions').where({
name: config.permission
}).first();
if (!permission) {
throw new errors.InternalServerError({
message: tpl(messages.permissionRoleActionError, {
action: 'add',
permission: config.permission,
role: config.role,
resource: 'permission'
})
});
}
const role = await connection('roles').where({
name: config.role
}).first();
if (!role) {
throw new errors.InternalServerError({
message: tpl(messages.permissionRoleActionError, {
action: 'add',
permission: config.permission,
role: config.role,
resource: 'role'
})
});
}
const existingRelation = await connection('permissions_roles').where({
permission_id: permission.id,
role_id: role.id
}).first();
if (existingRelation) {
logging.warn(`Adding permission(${config.permission}) to role(${config.role}) - already exists`);
return;
}
logging.info(`Adding permission(${config.permission}) to role(${config.role})`);
await connection('permissions_roles').insert({
id: ObjectId().toHexString(),
permission_id: permission.id,
role_id: role.id
});
await addPermissionToRoleHelper(connection, config);
},
async function down(connection) {
const permission = await connection('permissions').where({
name: config.permission
}).first();
await removePermissionFromRoleHelper(connection, config);
}
);
}
if (!permission) {
logging.warn(`Removing permission(${config.permission}) from role(${config.role}) - Permission not found.`);
return;
}
const role = await connection('roles').where({
name: config.role
}).first();
if (!role) {
logging.warn(`Removing permission(${config.permission}) from role(${config.role}) - Role not found.`);
return;
}
const existingRelation = await connection('permissions_roles').where({
permission_id: permission.id,
role_id: role.id
}).first();
if (!existingRelation) {
logging.warn(`Removing permission(${config.permission}) from role(${config.role}) - already removed`);
return;
}
logging.info(`Removing permission(${config.permission}) from role(${config.role})`);
await connection('permissions_roles').where({
permission_id: permission.id,
role_id: role.id
}).del();
/**
* Creates a migration which will remove the permission from roles
*
* @param {Object} config
* @param {string} config.permission - The name of the permission
* @param {string} config.role - The name of the role
*
* @returns {Migration}
*/
function removePermissionFromRole(config) {
return createTransactionalMigration(
async function up(connection) {
await removePermissionFromRoleHelper(connection, config);
},
async function down(connection) {
await addPermissionToRoleHelper(connection, config);
}
);
}
@ -187,10 +244,30 @@ function addPermissionWithRoles(config, roles) {
);
}
/**
* Creates a migration which will remove permissions from roles, and then remove the permission
*
* @param {Object} config
* @param {string} config.name - The name of the permission
* @param {string} config.action - The action_type of the permission
* @param {string} config.object - The object_type of the permission
*
* @param {string[]} roles - A list of role names
*
* @returns {Migration}
*/
function createRemovePermissionMigration(config, roles) {
return combineTransactionalMigrations(
...roles.map((role => removePermissionFromRole({permission: config.name, role}))),
removePermission(config)
);
}
module.exports = {
addPermission,
addPermissionToRole,
addPermissionWithRoles
addPermissionWithRoles,
createRemovePermissionMigration
};
/**