From 771f1a1c585b8856b23495d51673c89fbddd97dd Mon Sep 17 00:00:00 2001 From: Methapon Metanipat Date: Tue, 10 Sep 2024 13:33:59 +0700 Subject: [PATCH] feat: product group permission check --- .../04-product-group-controller.ts | 218 +++--------------- 1 file changed, 34 insertions(+), 184 deletions(-) diff --git a/src/controllers/04-product-group-controller.ts b/src/controllers/04-product-group-controller.ts index c8bd006..2365898 100644 --- a/src/controllers/04-product-group-controller.ts +++ b/src/controllers/04-product-group-controller.ts @@ -19,13 +19,19 @@ import { RequestWithUser } from "../interfaces/user"; import HttpError from "../interfaces/http-error"; import HttpStatus from "../interfaces/http-status"; import { isSystem } from "../utils/keycloak"; +import { + branchRelationPermInclude, + createPermCheck, + createPermCondition, +} from "../services/permission"; +import { filterStatus } from "../services/prisma"; type ProductGroupCreate = { name: string; detail: string; remark: string; status?: Status; - registeredBranchId?: string; + registeredBranchId: string; }; type ProductGroupUpdate = { @@ -50,56 +56,24 @@ function globalAllow(user: RequestWithUser["user"]) { return allowList.some((v) => user.roles?.includes(v)); } -async function permissionCheck(user: RequestWithUser["user"], branchId: string) { - const record = await prisma.branch.findUnique({ - include: { - headOffice: { - include: { - branch: { where: { user: { some: { userId: user.sub } } } }, - user: { where: { userId: user.sub } }, - }, - }, - user: { where: { userId: user.sub } }, - }, - where: { id: branchId }, - }); - - if (!record) { - throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound"); - } - - if (!isSystem(user)) { - if (!globalAllow(user) && record.user.length === 0) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } else { - if ( - (record.user.length === 0 && !record.headOffice) || - (record.headOffice && - record.headOffice.user.length === 0 && - record.headOffice.branch.length === 0) - ) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } - } - } - return record; -} +const permissionCond = createPermCondition(globalAllow); +const permissionCheck = createPermCheck(globalAllow); @Route("api/v1/product-group") @Tags("Product Group") export class ProductGroup extends Controller { @Get("stats") @Security("keycloak") - async getProductGroupStats() { - return await prisma.productGroup.count(); + async getProductGroupStats(@Request() req: RequestWithUser) { + return await prisma.productGroup.count({ + where: { + AND: [ + { + registeredBranch: isSystem(req.user) ? undefined : { OR: permissionCond(req.user) }, + }, + ], + }, + }); } @Get() @@ -111,45 +85,12 @@ export class ProductGroup extends Controller { @Query() page: number = 1, @Query() pageSize: number = 30, ) { - const filterStatus = (val?: Status) => { - if (!val) return {}; - - return val !== Status.CREATED && val !== Status.ACTIVE - ? { status: val } - : { OR: [{ status: Status.CREATED }, { status: Status.ACTIVE }] }; - }; - const where = { - OR: [ - { name: { contains: query }, ...filterStatus(status) }, - { detail: { contains: query }, ...filterStatus(status) }, - ], + OR: [{ name: { contains: query } }, { detail: { contains: query } }], AND: [ { - registeredBranch: isSystem(req.user) - ? undefined - : { - OR: [ - { - user: { some: { userId: req.user.sub } }, - }, - { - branch: globalAllow(req.user) - ? { some: { user: { some: { userId: req.user.sub } } } } - : undefined, - }, - { - headOffice: globalAllow(req.user) - ? { branch: { some: { user: { some: { userId: req.user.sub } } } } } - : undefined, - }, - { - headOffice: globalAllow(req.user) - ? { user: { some: { userId: req.user.sub } } } - : undefined, - }, - ], - }, + ...filterStatus(status), + registeredBranch: isSystem(req.user) ? undefined : { OR: permissionCond(req.user) }, }, ], } satisfies Prisma.ProductGroupWhereInput; @@ -202,18 +143,18 @@ export class ProductGroup extends Controller { @Post() @Security("keycloak", MANAGE_ROLES) async createProductGroup(@Request() req: RequestWithUser, @Body() body: ProductGroupCreate) { - if (body.registeredBranchId) { - await permissionCheck(req.user, body.registeredBranchId); - } + let company = await permissionCheck(req.user, body.registeredBranchId).then( + (v) => (v.headOffice || v).code, + ); const record = await prisma.$transaction( async (tx) => { const last = await tx.runningNo.upsert({ where: { - key: `PRODGRP`, + key: `PRODGRP_${company}`, }, create: { - key: `PRODGRP`, + key: `PRODGRP_${company}`, value: 1, }, update: { value: { increment: 1 } }, @@ -252,15 +193,7 @@ export class ProductGroup extends Controller { where: { id: groupId }, include: { registeredBranch: { - include: { - headOffice: { - include: { - branch: { where: { user: { some: { userId: req.user.sub } } } }, - user: { where: { userId: req.user.sub } }, - }, - }, - user: { where: { userId: req.user.sub } }, - }, + include: branchRelationPermInclude(req.user), }, }, }); @@ -272,71 +205,17 @@ export class ProductGroup extends Controller { ); } - if (!isSystem(req.user)) { - if (!globalAllow(req.user) && record.registeredBranch?.user.length === 0) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } else { - if ( - (record.registeredBranch?.user.length === 0 && !record.registeredBranch?.headOffice) || - (record.registeredBranch?.headOffice && - record.registeredBranch?.headOffice.user.length === 0 && - record.registeredBranch?.headOffice.branch.length === 0) - ) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } - } - } + if (record.registeredBranch) await permissionCheck(req.user, record.registeredBranch); const [branch] = await prisma.$transaction([ prisma.branch.findFirst({ where: { id: body.registeredBranchId }, - include: { - user: { - where: { userId: req.user.sub }, - }, - headOffice: { - include: { - user: { - where: { userId: req.user.sub }, - }, - }, - }, - }, + include: branchRelationPermInclude(req.user), }), ]); - if (body.registeredBranchId !== undefined && !isSystem(req.user)) { - if (!globalAllow(req.user)) { - if (body.registeredBranchId === null || (branch && branch.user.length === 0)) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } - } else { - if ( - body.registeredBranchId === null || - (branch && - branch.user.length === 0 && - branch.headOffice && - branch.headOffice.user.length === 0) - ) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } - } + if (body.registeredBranchId !== undefined) { + await permissionCheck(req.user, branch); } if (!!body.registeredBranchId && !branch) { @@ -366,15 +245,7 @@ export class ProductGroup extends Controller { where: { id: groupId }, include: { registeredBranch: { - include: { - headOffice: { - include: { - branch: { where: { user: { some: { userId: req.user.sub } } } }, - user: { where: { userId: req.user.sub } }, - }, - }, - user: { where: { userId: req.user.sub } }, - }, + include: branchRelationPermInclude(req.user), }, }, }); @@ -387,28 +258,7 @@ export class ProductGroup extends Controller { ); } - if (!isSystem(req.user)) { - if (!globalAllow(req.user) && record.registeredBranch?.user.length === 0) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } else { - if ( - (record.registeredBranch?.user.length === 0 && !record.registeredBranch?.headOffice) || - (record.registeredBranch?.headOffice && - record.registeredBranch?.headOffice.user.length === 0 && - record.registeredBranch?.headOffice.branch.length === 0) - ) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } - } - } + if (record.registeredBranch) await permissionCheck(req.user, record.registeredBranch); if (record.status !== Status.CREATED) { throw new HttpError(HttpStatus.FORBIDDEN, "Product group is in used.", "productGroupInUsed");