一个用户对于一个资源的是否具有一系列操作权限的判断的重构
1、在获取资源列表的接口中,响应参数:actions,决定了当前用户对于一个资源的是否具有某个操作权限,值为 1 表示具有,值为 0 表示不具有。如图1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | "actions": { "enable": 0, "plan_task_create": 0, "disable": 1, "edit": 1, "update": 1, "submit": 1, "pass": 0, "refuse": 0, "return": 0, "view": 1, "delete": 1, "plan_task_index": 0, "review_opinion": 0, "invite": 0, "invite_accept": 0, "invite_refuse": 0, "plan_log_index": 1, "plan_resource_index": 0 }, |
2、接口文档说明,如图2
3、当调用删除资源的接口时,判断用户是否具有资源的操作权限:删除选题,删除 2 个资源,如图3
1 2 | // 判断用户是否具有资源的操作权限:删除选题(场景:编辑选题、指派任务等操作时,判断选题ID的存在性、操作按钮的显示与否(我的选题(获取选题列表))) PlanService::isActionAllow( explode ( ';' , $id ), Plan::ACTION_DELETE, $identity ); |
4、判断逻辑分为 2 个步骤,第 1 个步骤为:判断用户是否为选题的所有者(场景:编辑选题、指派任务等操作时,判断选题ID的存在性(我的选题(获取选题列表))),即资源列表中是否存在对应的资源 ID,如果不存在,则抛出异常,SQL 如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /** * 判断用户是否为选题的所有者(场景:编辑选题、指派任务等操作时,判断选题ID的存在性(我的选题(获取选题列表))) * * @param array $ids 多个选题ID * 格式如下:[1, 2, 3] * @param object $identity 当前用户的身份实例 * * @return array $models 多个选题对象 * * @throws NotFoundHttpException if the model cannot be found */ public static function isHaveIdentityOwner( $ids , $identity ) { /* @var $haveQuery PlanQuery */ // 获取查询对象(我的选题(获取选题列表)) $haveQuery = Plan::getHaveQuery( $identity ); $models = $haveQuery ->orderBy([Plan::tableName() . '.id' => SORT_DESC]) ->andWhere([ 'in' , Plan::tableName() . '.id' , $ids ]) ->indexBy( 'id' ) ->all(); if (! empty ( $models )) { // ID的数量与模型资源数量是否相等,如果不相等,响应失败 $flipIds = array_flip ( $ids ); if ( count ( $models ) == count ( $flipIds )) { return $models ; } else { $ids = implode( ';' , array_keys ( array_diff_key ( $flipIds , $models ))); } } else { $ids = implode( ';' , $ids ); } throw new NotFoundHttpException(Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '202080' ), [ 'ids' => $ids ])), 202080); } |
1 | SELECT `pa_plan`.* FROM `pa_plan` LEFT JOIN `pa_config_column` ON `pa_plan`.`config_column_id` = `pa_config_column`.`id` LEFT JOIN `pa_config_column_user` `ccu_plan_create` ON `pa_plan`.`config_column_id` = `ccu_plan_create`.`config_column_id` AND `pa_plan`.`create_user_id` = `ccu_plan_create`.`user_id` LEFT JOIN `pa_plan_attended_user_relation` ON `pa_plan`.`id` = `pa_plan_attended_user_relation`.`plan_id` LEFT JOIN `pa_config_column_user` `ccu_plan_relation` ON `pa_plan_attended_user_relation`.`config_column_id` = `ccu_plan_relation`.`config_column_id` AND `pa_plan_attended_user_relation`.`relation_user_id` = `ccu_plan_relation`.`user_id` LEFT JOIN `pa_plan_group_relation` ON `pa_plan`.`id` = `pa_plan_group_relation`.`plan_id` LEFT JOIN `pa_config_column_user` `ccu_plan_accepted` ON `pa_plan_group_relation`.`config_column_id` = `ccu_plan_accepted`.`config_column_id` AND `pa_plan_group_relation`.`accepted_user_id` = `ccu_plan_accepted`.`user_id` WHERE (`pa_config_column`.`is_deleted`=0) AND (`pa_plan`.`is_deleted`=0) AND (((`pa_plan`.`group_id`='c10e87f39873512a16727e17f57456a5') AND (`pa_plan`.`create_user_id`='1') AND (`ccu_plan_create`.`is_deleted`=0)) OR ((`pa_plan`.`group_id`='c10e87f39873512a16727e17f57456a5') AND (`pa_plan_attended_user_relation`.`relation_user_id`='1') AND (FIND_IN_SET('1', `pa_plan_attended_user_relation`.role)) AND (`pa_plan_attended_user_relation`.`is_deleted`=0) AND (`ccu_plan_relation`.`is_deleted`=0)) OR ((`pa_plan`.`group_id`='c10e87f39873512a16727e17f57456a5') AND (`pa_plan`.`config_column_id`=2)) OR ((`pa_plan`.`is_not_isolated`=1) AND (`pa_plan_group_relation`.`relation_group_id`='c10e87f39873512a16727e17f57456a5') AND (`pa_plan_group_relation`.`is_inviter`=0) AND (`pa_plan_group_relation`.`is_deleted`=0) AND ((`pa_plan_group_relation`.`accepted_status` IN (0, 2)) OR ((`pa_plan_group_relation`.`accepted_status`=1) AND (`pa_plan_group_relation`.`accepted_user_id`='1') AND (`ccu_plan_accepted`.`is_deleted`=0)) OR ((`pa_plan_group_relation`.`accepted_status`=1) AND (`pa_plan`.`config_column_id`=2))))) AND (`pa_plan`.`id` IN ('38', '39')) GROUP BY `pa_plan`.`id` ORDER BY `pa_plan`.`id` DESC |
5、如果需要删除的资源 ID 皆存在资源列表中,即确认用户为资源的所有者。判断用户是否具有资源的操作权限(场景:编辑选题、指派任务等操作时,判断操作按钮的显示与否(我的选题(获取选题列表)))。如果不具有,则抛出异常,如果具有,由执行后续的操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | /** * 判断用户是否具有资源的操作权限(场景:编辑选题、指派任务等操作时,判断操作按钮的显示与否(我的选题(获取选题列表))) * * @param array|object $item 选题数组 * @param string $action 资源的操作权限 * 格式如下:update * @param array $configColumns 栏目配置列表 * @param int $configColumnUserStatus 栏目人员状态 * @param array $planTaskCreatePlanAttendedUserRelations 基于 关联的用户ID、角色包含执行(负责)、多个选题ID 查找资源列表(场景:我的选题列表中,当前用户可指派任务的资源列表) * @param array $inviteAcceptPlanGroupRelations 基于 关联的租户ID、多个选题ID 查找资源列表(场景:我的选题列表中,当前租户可接受邀请/拒绝邀请的资源列表) * @param array $planTaskCreatePlanGroupRelations 基于 关联的租户ID、多个选题ID 查找资源列表(场景:我的选题列表中,当前租户可指派任务的资源列表) * @param array $isColumnManagerPlanIds 当前用户身为栏目负责人下的选题ID列表 * @param object $identity 当前用户的身份实例 * * @return int $isActionShow 0:无;1:有 */ public static function isActionShow( $item , $action , $configColumns , $configColumnUserStatus , $planTaskCreatePlanAttendedUserRelations , $inviteAcceptPlanGroupRelations , $planTaskCreatePlanGroupRelations , $isColumnManagerPlanIds , $identity ) { $isActionShow = 0; if ( $action == Plan::ACTION_ENABLE) { // 启用选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,0:禁用) if ( $item [ 'group_id' ] == $identity ->group_id && $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ( $item [ 'create_user_id' ] == $identity ->id || in_array( $item [ 'id' ], $isColumnManagerPlanIds )) && $item [ 'status' ] == Plan::STATUS_DISABLED) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_PLAN_TASK_CREATE) { // 指派任务的权限,0:无;1:有(栏目状态,1:启用 && 栏目人员状态,1:启用 && ((选题的租户ID为当前租户ID && 选题与参与用户的关联模型的关联的用户ID为当前登录用户ID && 选题与参与用户的关联模型的角色包含执行(负责) && 选题与参与用户的关联模型是否被删除,0:否 && 栏目人员是否被删除,0:否) || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,3:通过;5:指派;6:完成 && (选题的租户ID为当前租户ID || (选题的是否联合,1:是 && 选题与租户的关联模型的关联的租户ID为当前租户ID && 选题与租户的关联模型的是否邀请者,0:否 && 选题与租户的关联模型的接受状态,1:已接受 && 选题与租户的关联模型是否被删除,0:否 && 选题与租户的关联模型的状态,1:启用))) if ( $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && (isset( $planTaskCreatePlanAttendedUserRelations [ $item [ 'id' ]]) || in_array( $item [ 'id' ], $isColumnManagerPlanIds )) && in_array( $item [ 'status' ], [Plan::STATUS_PASSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED]) && ( $item [ 'group_id' ] == $identity ->group_id || isset( $planTaskCreatePlanGroupRelations [ $item [ 'id' ]]))) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_DISABLE) { // 禁用选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,1:编辑;2:待审;3:通过;4:拒绝;5:指派;6:完成) if ( $item [ 'group_id' ] == $identity ->group_id && $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ( $item [ 'create_user_id' ] == $identity ->id || in_array( $item [ 'id' ], $isColumnManagerPlanIds )) && in_array( $item [ 'status' ], [Plan::STATUS_EDITED, Plan::STATUS_WAITING_REVIEW, Plan::STATUS_PASSED, Plan::STATUS_REFUSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_EDIT) { // 编辑选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,1:编辑;2:待审;3:通过;4:拒绝;5:指派;6:完成) if ( $item [ 'group_id' ] == $identity ->group_id && $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ( $item [ 'create_user_id' ] == $identity ->id || in_array( $item [ 'id' ], $isColumnManagerPlanIds )) && in_array( $item [ 'status' ], [Plan::STATUS_EDITED, Plan::STATUS_WAITING_REVIEW, Plan::STATUS_PASSED, Plan::STATUS_REFUSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_UPDATE) { // 更新选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,1:编辑;2:待审;3:通过;4:拒绝;5:指派;6:完成) if ( $item [ 'group_id' ] == $identity ->group_id && $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ( $item [ 'create_user_id' ] == $identity ->id || in_array( $item [ 'id' ], $isColumnManagerPlanIds )) && in_array( $item [ 'status' ], [Plan::STATUS_EDITED, Plan::STATUS_WAITING_REVIEW, Plan::STATUS_PASSED, Plan::STATUS_REFUSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_SUBMIT) { // 提交审核选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,1:编辑;4:拒绝) if ( $item [ 'group_id' ] == $identity ->group_id && $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ( $item [ 'create_user_id' ] == $identity ->id || in_array( $item [ 'id' ], $isColumnManagerPlanIds )) && in_array( $item [ 'status' ], [Plan::STATUS_EDITED, Plan::STATUS_REFUSED])) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_PASS) { // 通过选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && 栏目人员配置角色标识包含栏目负责人标识 && 选题状态,2:待审) if ( $item [ 'group_id' ] == $identity ->group_id && $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && in_array( $item [ 'id' ], $isColumnManagerPlanIds ) && $item [ 'status' ] == Plan::STATUS_WAITING_REVIEW) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_REFUSE) { // 拒绝选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && 栏目人员配置角色标识包含栏目负责人标识 && 选题状态,2:待审) if ( $item [ 'group_id' ] == $identity ->group_id && $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && in_array( $item [ 'id' ], $isColumnManagerPlanIds ) && $item [ 'status' ] == Plan::STATUS_WAITING_REVIEW) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_RETURN) { // 退回选题的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && 栏目人员配置角色标识包含栏目负责人标识 && 选题状态,3:通过;5:指派) if ( $item [ 'group_id' ] == $identity ->group_id && $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && in_array( $item [ 'id' ], $isColumnManagerPlanIds ) && in_array( $item [ 'status' ], [Plan::STATUS_PASSED, Plan::STATUS_ASSIGNED])) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_VIEW) { // 详情的权限,0:无;1:有() $isActionShow = 1; } elseif ( $action == Plan::ACTION_DELETE) { // 删除选题的权限,0:无;1:有(选题的租户ID为当前租户ID && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识)) if ( $item [ 'group_id' ] == $identity ->group_id && ( $item [ 'create_user_id' ] == $identity ->id || in_array( $item [ 'id' ], $isColumnManagerPlanIds ))){ $isActionShow = 1; } } elseif ( $action == Plan::ACTION_PLAN_TASK_INDEX) { // 相关任务的权限,0:无;1:有(选题状态,3:通过;5:指派;6:完成) if (in_array( $item [ 'status' ], [Plan::STATUS_PASSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_REVIEW_OPINION) { // 审核意见的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题状态,4:拒绝) if ( $item [ 'group_id' ] == $identity ->group_id && $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ( $item [ 'create_user_id' ] == $identity ->id || in_array( $item [ 'id' ], $isColumnManagerPlanIds )) && $item [ 'status' ] == Plan::STATUS_REFUSED) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_INVITE) { // 邀请的权限,0:无;1:有(选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && (选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识) && 选题的是否联合,1:是 && 选题状态,3:通过;5:指派;6:完成) if ( $item [ 'group_id' ] == $identity ->group_id && $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ( $item [ 'create_user_id' ] == $identity ->id || in_array( $item [ 'id' ], $isColumnManagerPlanIds )) && $item [ 'is_united' ] == Plan::IS_UNITED_YES && in_array( $item [ 'status' ], [Plan::STATUS_PASSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_INVITE_ACCEPT) { // 同意邀请的权限,0:无;1:有 if ( $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && isset( $inviteAcceptPlanGroupRelations [ $item [ 'id' ]]) && in_array( $item [ 'status' ], [Plan::STATUS_PASSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) { $isActionShow = 1; } } elseif ( $action == Plan::ACTION_INVITE_REFUSE) { // 拒绝邀请的权限,0:无;1:有 if ( $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && isset( $inviteAcceptPlanGroupRelations [ $item [ 'id' ]]) && in_array( $item [ 'status' ], [Plan::STATUS_PASSED, Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) { $isActionShow = 0; } } elseif ( $action == Plan::ACTION_PLAN_LOG_INDEX) { // 选题日志的权限,0:无;1:有() $isActionShow = 1; } elseif ( $action == Plan::ACTION_PLAN_RESOURCE_INDEX) { // 选题素材的权限,0:无;1:有(选题状态,5:指派;6:完成) if (in_array( $item [ 'status' ], [Plan::STATUS_ASSIGNED, Plan::STATUS_COMPLETED])) { $isActionShow = 1; } } return $isActionShow ; } |
6、由于新增加了选题资源的一些列表接口,因此,导致第 1 个步骤:判断用户是否为选题的所有者(场景:编辑选题、指派任务等操作时,判断选题ID的存在性(我的选题(获取选题列表))),需要兼容多个列表,进而导致多个 SQL。存在一定的难度,而且后续不可控。因此,最终决定,简化第 1 个步骤,完善第 2 个步骤。如图4
7、以启用选题举例,调整前的规则:
1 2 3 4 5 6 7 8 9 10 11 | ( 7 ) actions['enable']:启用选题 ( 选题的租户ID为当前租户ID && 栏目状态,1:启用 && 栏目人员状态,1:启用 && ( 选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识 ) && 选题状态,0:禁用 ) |
1 2 3 | if ( $item [ 'group_id' ] == $identity ->group_id && $configColumns [ $item [ 'config_column_id' ]][ 'status' ] == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && ( $item [ 'create_user_id' ] == $identity ->id || in_array( $item [ 'id' ], $isColumnManagerPlanIds )) && $item [ 'status' ] == Plan::STATUS_DISABLED) { $isActionShow = 1; } |
8、以启用选题举例,调整后的规则:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ( 7 ) actions['enable']:启用选题 ( 选题状态,0:禁用 && ( 是否下发,0:否 && 栏目是否被删除,0:否 && 栏目人员是否被删除,0:否 && 栏目状态,1:启用 && 栏目人员状态,1:启用 && 选题的租户ID为当前租户ID && ( 选题创建用户ID为当前登录用户ID || 栏目人员配置角色标识包含栏目负责人标识 ) ) || ( 是否下发,1:是 && 选题的租户ID为当前租户ID && 选题创建用户ID为当前登录用户ID ) ) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | if ( $item [ 'status' ] == Plan::STATUS_DISABLED && ( $item [ 'is_send_down' ] == Plan::IS_SEND_DOWN_NO && $configColumnIsDeleted == ConfigColumn::IS_DELETED_NO && $configColumnUserIsDeleted == ConfigColumnUser::IS_DELETED_NO && $configColumnStatus == ConfigColumn::STATUS_ENABLED && $configColumnUserStatus == ConfigColumnUser::STATUS_ENABLED && $item [ 'group_id' ] == $identity ->group_id && ( $item [ 'create_user_id' ] == $identity ->id || in_array( $item [ 'id' ], $isColumnManagerPlanIds ) ) ) || ( $item [ 'is_send_down' ] == Plan::IS_SEND_DOWN_YES && $item [ 'group_id' ] == $identity ->group_id && $item [ 'create_user_id' ] == $identity ->id ) ) { $isActionShow = 1; } |
9、删除 16 与 43 时,由于第 1 个步骤验证失败,响应如下,如图5
1 2 3 4 5 6 7 | { "name": "Not Found", "message": "选题ID:16,不存在于我的选题列表中", "code": 202080, "status": 404, "type": "yii\\web\\NotFoundHttpException" } |
10、简化第 1 个步骤,且调整第 2 个步骤后,删除 16 与 43 时,由于由于第 1 个步骤验证成功,且第 2 个步骤验证失败,响应如下,如图6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | /** * 判断用户是否为选题的所有者(场景:编辑选题、指派任务等操作时,判断选题ID的存在性(我的选题、待审核选题、相关选题))) * * @param array $ids 多个选题ID * 格式如下:[1, 2, 3] * * @return array $models 多个选题对象 * * @throws NotFoundHttpException if the model cannot be found */ public static function isIndexIdentityOwner( $ids ) { $models = Plan::find() ->where([ 'in' , Plan::tableName() . '.id' , $ids ]) ->isDeletedNo() ->indexBy( 'id' ) ->all(); if (! empty ( $models )) { // ID的数量与模型资源数量是否相等,如果不相等,响应失败 $flipIds = array_flip ( $ids ); if ( count ( $models ) == count ( $flipIds )) { return $models ; } else { $ids = implode( ';' , array_keys ( array_diff_key ( $flipIds , $models ))); } } else { $ids = implode( ';' , $ids ); } throw new NotFoundHttpException(Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '202080' ), [ 'ids' => $ids ])), 202080); } /** * 判断用户是否具有资源的操作权限(场景:编辑选题、指派任务等操作时,判断选题ID的存在性、操作按钮的显示与否(我的选题(获取选题列表))) * * @param array $ids 多个选题ID * 格式如下:[1, 2, 3] * @param string $action 资源的操作权限 * 格式如下:update * @param object $identity 当前用户的身份实例 * * @return bool * * @throws NotFoundHttpException if the model cannot be found * @throws UnprocessableEntityHttpException */ public static function isActionAllow( $ids , $action , $identity ) { // 判断用户是否为选题的所有者(场景:编辑选题、指派任务等操作时,判断选题ID的存在性(我的选题、待审核选题、相关选题))) $models = static ::isIndexIdentityOwner( $ids ); $serialize = static ::getPlanSerializer( $models , $identity ); /* 查询当前分页的栏目配置列表 */ $configColumns = $serialize [ 'configColumns' ]; /* 查询当前分页的栏目人员配置列表 */ $configColumnUsers = $serialize [ 'configColumnUsers' ]; // 基于 关联的用户ID、角色包含执行(负责)、多个选题ID 查找资源列表(场景:我的选题列表中,当前用户可指派任务的资源列表) $planTaskCreatePlanAttendedUserRelations = $serialize [ 'planTaskCreatePlanAttendedUserRelations' ]; // 基于 关联的租户ID、多个选题ID 查找资源列表(场景:我的选题列表中,当前租户可接受邀请/拒绝邀请的资源列表) $inviteAcceptPlanGroupRelations = $serialize [ 'inviteAcceptPlanGroupRelations' ]; // 基于 关联的租户ID、多个选题ID 查找资源列表(场景:我的选题列表中,当前租户可指派任务的资源列表) $planTaskCreatePlanGroupRelations = $serialize [ 'planTaskCreatePlanGroupRelations' ]; /* 查询多个选题对象的角色包含执行(负责)、状态为启用的选题与参与用户的关联列表 */ $planAttendedUserRoleExecs = $serialize [ 'planAttendedUserRoleExecs' ]; /* 查询当前分页的框架服务控制台用户列表 */ $redisCmcConsoleUsers = $serialize [ 'redisCmcConsoleUsers' ]; /* 当前用户身为栏目负责人下的选题ID列表 */ $isColumnManagerPlanIds = $serialize [ 'isColumnManagerPlanIds' ]; // 不具有相关操作权限的选题ID $ids = []; /* @var $model Plan */ foreach ( $models as $key => $model ) { // 栏目人员状态 $configColumnUserStatus = $configColumnUsers [ $model ->config_column_id . '_' . $identity ->id][ 'status' ] ?? ConfigColumnUser::STATUS_DISABLED; // 权限,0:无;1:有 $isActionAllow = static ::isActionShow( $model , $action , $configColumns , $configColumnUsers , $planTaskCreatePlanAttendedUserRelations , $inviteAcceptPlanGroupRelations , $planTaskCreatePlanGroupRelations , $isColumnManagerPlanIds , $identity ); if ( $isActionAllow == 0) { $ids [] = $model ->id; } } if (! empty ( $ids )) { $ids = implode( ';' , $ids ); throw new UnprocessableEntityHttpException(Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '202081' ), [ 'ids' => $ids , 'action' => $action ])), 202081); } return true; } |
1 | SELECT * FROM `pa_plan` WHERE (`pa_plan`.`id` IN ('16', '43')) AND (`is_deleted`=0) |
1 2 3 4 5 6 7 | { "name": "Unprocessable entity", "message": "当前用户不具有选题ID:16,的权限:enable", "code": 202081, "status": 422, "type": "yii\\web\\UnprocessableEntityHttpException" } |
11、其他的操作权限皆遵循上述类似的规则调整。便能够实现完整的操作权限控制,且降低了判断的性能开销。
近期评论