154 lines
4.3 KiB
JavaScript
154 lines
4.3 KiB
JavaScript
const db = require('../db/models');
|
|
|
|
class AccessPolicyAuditService {
|
|
static async findViolations(options = {}) {
|
|
const transaction = options.transaction;
|
|
|
|
const publicRoles = await db.roles.findAll({
|
|
where: { name: 'Public' },
|
|
include: [{ association: 'permissions' }],
|
|
transaction,
|
|
});
|
|
|
|
const publicRolePermissions = publicRoles.flatMap((role) =>
|
|
(role.permissions || []).map((permission) => ({
|
|
roleId: role.id,
|
|
permissionId: permission.id,
|
|
permissionName: permission.name,
|
|
})),
|
|
);
|
|
|
|
const publicUsersWithCustomPermissions = await db.users.findAll({
|
|
attributes: ['id', 'email'],
|
|
include: [
|
|
{
|
|
association: 'app_role',
|
|
attributes: ['id', 'name'],
|
|
where: { name: 'Public' },
|
|
required: true,
|
|
},
|
|
{
|
|
association: 'custom_permissions',
|
|
attributes: ['id', 'name'],
|
|
required: true,
|
|
},
|
|
],
|
|
transaction,
|
|
});
|
|
|
|
const productionPresentationAccessForNonPublicUsers =
|
|
await db.production_presentation_access.findAll({
|
|
attributes: ['id', 'userId', 'projectId'],
|
|
include: [
|
|
{
|
|
association: 'user',
|
|
attributes: ['id', 'email'],
|
|
required: true,
|
|
include: [
|
|
{
|
|
association: 'app_role',
|
|
attributes: ['id', 'name'],
|
|
required: false,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
association: 'project',
|
|
attributes: ['id', 'name', 'slug'],
|
|
required: false,
|
|
},
|
|
],
|
|
transaction,
|
|
});
|
|
|
|
const nonPublicGrants =
|
|
productionPresentationAccessForNonPublicUsers.filter(
|
|
(grant) => grant.user?.app_role?.name !== 'Public',
|
|
);
|
|
|
|
return {
|
|
publicRolePermissions: publicRolePermissions.map((entry) => ({
|
|
roleId: entry.roleId,
|
|
id: entry.permissionId,
|
|
name: entry.permissionName,
|
|
})),
|
|
publicUsersWithCustomPermissions: publicUsersWithCustomPermissions.map(
|
|
(user) => ({
|
|
id: user.id,
|
|
email: user.email,
|
|
customPermissions: (user.custom_permissions || []).map(
|
|
(permission) => ({
|
|
id: permission.id,
|
|
name: permission.name,
|
|
}),
|
|
),
|
|
}),
|
|
),
|
|
productionPresentationAccessForNonPublicUsers: nonPublicGrants.map(
|
|
(grant) => ({
|
|
id: grant.id,
|
|
userId: grant.userId,
|
|
userEmail: grant.user?.email || null,
|
|
userRole: grant.user?.app_role?.name || null,
|
|
projectId: grant.projectId,
|
|
projectSlug: grant.project?.slug || null,
|
|
}),
|
|
),
|
|
};
|
|
}
|
|
|
|
static hasViolations(report) {
|
|
return (
|
|
report.publicRolePermissions.length > 0 ||
|
|
report.publicUsersWithCustomPermissions.length > 0 ||
|
|
report.productionPresentationAccessForNonPublicUsers.length > 0
|
|
);
|
|
}
|
|
|
|
static async cleanupViolations(options = {}) {
|
|
const transaction = options.transaction;
|
|
const report = await this.findViolations({ transaction });
|
|
|
|
const publicRoleIds = [
|
|
...new Set(
|
|
report.publicRolePermissions
|
|
.map((permission) => permission.roleId)
|
|
.filter(Boolean),
|
|
),
|
|
];
|
|
|
|
for (const publicRoleId of publicRoleIds) {
|
|
const publicRole = await db.roles.findByPk(publicRoleId, { transaction });
|
|
if (publicRole) {
|
|
await publicRole.setPermissions([], { transaction });
|
|
}
|
|
}
|
|
|
|
for (const userReport of report.publicUsersWithCustomPermissions) {
|
|
const user = await db.users.findByPk(userReport.id, { transaction });
|
|
await user.setCustom_permissions([], { transaction });
|
|
}
|
|
|
|
const grantIds = report.productionPresentationAccessForNonPublicUsers.map(
|
|
(grant) => grant.id,
|
|
);
|
|
|
|
if (grantIds.length > 0) {
|
|
await db.production_presentation_access.destroy({
|
|
where: { id: { [db.Sequelize.Op.in]: grantIds } },
|
|
transaction,
|
|
});
|
|
}
|
|
|
|
return {
|
|
before: report,
|
|
removedPublicRolePermissions: report.publicRolePermissions.length,
|
|
clearedPublicUserCustomPermissions:
|
|
report.publicUsersWithCustomPermissions.length,
|
|
removedNonPublicProductionPresentationGrants: grantIds.length,
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = AccessPolicyAuditService;
|