refactor: permission user

This commit is contained in:
Methapon Metanipat 2024-09-04 11:40:55 +07:00
parent 34668b3569
commit 9f426d9b08

View file

@ -34,6 +34,12 @@ if (!process.env.MINIO_BUCKET) {
} }
const MINIO_BUCKET = process.env.MINIO_BUCKET; const MINIO_BUCKET = process.env.MINIO_BUCKET;
const MANAGE_ROLES = ["system", "head_of_admin", "admin", "branch_manager"];
function globalAllow(user: RequestWithUser["user"]) {
const listAllowed = ["system", "head_of_admin"];
return user.roles?.some((v) => listAllowed.includes(v)) || false;
}
type UserCreate = { type UserCreate = {
status?: Status; status?: Status;
@ -294,7 +300,7 @@ export class UserController extends Controller {
} }
@Post() @Post()
@Security("keycloak", ["system", "head_of_admin", "admin", "branch_admin", "branch_manager"]) @Security("keycloak", MANAGE_ROLES)
async createUser(@Request() req: RequestWithUser, @Body() body: UserCreate) { async createUser(@Request() req: RequestWithUser, @Body() body: UserCreate) {
const [province, district, subDistrict, branch, user] = await prisma.$transaction([ const [province, district, subDistrict, branch, user] = await prisma.$transaction([
prisma.province.findFirst({ where: { id: body.provinceId ?? undefined } }), prisma.province.findFirst({ where: { id: body.provinceId ?? undefined } }),
@ -340,31 +346,25 @@ export class UserController extends Controller {
throw new HttpError(HttpStatus.BAD_REQUEST, "User exists.", "userExists"); throw new HttpError(HttpStatus.BAD_REQUEST, "User exists.", "userExists");
} }
if (!["system", "head_of_admin", "admin"].some((v) => req.user.roles?.includes(v))) { const roleSetIndex = MANAGE_ROLES.findIndex((v) => v === body.userRole);
if (body.userRole in ["system", "head_of_admin", "admin"]) {
throw new HttpError( const THROW_PERM_MSG = "You do not have permission to perform this action.";
HttpStatus.FORBIDDEN, const THROW_PERM_CODE = "noPermission";
"You do not have permission to perform this action.",
"noPermission", if (roleSetIndex !== -1 && roleSetIndex < 1) {
); throw new HttpError(HttpStatus.FORBIDDEN, THROW_PERM_MSG, THROW_PERM_CODE);
}
if (!req.user.roles.includes("branch_admin") && body.userRole === "branch_admin") {
throw new HttpError(
HttpStatus.FORBIDDEN,
"You do not have permission to perform this action.",
"noPermission",
);
}
} }
if ( if (roleSetIndex !== -1 && roleSetIndex < 2 && !req.user.roles?.includes("head_of_admin")) {
!["system", "head_of_admin", "admin"].some((v) => req.user.roles?.includes(v)) && throw new HttpError(HttpStatus.FORBIDDEN, THROW_PERM_MSG, THROW_PERM_CODE);
branch?.some((v) => !v.user.find((v) => v.userId === req.user.sub)) }
) { if (roleSetIndex !== -1 && roleSetIndex < 3 && !req.user.roles?.includes("admin")) {
throw new HttpError( throw new HttpError(HttpStatus.FORBIDDEN, THROW_PERM_MSG, THROW_PERM_CODE);
HttpStatus.FORBIDDEN, }
"You do not have permission to perform this action.",
"noPermission", if (!globalAllow(req.user)) {
); if (branch.some((v) => !v.user.find((v) => v.userId === req.user.sub))) {
throw new HttpError(HttpStatus.FORBIDDEN, THROW_PERM_MSG, THROW_PERM_CODE);
}
} }
const { branchId, provinceId, districtId, subDistrictId, username, ...rest } = body; const { branchId, provinceId, districtId, subDistrictId, username, ...rest } = body;
@ -416,27 +416,24 @@ export class UserController extends Controller {
province: { connect: provinceId ? { id: provinceId } : undefined }, province: { connect: provinceId ? { id: provinceId } : undefined },
district: { connect: districtId ? { id: districtId } : undefined }, district: { connect: districtId ? { id: districtId } : undefined },
subDistrict: { connect: subDistrictId ? { id: subDistrictId } : undefined }, subDistrict: { connect: subDistrictId ? { id: subDistrictId } : undefined },
branch: {
create: Array.isArray(branchId)
? branchId.map((v) => ({
branchId: v,
createdByUserId: req.user.sub,
udatedByUserId: req.user.sub,
}))
: {
branchId,
createdByUserId: req.user.sub,
updatedByUserId: req.user.sub,
},
},
createdBy: { connect: { id: req.user.sub } }, createdBy: { connect: { id: req.user.sub } },
updatedBy: { connect: { id: req.user.sub } }, updatedBy: { connect: { id: req.user.sub } },
}, },
}); });
await prisma.branchUser.createMany({
data: Array.isArray(branchId)
? branchId.map((v) => ({
branchId: v,
userId: record.id,
createdByUserId: req.user.sub,
updatedByUserId: req.user.sub,
}))
: {
branchId,
userId: record.id,
createdByUserId: req.user.sub,
updatedByUserId: req.user.sub,
},
});
const updated = await userBranchCodeGen(record, branch[0]); // only generate code by using first branch only const updated = await userBranchCodeGen(record, branch[0]); // only generate code by using first branch only
record.code = updated.code; record.code = updated.code;
@ -458,7 +455,7 @@ export class UserController extends Controller {
} }
@Put("{userId}") @Put("{userId}")
@Security("keycloak", ["system", "head_of_admin", "admin", "branch_admin", "branch_manager"]) @Security("keycloak", MANAGE_ROLES)
async editUser( async editUser(
@Request() req: RequestWithUser, @Request() req: RequestWithUser,
@Body() body: UserUpdate, @Body() body: UserUpdate,
@ -509,34 +506,25 @@ export class UserController extends Controller {
"minimumBranchNotMet", "minimumBranchNotMet",
); );
} }
if ( const roleSetIndex = MANAGE_ROLES.findIndex((v) => v === body.userRole);
body.userRole &&
!["system", "head_of_admin", "admin"].some((v) => req.user.roles?.includes(v)) const THROW_PERM_MSG = "You do not have permission to perform this action.";
) { const THROW_PERM_CODE = "noPermission";
if (body.userRole in ["system", "head_of_admin", "admin"]) {
throw new HttpError( if (roleSetIndex !== -1 && roleSetIndex < 1) {
HttpStatus.FORBIDDEN, throw new HttpError(HttpStatus.FORBIDDEN, THROW_PERM_MSG, THROW_PERM_CODE);
"You do not have permission to perform this action.",
"noPermission",
);
}
if (!req.user.roles.includes("branch_admin") && body.userRole === "branch_admin") {
throw new HttpError(
HttpStatus.FORBIDDEN,
"You do not have permission to perform this action.",
"noPermission",
);
}
} }
if ( if (roleSetIndex !== -1 && roleSetIndex < 2 && !req.user.roles?.includes("head_of_admin")) {
!["system", "head_of_admin", "admin"].some((v) => req.user.roles?.includes(v)) && throw new HttpError(HttpStatus.FORBIDDEN, THROW_PERM_MSG, THROW_PERM_CODE);
branch?.some((v) => !v.user.find((v) => v.userId === req.user.sub)) }
) { if (roleSetIndex !== -1 && roleSetIndex < 3 && !req.user.roles?.includes("admin")) {
throw new HttpError( throw new HttpError(HttpStatus.FORBIDDEN, THROW_PERM_MSG, THROW_PERM_CODE);
HttpStatus.FORBIDDEN, }
"You do not have permission to perform this action.",
"noPermission", if (!globalAllow(req.user)) {
); if (branch.some((v) => !v.user.find((v) => v.userId === req.user.sub))) {
throw new HttpError(HttpStatus.FORBIDDEN, THROW_PERM_MSG, THROW_PERM_CODE);
}
} }
let userRole: string | undefined; let userRole: string | undefined;
@ -658,7 +646,7 @@ export class UserController extends Controller {
} }
@Delete("{userId}") @Delete("{userId}")
@Security("keycloak", ["system", "head_of_admin", "admin", "branch_admin", "branch_manager"]) @Security("keycloak", MANAGE_ROLES)
async deleteUser(@Request() req: RequestWithUser, @Path() userId: string) { async deleteUser(@Request() req: RequestWithUser, @Path() userId: string) {
const record = await prisma.user.findFirst({ const record = await prisma.user.findFirst({
include: { include: {
@ -676,10 +664,7 @@ export class UserController extends Controller {
where: { id: userId }, where: { id: userId },
}); });
if ( if (!globalAllow(req.user) && !record?.branch.some((v) => v.userId === req.user.sub)) {
!["system", "head_of_admin", "admin"].some((v) => req.user.roles?.includes(v)) &&
!record?.branch.some((v) => v.userId === req.user.sub)
) {
throw new HttpError( throw new HttpError(
HttpStatus.FORBIDDEN, HttpStatus.FORBIDDEN,
"You do not have permission to perform this action.", "You do not have permission to perform this action.",