diff --git a/src/controllers/00-stats-controller.ts b/src/controllers/00-stats-controller.ts index 8cb5d53..ce0f144 100644 --- a/src/controllers/00-stats-controller.ts +++ b/src/controllers/00-stats-controller.ts @@ -12,7 +12,7 @@ import { } from "@prisma/client"; import { Controller, Get, Query, Request, Route, Security, Tags } from "tsoa"; import prisma from "../db"; -import { createPermCondition } from "../services/permission"; +import { createPermCondition, createQueryPermissionCondition } from "../services/permission"; import { RequestWithUser } from "../interfaces/user"; import { precisionRound } from "../utils/arithmetic"; import dayjs from "dayjs"; @@ -20,6 +20,7 @@ import { json2csv } from "json-2-csv"; import { isSystem } from "../utils/keycloak"; const permissionCondCompany = createPermCondition((_) => true); +const permissionQueryCondCompany = createQueryPermissionCondition((_) => true); const VAT_DEFAULT = config.vat; @@ -669,33 +670,7 @@ export class StatsController extends Controller { .distinctOn("Quotation.id"); if (!isSystem(req.user)) { - query = query.where(({ eb, exists }) => - exists( - eb - .selectFrom("Branch") - .leftJoin("BranchUser", "BranchUser.branchId", "Branch.id") - .leftJoin("Branch as SubBranch", "SubBranch.headOfficeId", "Branch.id") - .leftJoin("BranchUser as SubBranchUser", "SubBranchUser.branchId", "SubBranch.id") - .leftJoin("Branch as HeadBranch", "HeadBranch.id", "Branch.id") - .leftJoin("BranchUser as HeadBranchUser", "HeadBranchUser.branchId", "HeadBranch.id") - .leftJoin("Branch as SubHeadBranch", "SubHeadBranch.headOfficeId", "HeadBranch.id") - .leftJoin( - "BranchUser as SubHeadBranchUser", - "SubHeadBranchUser.branchId", - "SubHeadBranch.id", - ) - .where((eb) => { - const cond = [ - eb("BranchUser.userId", "=", req.user.sub), // NOTE: if user belong to current branch. - eb("SubBranchUser.userId", "=", req.user.sub), // NOTE: if user belong to branch under current branch. - eb("HeadBranchUser.userId", "=", req.user.sub), // NOTE: if the current branch is under head branch user belong to. - eb("SubHeadBranchUser.userId", "=", req.user.sub), // NOTE: if the current branch is under the same head branch user belong to. - ]; - return eb.or(cond); - }) - .select("Branch.id"), - ), - ); + query = query.where(permissionQueryCondCompany(req.user)); } const ret = await query.execute(); diff --git a/src/services/permission.ts b/src/services/permission.ts index 7ac7f66..88f4f6e 100644 --- a/src/services/permission.ts +++ b/src/services/permission.ts @@ -4,6 +4,8 @@ import HttpError from "../interfaces/http-error"; import HttpStatus from "../interfaces/http-status"; import { RequestWithUser } from "../interfaces/user"; import { isSystem } from "../utils/keycloak"; +import { ExpressionBuilder } from "kysely"; +import { DB } from "../generated/kysely/types"; export function branchRelationPermInclude(user: RequestWithUser["user"]) { return { @@ -133,3 +135,47 @@ export function createPermCheck(globalAllow: (user: RequestWithUser["user"]) => return branch; }; } + +export function createQueryPermissionCondition( + globalAllow: (user: RequestWithUser["user"]) => boolean, + opts?: { alwaysIncludeHead?: boolean }, +) { + return (user: RequestWithUser["user"]) => + ({ eb, exists }: ExpressionBuilder) => + exists( + eb + .selectFrom("Branch") + .leftJoin("BranchUser", "BranchUser.branchId", "Branch.id") + .leftJoin("Branch as SubBranch", "SubBranch.headOfficeId", "Branch.id") + .leftJoin("BranchUser as SubBranchUser", "SubBranchUser.branchId", "SubBranch.id") + .leftJoin("Branch as HeadBranch", "HeadBranch.id", "Branch.id") + .leftJoin("BranchUser as HeadBranchUser", "HeadBranchUser.branchId", "HeadBranch.id") + .leftJoin("Branch as SubHeadBranch", "SubHeadBranch.headOfficeId", "HeadBranch.id") + .leftJoin( + "BranchUser as SubHeadBranchUser", + "SubHeadBranchUser.branchId", + "SubHeadBranch.id", + ) + .where((eb) => { + const cond = [ + eb("BranchUser.userId", "=", user.sub), // NOTE: if user belong to current branch. + ]; + + if (globalAllow?.(user) || opts?.alwaysIncludeHead) { + cond.push( + eb("SubBranchUser.userId", "=", user.sub), // NOTE: if user belong to branch under current branch. + ); + } + + if (globalAllow(user)) { + cond.push( + eb("HeadBranchUser.userId", "=", user.sub), // NOTE: if the current branch is under head branch user belong to. + eb("SubHeadBranchUser.userId", "=", user.sub), // NOTE: if the current branch is under the same head branch user belong to. + ); + } + + return eb.or(cond); + }) + .select("Branch.id"), + ); +}