Sfoglia il codice sorgente

feature: 添加了对项目列表访问的权限控制,只允许项目负责人,项目组成员,项目和任务审核人及允许访问所有项目的特权人员获取相关项目信息
bug_fix: 修改了get_tasks中ui_status的原始数据被代码修改的bug,改为用clone

eyes4 6 mesi fa
parent
commit
3ad0299181

+ 4 - 0
pmr-biz-manager/src/routes/api/cfg/staff/add.ts

@@ -72,6 +72,10 @@ function add(json: IRequest, _params: IMethodParams, cached_data: ICachedData):
                 user_id: data.mobile,
                 domain_id: data.domain_id,
             }, {transaction: t});
+            await AcsUserDomain.create({
+                user_id: data.mobile,
+                domain_id: 100,
+            }, {transaction: t});
 
             await AcsUserRole.upsert({
                 user_id: data.mobile,

+ 2 - 2
pmr-biz-manager/src/routes/api/cfg/staff/get_list.ts

@@ -110,8 +110,8 @@ export function get(json: IRequest, params: IMethodParams, cachedData: ICachedDa
             select_sql += ` order by name desc `;
             let result = await DataCURD.get_page_list({
                 sequelize: BizCustomer.sequelize!,
-                page_no: 1,//data.page_no,
-                page_size: 100,//data.page_size,
+                page_no: data.page_no,
+                page_size: data.page_size,
                 count_sql: count_sql,
                 count_replacements: replacements,
                 select_sql: select_sql,

+ 51 - 10
pmr-biz-manager/src/routes/api/prj/info/get_list.ts

@@ -12,6 +12,7 @@ import {BizContractInfo} from "@core-models/BizContractInfo";
 import {PrjPhaseDefine} from "@core-models/PrjPhaseDefine";
 import {BpmnWork} from "@core-models/BpmnWork";
 import {BpmnCase} from "@core-models/BpmnCase";
+import {PrjMembers} from "@core-models/PrjMembers";
 
 interface IData {
     /**
@@ -68,7 +69,6 @@ interface IData {
     type_id?: number;
 }
 
-
 function get_list(json: IRequest, params: IMethodParams, cached_data: ICachedData): Promise<WhereOptions> {
     return new Promise<WhereOptions>(async (resolve, reject) => {
         try {
@@ -117,9 +117,57 @@ function get_list(json: IRequest, params: IMethodParams, cached_data: ICachedDat
                     work.assigned_to = '${cached_data.user_id}' and 
                     work.status <> 2 and work.process_type = 1 and
                     flow.model_id = 'prj'
-                where 1=1 
+                where (
+                    -- 项目负责人可以取到自己的项目
+                    prj.leader_id = :user_id or
+                    
+                    -- 项目商务负责人可以取到自己的项目
+                    prj.bizman_id = :user_id or
+                    
+                    -- 项目组成员可以取到自己的项目
+                    EXISTS (
+                        select 1 from ${PrjMembers.table_name} member where member.member_id = :user_id and member.prj_id = prj.id
+                    ) or
+                  
+                    -- 有全部项目查看权限的人(特权人员)可以取到全部项目
+                    EXISTS (
+                        select 1 from tb_acs_user
+                        where ext_info->>'full_range' = 'true'
+                         and id = :user_id
+                    ) or
+                    
+                    -- 项目审核人可以取到相关项目
+                    EXISTS (
+                        select 1 from tb_prj_info prj_info, jsonb_array_elements(prj.checkers) AS checker_obj
+                        where checker_obj->>'id' = :user_id and prj_info.id = prj.id
+                    ) or
+                    --prj.id in (
+                    --   select prj_id from (
+                    --    select * from (SELECT distinct jsonb_array_elements_text((value ->> 'handlers')::jsonb) AS handler, prj_id
+                    --                   FROM tb_prj_plan_task_draft,
+                    --                        jsonb_array_elements(checkers) AS checker_obj) a
+                    --    ) b) or
+                    
+
+                    -- 任务审核人可以取到相关项目
+                    EXISTS (
+                        SELECT 1
+                        FROM tb_prj_plan_task prj_task,
+                             jsonb_array_elements(prj_task.checkers) AS checker_obj
+                        WHERE  (checker_obj->>'handlers')::jsonb ? :user_id
+                          and prj_task.prj_id = prj.id
+                    
+                       ) 
+                    --prj.id in (select prj_id from (
+                    --    select * from (SELECT  distinct jsonb_array_elements_text((value ->> 'handlers')::jsonb) AS handler, prj_id
+                    --    FROM tb_prj_plan_task_draft,
+                    --          jsonb_array_elements(checkers) AS checker_obj) a where a.handler = :user_id
+                    --) b)
+                     
+                )    
+
             `;
-            let replacements: ISQLReplacements = {};
+            let replacements: ISQLReplacements = {user_id: cached_data.user_id};
             if (data.name !== undefined) {
                 condition += ` and prj.name like :name `;
                 replacements.name = `%${data.name}%`;
@@ -137,13 +185,6 @@ function get_list(json: IRequest, params: IMethodParams, cached_data: ICachedDat
                 replacements.leader_id = data.leader_id;
             }
             if (data.region_id !== undefined) {
-                // condition += `
-                //     and prj.id in (
-                //         select customer.id as id from ${AcsDomain.table_name} domain, ${BizCustomer.table_name} customer
-                //         where domain.id = customer.region_id and
-                //             domain.path <@(select path from ${AcsDomain.table_name} where id = :region_id)
-                //     )
-                // `;
                 condition += `
                     and prj.id in (
                         select prj.id as id from ${AcsDomain.table_name} domain, ${PrjInfo.table_name} prj

+ 15 - 1
pmr-biz-manager/src/routes/api/prj/info/modify.ts

@@ -57,7 +57,20 @@ interface IData {
     type_id?: number;
 }
 
+function permission_guard(content: IRequest, cached_data: ICachedData): Promise<void> {
+    return new Promise<void>(async (resolve, reject) => {
+        let data = <IData>content.data;
+        let prj = await PrjInfo.findOne({where: {id: data.id, raw: true}});
+        if (!prj)
+            throw Resp.gen_err(Resp.ResourceNotFound, '项目不存在。');
+
+        if (prj.leader_id !== cached_data.user_id)
+            return reject(Resp.gen_err(Resp.Forbidden, '您没有权限修改该项目,请确认您是项目负责人。'));
+
+        resolve();
 
+    });
+}
 
 async function get_where(json: IRequest, params: IMethodParams, cached_data: ICachedData): Promise<WhereOptions> {
     let data = <IData>json.data;
@@ -274,7 +287,8 @@ const v1_0: IApiProcessor = {
             intro: "intro",
             // updated_at: "updated_at"
         }
-    }
+    },
+    guards: [permission_guard],
 }
 
 module.exports = {

+ 2 - 0
pmr-biz-manager/src/routes/api/prj/info/remove.ts

@@ -21,6 +21,8 @@ export function statusGuard(json: IRequest, cached_data: ICachedData): Promise<v
         if (user === ADMINISTRATOR) return resolve();
         let prj_info = await PrjInfo.findOne({where: {id: data.id}, raw: true});
         if (!prj_info) return reject(Resp.gen_err(Resp.ResourceNotFound));
+        if (prj_info.leader_id !== cached_data.user_id)
+            return reject(Resp.gen_err(Resp.Forbidden, '您没有权限删除该项目,请确认您是项目负责人。'));
         let phase = await PrjPhaseDefine.findOne({where: {id: prj_info.phase_id}, raw: true});
         if (!phase) return reject(Resp.gen_err(Resp.ResourceNotFound, '项目状态信息出错,id: ' + prj_info.id));
         if (phase.order_index > 0) return reject(Resp.gen_err(Resp.InvalidFlow, '当前项目阶段不允许删除项目,可使用作废功能使项目作废。'));

+ 2 - 0
pmr-biz-manager/src/routes/api/prj/info/set_checkers.ts

@@ -26,6 +26,8 @@ function statusGuard(json: IRequest, cached_data: ICachedData): Promise<void> {
 
         let prj_info = await PrjInfo.findOne({where: {id: data.id}, raw: true});
         if (!prj_info) return reject(Resp.gen_err(Resp.ResourceNotFound));
+        if (prj_info.leader_id !== cached_data.user_id)
+            return reject(Resp.gen_err(Resp.Forbidden, '您没有权限设置该项目的审核组成员,请确认您是项目负责人。'));
         let phase = await PrjPhaseDefine.findOne({where: {id: prj_info.phase_id}, raw: true});
         if (!phase) return reject(Resp.gen_err(Resp.ResourceNotFound, '项目状态信息出错,id: ' + prj_info.id));
         if (phase.id !== 'new' && phase.id !== 'doing') return reject(Resp.gen_err(Resp.InvalidFlow, '当前项目阶段不允许修改审核人。'));

+ 9 - 1
pmr-biz-manager/src/routes/api/prj/plan/get_tasks.ts

@@ -13,6 +13,8 @@ import {PrjPlanTaskDraft} from "@core-models/PrjPlanTaskDraft";
 import {PrjTaskOutcome} from "@core-models/PrjTaskOutcome";
 import {PrjTaskOutcomeDraft} from "@core-models/PrjTaskOutcomeDraft";
 import {ChangeMarker} from "@src/utils/define";
+import {Logger} from "@util/Logger";
+import {clone} from "@util/JsonToolkit";
 
 interface IData {
     /**
@@ -224,7 +226,9 @@ function get_tasks(json: IRequest, params: IMethodParams, cached_data: ICachedDa
             let data = <IData>json.data;
             let prj = await PrjInfo.findOne({where: {id: data.prj_id}, raw: true});
             if (!prj) return reject(Resp.gen_err(Resp.DataExists, `项目不存在,id:${data.prj_id}`));
+            Logger.trace(prj);
             let phase = await PrjPhaseDefine.findOne({where: {id: prj.phase_id}, raw: true});
+            Logger.trace(phase);
             let result: any = {
                 status: phase!.order_index,
                 tasks: new Array<any>(),
@@ -235,9 +239,13 @@ function get_tasks(json: IRequest, params: IMethodParams, cached_data: ICachedDa
                     handler_name: "rw",
                     begin_at: "rw",
                     end_at: "rw"
-                } : ui_status[prj.phase_id],
+                } : clone(ui_status[prj.phase_id]),
             }
+            Logger.trace(`data.draft: ${data.draft} ui_status doing: `);
+            console.log(ui_status['doing']);
+            console.log(data.draft ? {"test": test}: ui_status[prj.phase_id]);
             // 检查用户是否是项目负责人,只有项目负责人才可以修改任务
+            Logger.trace(`get_tasks: user_id: ${cached_data.user_id} leader_id: ${prj.leader_id}  alter: ${result.ui_status.alter}` );
             if (cached_data.user_id !== prj.leader_id) {
                 result.ui_status.alter = false;
             }

+ 2 - 2
pmr-biz-manager/src/routes/api/prj/work/upload_file.ts

@@ -57,7 +57,7 @@ function get_upload_url(json: IRequest, params: IMethodParams, cached_data: ICac
 }
 
 /// 检查工作项是否存在
-function existsGuard(json: IRequest, cached_data: ICachedData): Promise<void> {
+function exists_guard(json: IRequest, cached_data: ICachedData): Promise<void> {
     return new Promise<void>(async (resolve, reject) => {
         let data = <IData>json.data;
         let work = await BpmnWork.findOne({where: {id: data.work_id}, raw: true});
@@ -131,7 +131,7 @@ const v1_0: IApiProcessor = {
     },
     method: get_upload_url,
     method_params: {},
-    guards: [existsGuard]
+    guards: [exists_guard]
 };
 
 module.exports = {