diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/DataFilterAspect.java b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/DataFilterAspect.java index ce4cde92b7..3a60549d6a 100644 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/DataFilterAspect.java +++ b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/aspect/DataFilterAspect.java @@ -1,22 +1,11 @@ -/** - * Copyright (c) 2018 人人开源 All rights reserved. - *

- * https://www.renren.io - *

- * 版权所有,侵权必究! - */ - package com.epmet.commons.mybatis.aspect; import com.epmet.commons.mybatis.annotation.DataFilter; import com.epmet.commons.mybatis.feign.MybatisGovAccessFeignClient; -import com.epmet.commons.tools.constant.AccessSettingConstant; -import com.epmet.commons.tools.constant.OpeScopeConstant; import com.epmet.commons.mybatis.dto.form.*; import com.epmet.commons.tools.constant.ThreadLocalConstant; -import com.epmet.commons.tools.dto.form.LoginUserInfoResultDTO; -import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.RenException; +import com.epmet.commons.tools.security.user.LoginUserUtil; import com.epmet.commons.tools.utils.Result; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; @@ -28,9 +17,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.util.*; /** * 数据过滤,切面处理类 @@ -44,13 +30,11 @@ public class DataFilterAspect { private static final Logger log = LoggerFactory.getLogger(DataFilterAspect.class); - /** - * 线程变量,记录是否已经添加了至少一个过滤条件 - */ - private static final ThreadLocal hasConditions = new ThreadLocal(); + @Autowired + private LoginUserUtil loginUserUtil; @Autowired - private MybatisGovAccessFeignClient govAccessFeignClient; + private MybatisGovAccessFeignClient mybatisGovAccessFeignClient; @Before("@annotation(com.epmet.commons.mybatis.annotation.DataFilter)") public void dataFilter(JoinPoint point) { @@ -88,22 +72,17 @@ public class DataFilterAspect { } } - LoginUserInfoResultDTO loginUserInfo = ThreadLocalConstant.loginUserInfoTl.get(); - - hasConditions.set(false); + //LoginUserInfoResultDTO loginUserInfo = getLoginUserInfo(); - // 生成过滤sql - String sqlFilterSegment = getSqlFilterSegment( - loginUserInfo.getUserId(), - loginUserInfo.getRoleIdList(), - requirePermission, - loginUserInfo.getOrgIdPath(), - loginUserInfo.getGridIdList(), - tableAlias, - loginUserInfo.getDeptIdList(), - gridId, - deptId, - requirePermission); + GetSQLFilterFormDTO form = new GetSQLFilterFormDTO(); + form.setApp(loginUserUtil.getLoginUserApp()); + form.setClient(loginUserUtil.getLoginUserClient()); + form.setUserId(loginUserUtil.getLoginUserId()); + form.setDepartmentId(deptId); + form.setGridId(gridId); + form.setOperationKey(requirePermission); + form.setTableAlias(tableAlias); + Result sqlFilterSegmentRst = mybatisGovAccessFeignClient.getSqlFilterSegment(form); // 方式1.填充到Service方法列表中的DataScope对象中。如果dao入参是用DTO的话,那么再加一个DataScope入参,sql中会报错提示#{}参数找不到,因此改用方法2 //Object[] methodArgs = point.getArgs(); @@ -115,319 +94,13 @@ public class DataFilterAspect { //} // 方式2,采用ThreadLocal传参到DataFilterInterceptor中 - if (StringUtils.isNotBlank(sqlFilterSegment)) { - ThreadLocalConstant.sqlFilter.set(sqlFilterSegment); - } - } - - /** - * 生成过滤sql片段 - * - * @return - */ - private String getSqlFilterSegment(String userId, Set roleIds, String reqiurePermission, String orgIdPath, - Set gridIdList, String tableAlias, Set deptIds, String gridId, String deptId, - String operationKey) { - - StringBuilder sb = new StringBuilder(); - - Map accessSettings = listRoleAccessSettings(roleIds, operationKey); - - // 1.生成sql:组织范围过滤 - if (!genOrgScopeSql(sb, orgIdPath, roleIds, reqiurePermission, tableAlias)) { - // 返回false,说明已经开启了all所有范围,后续条件不在拼接入sql,结束执行 - return sb.toString(); - } - - // 2.生成sql:我发起的 - String iCreated = accessSettings.get(AccessSettingConstant.I_CREATED_KEY); - if (StringUtils.isNotBlank(iCreated) && AccessSettingConstant.I_CREATED_ON.equals(iCreated)) { - genICreatedSql(sb, userId, tableAlias); - } - // 3.生成sql:本网格的 - String inGrid = accessSettings.get(AccessSettingConstant.IN_GRID_KEY); - if (StringUtils.isNotBlank(inGrid) && AccessSettingConstant.IN_GRID_ON.equals(inGrid)) { - if (StringUtils.isBlank(gridId)) { - log.error("DataFilter:拼接SQL语句出错:需要in grid权限,但是代码中没有获取到:{}", gridId); - throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); - } - genInGrid(sb, gridId, tableAlias); - } - - // 4.生成sql:根据部门列表 - String inDept = accessSettings.get(AccessSettingConstant.IN_DEPARTMENT_KEY); - if (StringUtils.isNotBlank(inDept) && AccessSettingConstant.IN_DEPARTMENT_ON.equals(inDept)) { - if (StringUtils.isBlank(deptId)) { - log.error("DataFilter:拼接SQL语句出错:需要in department权限,但是代码中没有获取到:{}", deptId); - throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); - } - genDepartmentFilterSql(sb, deptId, tableAlias); + if (!sqlFilterSegmentRst.success()) { + throw new RenException("DataFilterAspect调用Access服务生成SqlFilterSegment失败:" + sqlFilterSegmentRst.getMsg()); } - return sb.toString(); - } - - /** - * 列出角色对应的权限设置项 - * - * @param roleIds - * @return - */ - private Map listRoleAccessSettings(Set roleIds, String operationKey) { - Map settings = new HashMap<>(); - roleIds.forEach(roleId -> { - settings.putAll(listRoleAccessSettings(roleId, operationKey)); - }); - return settings; - } - - private Map listRoleAccessSettings(String roleId, String operationKey) { - AccessSettingFormDTO accessSettingFormDTO = new AccessSettingFormDTO(); - accessSettingFormDTO.setRoleId(roleId); - accessSettingFormDTO.setOperationKey(operationKey); - Result> result = govAccessFeignClient.listAccessSettings(accessSettingFormDTO); - if (result.success()) { - return result.getData(); - } else { - log.error("角色[{}]查询权限配置AccessSettings失败:{}", roleId, result.getMsg()); - } - return new HashMap<>(); - } - - /** - * 生成部门过滤sql - * - * @param sb - */ - private void genDepartmentFilterSql(StringBuilder sb, String deptId, String tableAlias) { - //Result> deptListResult = govOrgFeignClient.getDepartmentListByStaffId(staffId); - if (hasConditions.get()) { - // 之前没有条件 - sb.append(" OR "); - } - if (StringUtils.isBlank(tableAlias)) { - sb.append(" DEPARTMENT_ID = '").append(deptId).append("' "); - } else { - sb.append(" ").append(tableAlias).append(".DEPARTMENT_ID ='").append(deptId).append("' "); - } - hasConditions.set(true); - } - - //private void genDepartmentFilterSql(StringBuilder sb, Set deptIdList) { - // //Result> deptListResult = govOrgFeignClient.getDepartmentListByStaffId(staffId); - // if (CollectionUtils.isEmpty(deptIdList)) { - // return; - // } - // deptIdList.forEach(deptId -> { - // sb.append(hasConditions.get() ? " OR " : "").append(" DEPARTMENT_ID = '").append(deptId).append("' "); - // }); - // hasConditions.set(true); - //} - - /** - * 网格sql - * - * @param sb - * @param tableAlias - */ - private void genInGrid(StringBuilder sb, String gridId, String tableAlias) { - if (hasConditions.get()) { - // 之前没有条件 - sb.append(" OR "); - } - - // OR GRID_ID = 'XXX' OR GRID_ID = 'QQQ' - if (StringUtils.isBlank(tableAlias)) { - sb.append(" GRID_ID = '").append(gridId).append("' "); - } else { - sb.append(" ").append(tableAlias).append(".GRID_ID ='").append(gridId).append("' "); - } - hasConditions.set(true); - } - - /** - * sql:我发起的 - * - * @param userId - */ - private void genICreatedSql(StringBuilder sb, String userId, String tableAlias) { - if (StringUtils.isBlank(tableAlias)) { - sb.append(hasConditions.get() ? " OR " : " ").append(" CREATED_BY ='").append(userId).append("'"); - } else { - sb.append(hasConditions.get() ? " OR " : " ").append(tableAlias).append(".CREATED_BY ='").append(userId).append("'"); - } - hasConditions.set(true); - } - - /** - * 计算组织范围过滤sql,整体入口 - * @param sb - * @param orgIdPath - * @param roleIds - * @param reqiurePermission - * @param tableAlias - * @return Boolean 是否继续往下执行。true:继续执行,false:不继续执行 - */ - public boolean genOrgScopeSql(StringBuilder sb, String orgIdPath, Set roleIds, String reqiurePermission, String tableAlias) { - - // 根据角色列表查询操作范围列表 - Set opeAndScopes = new HashSet<>(); - - roleIds.forEach(roleId -> { - Result> opeResult = govAccessFeignClient.listRoleAllOperationScopesByRoleId(roleId); - if (!opeResult.success()) { - log.error("DataFilter:根据角色查询角色所有的操作列表出错:{}", opeResult.getMsg()); - } else { - List opes = opeResult.getData(); - if (!CollectionUtils.isEmpty(opes)) { - opes.forEach(ope -> { - if (reqiurePermission.equals(ope.getOperationKey())) { - // 拿到当前操作对应的 RoleOpeScopeResultDTO - opeAndScopes.add(ope); - } - }); - } - } - }); - - // 过滤出最大的范围 - HashSet scopes = filteScopes(opeAndScopes); - if (CollectionUtils.isEmpty(scopes)) { - // 没有范围限制 - return true; - } - if (scopes.contains(OpeScopeConstant.ORG_ALL)) { - return false; - } - - // 生成sql语句 - genOrgScopeSql(sb, scopes, orgIdPath, tableAlias); - sb.replace(sb.lastIndexOf("OR"), sb.lastIndexOf("OR") + 3, ""); - hasConditions.set(true); - return true; - } - - /** - * 计算组织范围过滤sql - * PS:这个方法需要优化,当前阶段因为逻辑不稳定,暂时不做过度封装 - * @param scopes - * @return - */ - private void genOrgScopeSql(StringBuilder sb, HashSet scopes, String orgIdPath, String tableAlias) { - // 取出父组织ID path 和当前组织ID - //String parentOrgIDPath = orgIdPath.substring(0, orgIdPath.lastIndexOf(orgIdPathSpliter)); - //String currOrgID = orgIdPath.substring(orgIdPath.lastIndexOf(orgIdPathSpliter) + 1); - - for (String scope : scopes) { - switch (scope) { - // 当前单位(可以用ORG_ID_PATH,也可以用ORG_ID判断) - case OpeScopeConstant.ORG_CURR: - if (StringUtils.isBlank(tableAlias)) { - sb.append(" ORG_ID_PATH = '").append(orgIdPath).append("' OR "); - //sb.append(" ORG_ID = '").append(currOrgID).append("' OR "); - } else { - sb.append(" ").append(tableAlias).append(".ORG_ID_PATH = '").append(orgIdPath).append("' OR "); - //sb.append(" ").append(tableAlias).append(".ORG_ID = '").append(currOrgID).append("' OR "); - } - break; - // 本单位及其子级单位 - case OpeScopeConstant.ORG_CURR_AND_SUB: - if (StringUtils.isBlank(tableAlias)) { - sb.append(" ORG_ID_PATH like '").append(orgIdPath).append("%' OR "); - } else { - sb.append(" ").append(tableAlias).append(".ORG_ID_PATH like '").append(orgIdPath).append("%' OR "); - } - break; - // 本单位的子级单位 - case OpeScopeConstant.ORG_CURR_SUB: - if (StringUtils.isBlank(tableAlias)) { - sb.append(" ORG_ID_PATH like '").append(orgIdPath).append(":%' OR "); - } else { - sb.append(" ").append(tableAlias).append(".ORG_ID_PATH like '").append(orgIdPath).append(":%' OR "); - } - break; - //当前单位的父级单位 - case OpeScopeConstant.ORG_CURR_SUP: - if (StringUtils.isBlank(tableAlias)) { - sb.append(" '").append(orgIdPath).append("' like CONCAT(").append("ORG_ID_PATH,':%') OR "); - } else { - sb.append(" '").append(orgIdPath).append("' like CONCAT(").append(tableAlias).append(".ORG_ID_PATH,':%') OR "); - } - break; - // 当前单位及其父级单位 - case OpeScopeConstant.ORG_CURR_AND_SUP: - if (StringUtils.isBlank(tableAlias)) { - sb.append(" '").append(orgIdPath).append("' like CONCAT(").append("ORG_ID_PATH,'%') OR "); - } else { - sb.append(" '").append(orgIdPath).append("' like CONCAT(").append(tableAlias).append(".ORG_ID_PATH,'%' ) OR "); - } - break; - case OpeScopeConstant.ORG_EQUAL: - // todo 同级 - //sb.append(" OR "); - break; - case OpeScopeConstant.ORG_EQUAL_AND_SUB: - // todo 同级及其子级 - //sb.append(" OR "); - break; - case OpeScopeConstant.ORG_EQUAL_SUB: - // todo 同级的子级 - //sb.append(" OR "); - break; - case OpeScopeConstant.ORG_EQUAL_AND_SUP: - // todo 同级及其上级 - //sb.append(" OR "); - break; - case OpeScopeConstant.ORG_EQUAL_SUP: - // todo 同级的上级 - //sb.append(" OR "); - break; - } - } - } - - /** - * 过滤有效范围 - * - * @param scopeDTOS - * @return - */ - private HashSet filteScopes(Set scopeDTOS) { - HashMap filtedScopes = new HashMap<>(); - for (RoleOpeScopeResultDTO scope : scopeDTOS) { - String scopeIndex = scope.getScopeIndex(); - if (StringUtils.isBlank(scopeIndex)) { - continue; - } - if (OpeScopeConstant.ORG_ALL.equals(scope.getScopeKey())) { - // 该操作具有all的权限,直接放入 - filtedScopes.put(scopeIndex, scope); - break; - } - String[] currArr = scopeIndex.split("_"); - if ("0".equals(currArr[1])) { - // 为0,说明没有包含关系,直接放入 - filtedScopes.put(scopeIndex, scope); - continue; - } - - RoleOpeScopeResultDTO tempScope = filtedScopes.get(currArr[0]); - if (tempScope != null) { - // 已经有ac开头的了 - String tempScopeIndex = tempScope.getScopeIndex(); - if (Integer.valueOf(currArr[1]) < Integer.valueOf(tempScopeIndex.split("_")[1])) { - filtedScopes.put(currArr[0], scope); - } - } else { - filtedScopes.put(currArr[0], scope); - } - } - HashSet scopeStrs = new HashSet<>(); - Set> entries = filtedScopes.entrySet(); - for (Map.Entry entry : entries) { - scopeStrs.add(entry.getValue().getScopeKey()); + if (StringUtils.isNotBlank(sqlFilterSegmentRst.getData())) { + ThreadLocalConstant.sqlFilter.set(sqlFilterSegmentRst.getData()); } - return scopeStrs; } } diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/dto/form/GetSQLFilterFormDTO.java b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/dto/form/GetSQLFilterFormDTO.java new file mode 100644 index 0000000000..e0d6b266d6 --- /dev/null +++ b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/dto/form/GetSQLFilterFormDTO.java @@ -0,0 +1,28 @@ +package com.epmet.commons.mybatis.dto.form; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class GetSQLFilterFormDTO { + + @NotBlank + private String operationKey; + + @NotBlank + private String userId; + + @NotBlank + private String app; + + @NotBlank + private String client; + + private String tableAlias; + + private String gridId; + + private String departmentId; + +} diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/MybatisGovAccessFeignClient.java b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/MybatisGovAccessFeignClient.java index 91e7743f4e..2c6e0d5ed8 100644 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/MybatisGovAccessFeignClient.java +++ b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/MybatisGovAccessFeignClient.java @@ -7,9 +7,9 @@ import com.epmet.commons.tools.utils.Result; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import java.util.List; -import java.util.Map; import java.util.Set; /** @@ -29,16 +29,17 @@ public interface MybatisGovAccessFeignClient { Result> getOperationScopesByRoleId(OperationScopeFormDTO operationScopeFormDTO); /** - * 查询角色的权限相关配置 + * 查询角色所有operation及其范围(缓存) * @return */ - @PostMapping("/gov/access/access/accesssettings") - Result> listAccessSettings(AccessSettingFormDTO accessSettingFormDTO); + @PostMapping("/gov/access/access/roleallopesandscopes/{roleId}") + Result> listRoleAllOperationScopesByRoleId(@PathVariable("roleId") String roleId); /** - * 查询角色所有operation及其范围(缓存) + * 查询sql过滤片段 + * @param form * @return */ - @PostMapping("/gov/access/access/roleallopesandscopes/{roleId}") - Result> listRoleAllOperationScopesByRoleId(@PathVariable("roleId") String roleId); + @PostMapping("/gov/access/access/getSqlFilterSegment") + Result getSqlFilterSegment(@RequestBody GetSQLFilterFormDTO form); } diff --git a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/MybatisGovAccessFeignClientFallback.java b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/MybatisGovAccessFeignClientFallback.java index 15562aa607..a14452346a 100644 --- a/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/MybatisGovAccessFeignClientFallback.java +++ b/epmet-commons/epmet-commons-mybatis/src/main/java/com/epmet/commons/mybatis/feign/fallback/MybatisGovAccessFeignClientFallback.java @@ -27,12 +27,12 @@ public class MybatisGovAccessFeignClientFallback implements MybatisGovAccessFeig } @Override - public Result> listAccessSettings(AccessSettingFormDTO accessSettingFormDTO) { - return ModuleUtils.feignConError(ServiceConstant.GOV_ACCESS_SERVER, "listAccessSettings", accessSettingFormDTO); + public Result> listRoleAllOperationScopesByRoleId(@PathVariable("roleId") String roleId){ + return ModuleUtils.feignConError(ServiceConstant.GOV_ACCESS_SERVER, "listRoleAllOperationScopesByRoleId", roleId); } @Override - public Result> listRoleAllOperationScopesByRoleId(@PathVariable("roleId") String roleId){ - return ModuleUtils.feignConError(ServiceConstant.GOV_ACCESS_SERVER, "listRoleAllOperationScopesByRoleId", roleId); + public Result getSqlFilterSegment(GetSQLFilterFormDTO form) { + return ModuleUtils.feignConError(ServiceConstant.GOV_ACCESS_SERVER, "getSqlFilterSegment", form); } } diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/BaseRequestLogAspect.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/BaseRequestLogAspect.java index 7ff4486544..eae13bdfd2 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/BaseRequestLogAspect.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/BaseRequestLogAspect.java @@ -11,6 +11,8 @@ import org.slf4j.LoggerFactory; import org.springframework.dao.DuplicateKeyException; import javax.servlet.http.HttpServletRequest; +import java.time.Duration; +import java.time.LocalDateTime; /** * 日志切面 @@ -40,13 +42,14 @@ public abstract class BaseRequestLogAspect { String requestURI = request.getRequestURI(); long id = Thread.currentThread().getId(); - Result result; + Result result = null; Exception exception = null; + LocalDateTime startTime = LocalDateTime.now(); + try { Object[] args = point.getArgs(); log.info(">>>>>>>>请求信息>>>>>>>>:线程ID:{},url:{},请求参数:{}", id, requestURI, objectsToString(args)); result = (Result)point.proceed(); - log.info("<<<<<<<<正常响应<<<<<<<<:线程ID:{},响应数据:{}", id, result.toString()); } catch (RenException e) { exception = e; result = handleRenException(e); @@ -63,8 +66,13 @@ public abstract class BaseRequestLogAspect { exception = e; result = handlerException(e); } finally { + LocalDateTime endTime = LocalDateTime.now(); + long execTimeMillis = Duration.between(startTime, endTime).toMillis(); + if (exception != null) { - log.info("<<<<<<<<异常响应<<<<<<<<:线程ID:{},异常信息:{}", id, ExceptionUtils.getErrorStackTrace(exception)); + log.info("<<<<<<<<异常响应<<<<<<<<:线程ID:{},执行时长:{}ms, 异常信息:{}", id, execTimeMillis, ExceptionUtils.getErrorStackTrace(exception)); + } else { + log.info("<<<<<<<<正常响应<<<<<<<<:线程ID:{},执行时长:{}ms, 响应数据:{}", id, execTimeMillis, result == null ? result : result.toString()); } } return result; @@ -124,6 +132,7 @@ public abstract class BaseRequestLogAspect { } Result result=new Result().error(); result.setData(e.getMsg()); + //result.setMsg(e.getMsg()); return result; } diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/RequirePermissionAspect.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/RequirePermissionAspect.java index dca14ce55f..3b5858b805 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/RequirePermissionAspect.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/RequirePermissionAspect.java @@ -10,6 +10,7 @@ package com.epmet.commons.tools.aspect; import com.epmet.commons.tools.annotation.RequirePermission; import com.epmet.commons.tools.constant.ThreadLocalConstant; +import com.epmet.commons.tools.dto.form.HasSpecifiedPermissionFormDTO; import com.epmet.commons.tools.dto.form.LoginUserInfoFormDTO; import com.epmet.commons.tools.dto.form.LoginUserInfoResultDTO; import com.epmet.commons.tools.dto.form.RoleOpeScopeResultDTO; @@ -65,68 +66,32 @@ public class RequirePermissionAspect { String requirePermission = requirePermissionEnum.getKey(); - LoginUserInfoResultDTO loginUserInfo = getLoginUserInfo(); - - Set ownPermissions = getPermissions(loginUserInfo.getRoleIdList()); - - // 校验操作权限 - validateOpePermission(ownPermissions, requirePermission); + validPermission(requirePermission); // 操作权限校验通过。将该操作key放入ThreadLocal,供DataFilterAspect中数据权限过滤器进一步使用 ThreadLocalConstant.requirePermissionTl.set(requirePermission); - ThreadLocalConstant.loginUserInfoTl.set(loginUserInfo); } /** - * 获取登陆用户信息 - * @return + * 校验权限 + * @param requirePermission */ - private LoginUserInfoResultDTO getLoginUserInfo() { - LoginUserInfoFormDTO loginUserinfoFormDTO = new LoginUserInfoFormDTO(); - loginUserinfoFormDTO.setApp(loginUserUtil.getLoginUserApp()); - loginUserinfoFormDTO.setClient(loginUserUtil.getLoginUserClient()); - loginUserinfoFormDTO.setStaffId(loginUserUtil.getLoginUserId()); - Result result = govAccessFeignClient.getLoginUserInfo(loginUserinfoFormDTO); - + private void validPermission(String requirePermission) { + HasSpecifiedPermissionFormDTO form = new HasSpecifiedPermissionFormDTO(); + form.setApp(loginUserUtil.getLoginUserApp()); + form.setClient(loginUserUtil.getLoginUserClient()); + form.setUserId(loginUserUtil.getLoginUserId()); + form.setOperationKey(requirePermission); + Result result = govAccessFeignClient.hasSpecifiedPermission(form); if (result.getCode() != 0) { // 查询不到权限,记录日志,抛出8000异常 log.error("调用Access查询权限失败:{}", result.getMsg()); throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); } - - LoginUserInfoResultDTO loginUserInfo = result.getData(); - if (loginUserInfo == null) { - log.error("操作权限不足,查询不到登录用户信息"); - throw new RenException(EpmetErrorCode.REQUIRE_PERMISSION.getCode()); - } - - return loginUserInfo; - } - - /** - * 校验操作权限 - */ - private void validateOpePermission(Set permissions, String reqiurePermission) { - if (!permissions.contains(reqiurePermission)) { - // 权限不足 + Boolean data = result.getData(); + if (data == null || !data) { log.error("操作权限不足"); throw new RenException(EpmetErrorCode.REQUIRE_PERMISSION.getCode()); } } - - private Set getPermissions(Set roleIdList) { - Set permissions = new HashSet<>(); - roleIdList.forEach(role -> { - // 找出该角色的所有功能操作列表 - Result> result = govAccessFeignClient.listRoleAllOperationScopesByRoleId(role); - if (!result.success()) { - // 获取operation异常 - log.error("调用GovAccess,根据RoleId查询Operation列表失败:{}", result.getMsg()); - throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); - } - List roleOperations = result.getData(); - permissions.addAll(roleOperations.stream().map(ope -> ope.getOperationKey()).collect(Collectors.toSet())); - }); - return permissions; - } } diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/ThreadLocalInitAspect.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/ThreadLocalInitAspect.java index d42d3f7f55..2e070b1817 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/ThreadLocalInitAspect.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/aspect/ThreadLocalInitAspect.java @@ -38,7 +38,6 @@ public class ThreadLocalInitAspect { try { ThreadLocalConstant.sqlFilter.remove(); ThreadLocalConstant.requirePermissionTl.remove(); - ThreadLocalConstant.loginUserInfoTl.remove(); } catch (Exception e) { log.error("清理sqlFilter缓存失败:{}", ExceptionUtils.getErrorStackTrace(e)); } diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/OpeScopeConstant.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/OpeScopeConstant.java index b770f2f2cb..104e4bad7a 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/OpeScopeConstant.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/OpeScopeConstant.java @@ -5,7 +5,10 @@ package com.epmet.commons.tools.constant; */ public class OpeScopeConstant { - // 权限覆盖所有范围 + // 无任何范围限制 + public static final String ALL = "all"; + + // 覆盖机构下的所有范围 public static final String ORG_ALL = "org_all"; //"同级组织的下级" diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/ThreadLocalConstant.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/ThreadLocalConstant.java index 16f8113cf7..2dad0d6dba 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/ThreadLocalConstant.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/ThreadLocalConstant.java @@ -12,11 +12,6 @@ public class ThreadLocalConstant { */ public static final ThreadLocal requirePermissionTl = new ThreadLocal<>(); - /** - * 登陆用户信息的 ThreadLocal - */ - public static final ThreadLocal loginUserInfoTl = new ThreadLocal<>(); - /** * 用于向DataFilterInterceptor传递权限过滤的sql片段(需要在Controller相关的AOP中进行清理,防止变量残留) */ diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/HasSpecifiedPermissionFormDTO.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/HasSpecifiedPermissionFormDTO.java new file mode 100644 index 0000000000..4141741fb0 --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/HasSpecifiedPermissionFormDTO.java @@ -0,0 +1,22 @@ +package com.epmet.commons.tools.dto.form; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class HasSpecifiedPermissionFormDTO { + + @NotBlank + private String operationKey; + + @NotBlank + private String userId; + + @NotBlank + private String app; + + @NotBlank + private String client; + +} diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/EpmetErrorCode.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/EpmetErrorCode.java index 78f66e9330..d4ff8fb7e5 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/EpmetErrorCode.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/exception/EpmetErrorCode.java @@ -43,7 +43,10 @@ public enum EpmetErrorCode { CANNOT_DISABLE_YOURSELF(8405,"您不能禁用自己"), ALREADY_EVALUATE(8501,"您已评价"), - ALREADY_VOTE(8502,"您已表态"); + ALREADY_VOTE(8502,"您已表态"), + + // 该错误不会提示给前端,只是后端传输错误信息用。 + ACCESS_SQL_FILTER_MISSION_ARGS(8601, "缺少生成权限过滤SQL所需参数"); private int code; private String msg; diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/CommonGovAccessFeignClient.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/CommonGovAccessFeignClient.java index 682a30e96c..180cef4025 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/CommonGovAccessFeignClient.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/CommonGovAccessFeignClient.java @@ -1,6 +1,7 @@ package com.epmet.commons.tools.feign; import com.epmet.commons.tools.constant.ServiceConstant; +import com.epmet.commons.tools.dto.form.HasSpecifiedPermissionFormDTO; import com.epmet.commons.tools.dto.form.LoginUserInfoFormDTO; import com.epmet.commons.tools.dto.form.LoginUserInfoResultDTO; import com.epmet.commons.tools.dto.form.RoleOpeScopeResultDTO; @@ -34,4 +35,12 @@ public interface CommonGovAccessFeignClient { */ @PostMapping("/gov/access/access/roleallopesandscopes/{roleId}") Result> listRoleAllOperationScopesByRoleId(@PathVariable("roleId") String roleId); + + /** + * 用户是否具有指定权限 + * @param form + * @return + */ + @PostMapping("/gov/access/access/hasspecifiedpermission") + Result hasSpecifiedPermission(@RequestBody HasSpecifiedPermissionFormDTO form); } diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonGovAccessFeignClientFallback.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonGovAccessFeignClientFallback.java index a03f87ccc9..feb8af499f 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonGovAccessFeignClientFallback.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/fallback/CommonGovAccessFeignClientFallback.java @@ -1,6 +1,7 @@ package com.epmet.commons.tools.feign.fallback; import com.epmet.commons.tools.constant.ServiceConstant; +import com.epmet.commons.tools.dto.form.HasSpecifiedPermissionFormDTO; import com.epmet.commons.tools.dto.form.LoginUserInfoFormDTO; import com.epmet.commons.tools.dto.form.LoginUserInfoResultDTO; import com.epmet.commons.tools.dto.form.RoleOpeScopeResultDTO; @@ -30,4 +31,9 @@ public class CommonGovAccessFeignClientFallback implements CommonGovAccessFeignC public Result> listRoleAllOperationScopesByRoleId(@PathVariable("roleId") String roleId){ return ModuleUtils.feignConError(ServiceConstant.GOV_ACCESS_SERVER, "listRoleAllOperationScopesByRoleId", roleId); } + + @Override + public Result hasSpecifiedPermission(HasSpecifiedPermissionFormDTO form) { + return ModuleUtils.feignConError(ServiceConstant.GOV_ACCESS_SERVER, "hasSpecifiedPermission", form); + } } diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java index 3670e1f9a6..4732f4f32f 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java @@ -204,13 +204,4 @@ public class RedisKeys { public static String getRoleAllOpeScopesKey(String roleId) { return rootPrefix.concat("gov:access:role:allopescopes:").concat(roleId); } - - /** - * 角色ID对应的权限配置 - * @param roleId - * @return - */ - public static String getRoleAccessSettingKey(String roleId, String operationKey) { - return rootPrefix.concat(String.format("gov:access:role:accesssettings:%s:%s", roleId, operationKey)); - } } diff --git a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/AccessConfigSettingFormDTO.java b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/AccessConfigOptionsFormDTO.java similarity index 86% rename from epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/AccessConfigSettingFormDTO.java rename to epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/AccessConfigOptionsFormDTO.java index 58193ec816..b96e438e0b 100644 --- a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/AccessConfigSettingFormDTO.java +++ b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/AccessConfigOptionsFormDTO.java @@ -5,7 +5,7 @@ import lombok.Data; import javax.validation.constraints.NotBlank; @Data -public class AccessConfigSettingFormDTO { +public class AccessConfigOptionsFormDTO { @NotBlank(message = "角色ID不能为空") private String roleId; diff --git a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/AccessConfigSaveSettingDTO.java b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/AccessConfigSaveConfigDTO.java similarity index 89% rename from epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/AccessConfigSaveSettingDTO.java rename to epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/AccessConfigSaveConfigDTO.java index 6a9f46c010..6a918b5bb2 100644 --- a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/AccessConfigSaveSettingDTO.java +++ b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/AccessConfigSaveConfigDTO.java @@ -6,7 +6,7 @@ import javax.validation.constraints.NotBlank; import java.util.Set; @Data -public class AccessConfigSaveSettingDTO { +public class AccessConfigSaveConfigDTO { @NotBlank(message = "角色ID不能为空") private String roleId; diff --git a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/GetSQLFilterFormDTO.java b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/GetSQLFilterFormDTO.java new file mode 100644 index 0000000000..4a63754bd7 --- /dev/null +++ b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/GetSQLFilterFormDTO.java @@ -0,0 +1,28 @@ +package com.epmet.dto.form; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class GetSQLFilterFormDTO { + + @NotBlank + private String operationKey; + + @NotBlank + private String userId; + + @NotBlank + private String app; + + @NotBlank + private String client; + + private String tableAlias; + + private String gridId; + + private String departmentId; + +} diff --git a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/HasSpecifiedPermissionFormDTO.java b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/HasSpecifiedPermissionFormDTO.java new file mode 100644 index 0000000000..4dabc98dd0 --- /dev/null +++ b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/form/HasSpecifiedPermissionFormDTO.java @@ -0,0 +1,22 @@ +package com.epmet.dto.form; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class HasSpecifiedPermissionFormDTO { + + @NotBlank + private String operationKey; + + @NotBlank + private String userId; + + @NotBlank + private String app; + + @NotBlank + private String client; + +} diff --git a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/AccessConfigOptionsResultDTO.java b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/AccessConfigOptionsResultDTO.java index 55d965ae05..4959a3af40 100644 --- a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/AccessConfigOptionsResultDTO.java +++ b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/AccessConfigOptionsResultDTO.java @@ -7,5 +7,4 @@ import java.util.List; @Data public class AccessConfigOptionsResultDTO { private List scopeOptions; - private List settingOptions; } diff --git a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/AccessConfigSettingResultDTO.java b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/AccessConfigSettingResultDTO.java deleted file mode 100644 index 150a02a49f..0000000000 --- a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/AccessConfigSettingResultDTO.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.epmet.dto.result; - -import lombok.Data; - -@Data -public class AccessConfigSettingResultDTO { - - private String settingKey; - private String settingName; - private String roleId; - private Boolean assigned; - private String operationKey; - -} diff --git a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/RoleOpeScopeResultDTO.java b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/RoleOpeScopeResultDTO.java index db971dcbb2..d950f7dc85 100644 --- a/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/RoleOpeScopeResultDTO.java +++ b/epmet-module/gov-access/gov-access-client/src/main/java/com/epmet/dto/result/RoleOpeScopeResultDTO.java @@ -30,4 +30,7 @@ public class RoleOpeScopeResultDTO { */ private String scopeIndex; + private String series; + private Integer sort; + } diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/bean/OpeScopeFilterResultBean.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/bean/OpeScopeFilterResultBean.java new file mode 100644 index 0000000000..fbe1b38052 --- /dev/null +++ b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/bean/OpeScopeFilterResultBean.java @@ -0,0 +1,15 @@ +package com.epmet.bean; + +import lombok.Data; + +import java.util.HashSet; +import java.util.Set; + +@Data +public class OpeScopeFilterResultBean { + + private HashSet orgLevelScopes; + private Set switchScopes; + private boolean allScopes; + +} diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/constant/OperationScopeConstant.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/constant/OperationScopeConstant.java new file mode 100644 index 0000000000..02dd6664ff --- /dev/null +++ b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/constant/OperationScopeConstant.java @@ -0,0 +1,48 @@ +package com.epmet.constant; + +/** + * 操作范围系列常量 + */ +public class OperationScopeConstant { + + /** + * ===================系列=================== + */ + public static final String SERIES_ORG_LEVEL = "org_level"; + public static final String SERIES_SWITCH = "switch"; + public static final String SERIES_ALL = "all"; + + /** + * ===================范围=================== + */ + // 无任何范围限制 + public static final String SCOPE_ALL = "all"; + + // 覆盖机构下的所有范围 + public static final String SCOPE_ORG_ALL = "org_all"; + + //"同级组织的下级" + public static final String SCOPE_ORG_EQUAL_SUB = "org_equal_sub"; + //"同级组织及下级" + public static final String SCOPE_ORG_EQUAL_AND_SUB = "org_equal_and_sub"; + // 同级组织的上级 + public static final String SCOPE_ORG_EQUAL_SUP = "org_equal_sup"; + // 同级组织及上级 + public static final String SCOPE_ORG_EQUAL_AND_SUP = "org_equal_and_sup"; + //"同级组织" + public static final String SCOPE_ORG_EQUAL = "org_equal"; + + //"本组织的下级" + public static final String SCOPE_ORG_CURR_SUB = "org_curr_sub"; + //"本组织及下级" + public static final String SCOPE_ORG_CURR_AND_SUB = "org_curr_and_sub"; + //"本组织" + public static final String SCOPE_ORG_CURR = "org_curr"; + + //我创建的 + public static final String SCOPE_I_CREATED = "i_created"; + //网格内 + public static final String SCOPE_IN_GRID = "in_grid"; + // 部门内 + public static final String SCOPE_IN_DEPARTMENT = "in_department"; +} diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/controller/AccessConfigController.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/controller/AccessConfigController.java index 70436077be..49374b9084 100644 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/controller/AccessConfigController.java +++ b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/controller/AccessConfigController.java @@ -3,15 +3,14 @@ package com.epmet.controller; import com.epmet.commons.tools.utils.Result; import com.epmet.commons.tools.validator.ValidatorUtils; import com.epmet.dto.form.AccessConfigOpesFormDTO; -import com.epmet.dto.form.AccessConfigSaveSettingDTO; -import com.epmet.dto.form.AccessConfigSettingFormDTO; +import com.epmet.dto.form.AccessConfigOptionsFormDTO; +import com.epmet.dto.form.AccessConfigSaveConfigDTO; import com.epmet.dto.result.AccessConfigOpesResultDTO; import com.epmet.dto.result.AccessConfigOptionsResultDTO; import com.epmet.service.AccessConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import javax.validation.constraints.NotBlank; import java.util.List; import java.util.Set; @@ -34,7 +33,7 @@ public class AccessConfigController { } /** - * 保存角色的操作功能列表 + * 保存角色的操作权限列表 * @return */ @PostMapping("saveroleopes") @@ -47,26 +46,25 @@ public class AccessConfigController { * 查询可配置项列表 * @return */ - @PostMapping("settingoptions") - public Result listSettingoptions(@RequestBody AccessConfigSettingFormDTO settingFormDTO) { - ValidatorUtils.validateEntity(settingFormDTO); - AccessConfigOptionsResultDTO options = accessConfigService.listScopeItemsForAccessConfig(settingFormDTO.getRoleId(), settingFormDTO.getOperationKey()); + @PostMapping("configoptions") + public Result listConfigOptions(@RequestBody AccessConfigOptionsFormDTO accessConfigFormDTO) { + ValidatorUtils.validateEntity(accessConfigFormDTO); + AccessConfigOptionsResultDTO options = accessConfigService.listScopeOptionsForAccessConfig(accessConfigFormDTO.getRoleId(), accessConfigFormDTO.getOperationKey()); return new Result().ok(options); } /** * 保存设置 - * @param settings + * @param config * @return */ - @PostMapping("savesettings") - public Result saveSettings(@RequestBody AccessConfigSaveSettingDTO settings) { - ValidatorUtils.validateEntity(settings); - String roleId = settings.getRoleId(); - String operationKey = settings.getOperationKey(); - Set scopeKeys = settings.getScopeKeys(); - Set settingKeys = settings.getSettingKeys(); - accessConfigService.saveSettings(roleId, operationKey, scopeKeys, settingKeys); + @PostMapping("saveconfig") + public Result saveSettings(@RequestBody AccessConfigSaveConfigDTO config) { + ValidatorUtils.validateEntity(config); + String roleId = config.getRoleId(); + String operationKey = config.getOperationKey(); + Set scopeKeys = config.getScopeKeys(); + accessConfigService.saveConfig(roleId, operationKey, scopeKeys); return new Result(); } diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/controller/AccessController.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/controller/AccessController.java index caabc26491..74e40a8579 100644 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/controller/AccessController.java +++ b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/controller/AccessController.java @@ -3,9 +3,7 @@ package com.epmet.controller; import com.epmet.commons.tools.security.dto.GovTokenDto; import com.epmet.commons.tools.utils.Result; import com.epmet.commons.tools.validator.ValidatorUtils; -import com.epmet.dto.form.AccessSettingFormDTO; -import com.epmet.dto.form.OperationScopeFormDTO; -import com.epmet.dto.form.StaffPermCacheFormDTO; +import com.epmet.dto.form.*; import com.epmet.dto.result.LoginUserInfoResultDTO; import com.epmet.dto.result.RoleOpeScopeResultDTO; import com.epmet.service.AccessService; @@ -13,7 +11,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; -import java.util.Map; import java.util.Set; /** @@ -91,12 +88,25 @@ public class AccessController { } /** - * 查询角色的权限相关配置(缓存) + * 用户是否具有指定权限 * @return */ - @PostMapping("/accesssettings") - public Result> listAccessSettings(@RequestBody AccessSettingFormDTO accessSettingFormDTO) { - Map settings = accessService.listAccessSettings(accessSettingFormDTO.getRoleId(), accessSettingFormDTO.getOperationKey()); - return new Result>().ok(settings); + @PostMapping("hasspecifiedpermission") + public Result hasSpecifiedPermission(@RequestBody HasSpecifiedPermissionFormDTO form) { + ValidatorUtils.validateEntity(form); + Boolean hasPermission = accessService.hasPermission(form.getOperationKey(), form.getUserId(), form.getApp(), form.getClient()); + return new Result().ok(hasPermission); + } + + /** + * 查询sql过滤片段 + * @param form + * @return + */ + @PostMapping("getSqlFilterSegment") + public Result getSqlFilterSegment(@RequestBody GetSQLFilterFormDTO form) { + ValidatorUtils.validateEntity(form); + String sqlFilterSegment = accessService.getSqlFilterSegment(form); + return new Result().ok(sqlFilterSegment); } } diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/dao/AccessSettingDao.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/dao/AccessSettingDao.java deleted file mode 100644 index 1af564a116..0000000000 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/dao/AccessSettingDao.java +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright 2018 人人开源 https://www.renren.io - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - *

- * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.epmet.dao; - -import com.epmet.commons.mybatis.dao.BaseDao; -import com.epmet.dto.result.AccessConfigSettingResultDTO; -import com.epmet.dto.result.AccessSettingResultDTO; -import com.epmet.entity.AccessSettingEntity; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -import java.util.List; -import java.util.Set; - -/** - * 权限配置 - * - * @author generator generator@elink-cn.com - * @since v1.0.0 2020-04-29 - */ -@Mapper -public interface AccessSettingDao extends BaseDao { - - /** - * 根据角色查询配置列表 - * @param roleId - * @return - */ - List listAccessSettingsByRoleId(@Param("roleId") String roleId, - @Param("operationKey") String operationKey); - - List listSettingOptionsForAccessConfig(@Param("roleId") String roleId, - @Param("operationKey") String operationKey); - - /** - * 删除 - * @param roleId - * @param operationKey - * @param settingKeys2Delete - * @return - */ - int delete(@Param("roleId") String roleId, - @Param("operationKey") String operationKey, - @Param("settingKeys2Delete") Set settingKeys2Delete); - - AccessSettingEntity get(@Param("roleId") String roleId, - @Param("operationKey") String operationKey, - @Param("settingKey") String settingKey); - - /** - * 启用 - * @param roleId - * @param operationKey - * @param settingKey - * @return - */ - int enable(@Param("roleId") String roleId, - @Param("operationKey") String operationKey, - @Param("settingKey") String settingKey); -} \ No newline at end of file diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/dao/AccessSettingOptionsDao.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/dao/AccessSettingOptionsDao.java deleted file mode 100644 index f07c5e1efe..0000000000 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/dao/AccessSettingOptionsDao.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2018 人人开源 https://www.renren.io - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - *

- * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.epmet.dao; - -import com.epmet.commons.mybatis.dao.BaseDao; -import com.epmet.entity.AccessSettingOptionsEntity; -import org.apache.ibatis.annotations.Mapper; - -/** - * 权限配置选项 - * - * @author generator generator@elink-cn.com - * @since v1.0.0 2020-04-29 - */ -@Mapper -public interface AccessSettingOptionsDao extends BaseDao { - -} \ No newline at end of file diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/dao/RoleScopeDao.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/dao/RoleScopeDao.java index 361bd033d4..3199a78e3d 100644 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/dao/RoleScopeDao.java +++ b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/dao/RoleScopeDao.java @@ -19,7 +19,6 @@ package com.epmet.dao; import com.epmet.commons.mybatis.dao.BaseDao; import com.epmet.dto.result.AccessConfigScopeResultDTO; -import com.epmet.dto.result.AccessConfigSettingResultDTO; import com.epmet.entity.RoleScopeEntity; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/entity/AccessSettingEntity.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/entity/AccessSettingEntity.java deleted file mode 100644 index 076476fcfa..0000000000 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/entity/AccessSettingEntity.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright 2018 人人开源 https://www.renren.io - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - *

- * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.epmet.entity; - -import com.baomidou.mybatisplus.annotation.TableName; - -import com.epmet.commons.mybatis.entity.BaseEpmetEntity; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.Date; - -/** - * 权限配置 - * - * @author generator generator@elink-cn.com - * @since v1.0.0 2020-04-29 - */ -@Data -@EqualsAndHashCode(callSuper=false) -@TableName("access_setting") -public class AccessSettingEntity extends BaseEpmetEntity { - - private static final long serialVersionUID = 1L; - - /** - * 角色ID - */ - private String roleId; - - /** - * 操作key - */ - private String operationKey; - - /** - * 配置KEY - */ - private String settingKey; - - /** - * 配置值 - */ - private String settingValue; - -} diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/entity/AccessSettingOptionsEntity.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/entity/AccessSettingOptionsEntity.java deleted file mode 100644 index 49fb16db01..0000000000 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/entity/AccessSettingOptionsEntity.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright 2018 人人开源 https://www.renren.io - *

- * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - *

- * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.epmet.entity; - -import com.baomidou.mybatisplus.annotation.TableName; - -import com.epmet.commons.mybatis.entity.BaseEpmetEntity; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.Date; - -/** - * 权限配置选项 - * - * @author generator generator@elink-cn.com - * @since v1.0.0 2020-04-29 - */ -@Data -@EqualsAndHashCode(callSuper=false) -@TableName("access_setting_options") -public class AccessSettingOptionsEntity extends BaseEpmetEntity { - - private static final long serialVersionUID = 1L; - - /** - * 配置KEY - */ - private String settingKey; - - /** - * 配置name - */ - private String settingName; - - /** - * 简介 - */ - private String brief; - -} diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/entity/OperationScopeEntity.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/entity/OperationScopeEntity.java index 2fd6b18361..2c7223d97d 100644 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/entity/OperationScopeEntity.java +++ b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/entity/OperationScopeEntity.java @@ -48,4 +48,8 @@ public class OperationScopeEntity extends BaseEpmetEntity { */ private String scopeName; + private String scopeIndex; + private String series; + private Integer sort; + } diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/redis/RoleAccessSettingRedis.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/redis/RoleAccessSettingRedis.java deleted file mode 100644 index c188cf2566..0000000000 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/redis/RoleAccessSettingRedis.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.epmet.redis; - -import com.epmet.commons.tools.redis.RedisKeys; -import com.epmet.commons.tools.redis.RedisUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -@Component -public class RoleAccessSettingRedis { - - @Autowired - private RedisUtils redisUtils; - - public void set(Map settings, String roleId, String operationKey) { - // 转化Map - HashMap newSettings = new HashMap<>(); - Set> entries = settings.entrySet(); - entries.forEach(entry -> { - newSettings.put(entry.getKey(), entry.getValue()); - }); - - String roleAccessSettingKey = RedisKeys.getRoleAccessSettingKey(roleId, operationKey); - redisUtils.hMSet(roleAccessSettingKey, newSettings); - } - - public Map get(String roleId, String operationKey) { - String roleAccessSettingKey = RedisKeys.getRoleAccessSettingKey(roleId, operationKey); - Map s = redisUtils.hGetAll(roleAccessSettingKey); - // 转化Map - if (!CollectionUtils.isEmpty(s)) { - Map settings = new HashMap<>(); - s.forEach((s1, o) -> { - if (o != null) { - settings.put(s1, String.valueOf(o)); - } - }); - return settings; - } - - return null; - } - - public void delete(String roleId, String operationKey) { - redisUtils.delete(RedisKeys.getRoleAccessSettingKey(roleId, operationKey)); - } - -} diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/AccessConfigService.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/AccessConfigService.java index 19e7421d6e..e6dfec5878 100644 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/AccessConfigService.java +++ b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/AccessConfigService.java @@ -11,7 +11,7 @@ public interface AccessConfigService { void saveRoleOpes(String roleId, List opes); - AccessConfigOptionsResultDTO listScopeItemsForAccessConfig(String roleId, String operationKey); + AccessConfigOptionsResultDTO listScopeOptionsForAccessConfig(String roleId, String operationKey); - void saveSettings(String roleId, String operationKey, Set scopeKeys, Set settingKeys); + void saveConfig(String roleId, String operationKey, Set scopeKeys); } diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/AccessService.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/AccessService.java index 7e976d3e65..8ba649e51d 100644 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/AccessService.java +++ b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/AccessService.java @@ -1,6 +1,7 @@ package com.epmet.service; import com.epmet.commons.tools.security.dto.GovTokenDto; +import com.epmet.dto.form.GetSQLFilterFormDTO; import com.epmet.dto.result.RoleOpeScopeResultDTO; import java.util.List; @@ -30,16 +31,23 @@ public interface AccessService { Set listOperationScopesByRoleId(String roleId, String operationKey); /** - * 查询角色的权限相关配置 + * 查询角色所有operation及其范围(缓存) * @param roleId * @return */ - Map listAccessSettings(String roleId, String operationKey); + List listAllRoleOperationScopesByRoleId(String roleId); /** - * 查询角色所有operation及其范围(缓存) - * @param roleId + * 角色 + * @param operationKey + * @param userId * @return */ - List listAllRoleOperationScopesByRoleId(String roleId); + Boolean hasPermission(String operationKey, String userId, String app, String client); + + /** + * 生成sql过滤脚本 + * @param form + */ + String getSqlFilterSegment(GetSQLFilterFormDTO form); } diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/impl/AccessConfigServiceImpl.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/impl/AccessConfigServiceImpl.java index cc39398289..78594a96fd 100644 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/impl/AccessConfigServiceImpl.java +++ b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/impl/AccessConfigServiceImpl.java @@ -1,14 +1,11 @@ package com.epmet.service.impl; -import com.epmet.commons.tools.constant.AccessSettingConstant; import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.RenException; import com.epmet.dao.*; import com.epmet.dto.result.*; -import com.epmet.entity.AccessSettingEntity; import com.epmet.entity.RoleOperationEntity; import com.epmet.entity.RoleScopeEntity; -import com.epmet.redis.RoleAccessSettingRedis; import com.epmet.redis.RoleOpeScopeRedis; import com.epmet.service.AccessConfigService; import org.slf4j.Logger; @@ -36,12 +33,6 @@ public class AccessConfigServiceImpl implements AccessConfigService { @Autowired private RoleScopeDao roleScopeDao; - @Autowired - private AccessSettingDao accessSettingDao; - - @Autowired - private RoleAccessSettingRedis roleAccessSettingRedis; - @Override public List listOpesByRole(String roleId) { return roleOperationDao.listOpesForAccessConfig(roleId); @@ -84,70 +75,18 @@ public class AccessConfigServiceImpl implements AccessConfigService { } @Override - public AccessConfigOptionsResultDTO listScopeItemsForAccessConfig(String roleId, String operationKey) { + public AccessConfigOptionsResultDTO listScopeOptionsForAccessConfig(String roleId, String operationKey) { List scopeOptions = roleScopeDao.listScopeOptionsForAccessConfig(roleId, operationKey); - List settingOptions = accessSettingDao.listSettingOptionsForAccessConfig(roleId, operationKey); + //List settingOptions = accessSettingDao.listSettingOptionsForAccessConfig(roleId, operationKey); AccessConfigOptionsResultDTO options = new AccessConfigOptionsResultDTO(); options.setScopeOptions(scopeOptions); - options.setSettingOptions(settingOptions); + //options.setSettingOptions(settingOptions); return options; } @Override @Transactional - public void saveSettings(String roleId, String operationKey, Set scopeKeys, Set settingKeys) { - saveScopeSettings(roleId, operationKey, scopeKeys); - saveAccessSettingSettings(roleId, operationKey, settingKeys); - } - - /** - * 保存设置 - * 可以优化为:遍历时候直接删除或者新增,而不用新建settingKeys2Delete, settingKeys2Add变量 - * @param roleId - * @param operationKey - */ - private void saveAccessSettingSettings(String roleId, String operationKey, Set newSettingKeys) { - Set settingKeysDB = accessSettingDao.listAccessSettingsByRoleId(roleId, operationKey) - .stream() - .map(setting -> setting.getSettingKey()) - .collect(Collectors.toSet()); - - Set settingKeys2Delete = settingKeysDB.stream().filter(settingKeyDB -> !newSettingKeys.contains(settingKeyDB)).collect(Collectors.toSet()); - Set settingKeys2Add = newSettingKeys.stream().filter(newSetting -> !settingKeysDB.contains(newSetting)).collect(Collectors.toSet()); - - // 删除 - if (!CollectionUtils.isEmpty(settingKeys2Delete)) { - accessSettingDao.delete(roleId, operationKey, settingKeys2Delete); - } - - // 新增 - if (!CollectionUtils.isEmpty(settingKeys2Add)) { - settingKeys2Add.forEach(settingKey -> { - if (accessSettingDao.get(roleId, operationKey, settingKey) != null) { - // 数据库中已有 - accessSettingDao.enable(roleId, operationKey, settingKey); - } else { - AccessSettingEntity newSetting = new AccessSettingEntity(); - newSetting.setRoleId(roleId); - newSetting.setOperationKey(operationKey); - newSetting.setSettingKey(settingKey); - newSetting.setSettingValue(AccessSettingConstant.ON); - accessSettingDao.insert(newSetting); - } - }); - } - - // 清空redis缓存 - roleAccessSettingRedis.delete(roleId, operationKey); - } - - /** - * 保存Scope设置 - * @param roleId - * @param operationKey - * @param scopeKeys - */ - private void saveScopeSettings(String roleId, String operationKey, Set scopeKeys) { + public void saveConfig(String roleId, String operationKey, Set scopeKeys) { List scopesDB = roleScopeDao.listScopeEntities(roleId, operationKey); // 数据库中已有的scopeKey列表 Set scopeKeysDB = scopesDB.stream().map(scope -> scope.getScopeKey()).collect(Collectors.toSet()); diff --git a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/impl/AccessServiceImpl.java b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/impl/AccessServiceImpl.java index 37a5dfd305..ee246fe87d 100644 --- a/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/impl/AccessServiceImpl.java +++ b/epmet-module/gov-access/gov-access-server/src/main/java/com/epmet/service/impl/AccessServiceImpl.java @@ -1,15 +1,20 @@ package com.epmet.service.impl; +import cn.hutool.core.collection.CollectionUtil; +import com.epmet.bean.OpeScopeFilterResultBean; +import com.epmet.commons.tools.constant.OpeScopeConstant; +import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.ExceptionUtils; +import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.security.dto.GovTokenDto; import com.epmet.commons.tools.utils.CpUserDetailRedis; -import com.epmet.dao.AccessSettingDao; +import com.epmet.constant.OperationScopeConstant; import com.epmet.dao.OperationScopeDao; -import com.epmet.dto.result.AccessSettingResultDTO; +import com.epmet.dto.form.GetSQLFilterFormDTO; import com.epmet.dto.result.RoleOpeScopeResultDTO; -import com.epmet.redis.RoleAccessSettingRedis; import com.epmet.redis.RoleOpeScopeRedis; import com.epmet.service.AccessService; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -17,28 +22,27 @@ import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.util.*; +import java.util.stream.Collectors; @Service public class AccessServiceImpl implements AccessService { private static Logger logger = LoggerFactory.getLogger(AccessServiceImpl.class); + /** + * 线程变量,记录是否已经添加了至少一个过滤条件 + */ + private static final ThreadLocal hasConditions = new ThreadLocal(); + @Autowired private CpUserDetailRedis cpUserDetailRedis; @Autowired private OperationScopeDao operationScopeDao; - @Autowired - private AccessSettingDao accessSettingDao; - @Autowired private RoleOpeScopeRedis roleOpeScopeRedis; - @Autowired - private RoleAccessSettingRedis roleAccessSettingRedis; - - /** * 更新权限缓存 * @param staffId @@ -90,38 +94,333 @@ public class AccessServiceImpl implements AccessService { return scopes; } + @Override + public List listAllRoleOperationScopesByRoleId(String roleId) { + List roleAllOpeScopes = roleOpeScopeRedis.getRoleAllOpeScopes(roleId); + if (roleAllOpeScopes == null) { + roleAllOpeScopes = operationScopeDao.listAllRoleOperationScopesByRoleId(roleId); + roleOpeScopeRedis.setRoleAllOpeScopes(roleId, roleAllOpeScopes); + } + return roleAllOpeScopes; + } + + @Override + public Boolean hasPermission(String operationKey, String userId, String app, String client) { + GovTokenDto userDetails = getUserDetails(app, client, userId); + if (userDetails == null) { + return false; + } + Set roleIdList = userDetails.getRoleIdList(); + if (CollectionUtils.isEmpty(roleIdList)) { + return false; + } + + final Set operationKeys = new HashSet<>(); + + roleIdList.stream().forEach(roleId -> { + List opeAndScopes = listAllRoleOperationScopesByRoleId(roleId); + operationKeys.addAll(opeAndScopes.stream().map(opeAndScope -> opeAndScope.getOperationKey()).collect(Collectors.toSet())); + }); + + if (operationKeys.contains(operationKey)) { + return true; + } + return false; + } + + @Override + public String getSqlFilterSegment(GetSQLFilterFormDTO form) { + hasConditions.set(false); + GovTokenDto userDetails = getUserDetails(form.getApp(), form.getClient(), form.getUserId()); + if (userDetails == null) { + logger.error("查询SQL过滤脚本:没有找到用户的登陆信息:app: {}, client: {}, userId:{}", form.getApp(), form.getClient(), form.getUserId()); + throw new RenException(EpmetErrorCode.ERR10006.getCode()); + } + + StringBuilder sb = new StringBuilder(); + + if (CollectionUtils.isEmpty(userDetails.getRoleIdList())) { + //logger.warn("用户{}没有配置任何角色,无法执行{}操作", form.getUserId(), form.getOperationKey()); + throw new RenException(String.format("用户%s没有配置任何角色,无法执行%s操作", form.getUserId(), form.getOperationKey())); + } + + OpeScopeFilterResultBean effectiveOpeScopes = getEffectiveOpeScopes(userDetails.getRoleIdList(), form.getOperationKey()); + if (effectiveOpeScopes.isAllScopes()) { + return sb.toString(); + } + + HashSet orgLevelScopes = effectiveOpeScopes.getOrgLevelScopes(); + Set switchScopes = effectiveOpeScopes.getSwitchScopes(); + + // 生成组织上下级关系系列的sql过滤片段 + if (!CollectionUtil.isEmpty(orgLevelScopes) && !orgLevelScopes.contains(OpeScopeConstant.ORG_ALL)) { + genOrgLevelScopeSqlFilter(sb, orgLevelScopes, userDetails.getOrgIdPath(), form.getTableAlias()); + } + + // 生成开关范围的sql过滤器 + if (!CollectionUtil.isEmpty(switchScopes)) { + genSwitchScopeSqlFilter(switchScopes, sb, form.getTableAlias(), userDetails.getUserId(), form.getGridId(), form.getDepartmentId()); + } + + return sb.toString(); + } + /** - * 查询角色的权限相关配置 - * @param roleId + * 生成开关系列范围sql过滤片段 + * @param switchScopes + */ + private void genSwitchScopeSqlFilter(Set switchScopes, + StringBuilder sb, + String tableAlias, + String userId, + String gridId, + String departmentId) { + + if (switchScopes.contains(OperationScopeConstant.SCOPE_I_CREATED)) { + genICreatedSql(sb, userId, tableAlias); + } + + if (switchScopes.contains(OperationScopeConstant.SCOPE_IN_GRID)) { + if (StringUtils.isBlank(gridId)) { + String error = String.format("DataFilter:拼接SQL语句出错:需要in grid权限,但是代码中没有获取到,GridId:%s", gridId); + logger.error(error); + throw new RenException(error); + } + genInGrid(sb, gridId, tableAlias); + } + + if (switchScopes.contains(OperationScopeConstant.SCOPE_IN_DEPARTMENT)) { + if (StringUtils.isBlank(departmentId)) { + String error = String.format("DataFilter:拼接SQL语句出错:需要in department权限,但是代码中没有获取到, departmentId:%s", departmentId); + logger.error(error); + throw new RenException(error); + } + genDepartmentFilterSql(sb, departmentId, tableAlias); + } + } + + /** + * sql:我发起的 + * + * @param userId + */ + private void genICreatedSql(StringBuilder sb, String userId, String tableAlias) { + if (StringUtils.isBlank(tableAlias)) { + sb.append(hasConditions.get() ? " OR " : " ").append(" CREATED_BY ='").append(userId).append("'"); + } else { + sb.append(hasConditions.get() ? " OR " : " ").append(tableAlias).append(".CREATED_BY ='").append(userId).append("'"); + } + hasConditions.set(true); + } + + /** + * 网格sql + * + * @param sb + * @param tableAlias + */ + private void genInGrid(StringBuilder sb, String gridId, String tableAlias) { + if (hasConditions.get()) { + // 之前没有条件 + sb.append(" OR "); + } + + // OR GRID_ID = 'XXX' OR GRID_ID = 'QQQ' + if (StringUtils.isBlank(tableAlias)) { + sb.append(" GRID_ID = '").append(gridId).append("' "); + } else { + sb.append(" ").append(tableAlias).append(".GRID_ID ='").append(gridId).append("' "); + } + hasConditions.set(true); + } + + /** + * 生成部门过滤sql + * + * @param sb + */ + private void genDepartmentFilterSql(StringBuilder sb, String deptId, String tableAlias) { + //Result> deptListResult = govOrgFeignClient.getDepartmentListByStaffId(staffId); + if (hasConditions.get()) { + // 之前没有条件 + sb.append(" OR "); + } + if (StringUtils.isBlank(tableAlias)) { + sb.append(" DEPARTMENT_ID = '").append(deptId).append("' "); + } else { + sb.append(" ").append(tableAlias).append(".DEPARTMENT_ID ='").append(deptId).append("' "); + } + hasConditions.set(true); + } + + /** + * 计算有效操作范围 + */ + public OpeScopeFilterResultBean getEffectiveOpeScopes(Set roleIds, String reqiurePermission) { + + // 根据角色列表查询操作范围列表 + Set opeAndScopesOfThisOperation = new HashSet<>(); + roleIds.forEach(roleId -> { + List opes = listAllRoleOperationScopesByRoleId(roleId); + if (!CollectionUtils.isEmpty(opes)) { + opes.forEach(ope -> { + if (reqiurePermission.equals(ope.getOperationKey())) { + // 拿到当前操作对应的 RoleOpeScopeResultDTO + opeAndScopesOfThisOperation.add(ope); + } + }); + } + }); + + // 过滤范围 + return filteAndGroupScopes(opeAndScopesOfThisOperation); + } + + /** + * 对范围进行过滤和分组 + * + * @param scopeDTOS * @return */ - @Override - public Map listAccessSettings(String roleId, String operationKey) { - Map settings = roleAccessSettingRedis.get(roleId, operationKey); - if (settings == null) { - settings = new HashMap<>(); - // 数据库查出来,放入redis一份。此处为权限过滤器用到 - List accessSettingDtos = accessSettingDao.listAccessSettingsByRoleId(roleId, operationKey); - if (!CollectionUtils.isEmpty(accessSettingDtos)) { - for (AccessSettingResultDTO setting : accessSettingDtos) { - settings.put(setting.getSettingKey(), setting.getSettingValue()); + private OpeScopeFilterResultBean filteAndGroupScopes(Set scopeDTOS) { + // 存储上下级关系系列范围。先放到Map是为了去重和中途判断 + HashMap orgLevelScopes = new HashMap<>(); + + // 存储开关系列范围 + Set switchScopes = new HashSet<>(); + + // 所有范围 + Boolean all = false; + + for (RoleOpeScopeResultDTO scope : scopeDTOS) { + + if (OpeScopeConstant.ALL.equals(scope.getScopeKey())) { + all = true; + break; + } + + if (OperationScopeConstant.SERIES_SWITCH.equals(scope.getSeries())) { + switchScopes.add(scope.getScopeKey()); + continue; + } + + String scopeIndex = scope.getScopeIndex(); + if (OpeScopeConstant.ORG_ALL.equals(scope.getScopeKey())) { + // 该操作具有org_all的权限,直接放入 + orgLevelScopes.put(scopeIndex, scope); + continue; + } + + String[] currArr = scopeIndex.split("_"); + if ("0".equals(currArr[1])) { + // 为0,说明没有包含关系,直接放入 + orgLevelScopes.put(scopeIndex, scope); + continue; + } + + RoleOpeScopeResultDTO tempScope = orgLevelScopes.get(currArr[0]); + if (tempScope != null) { + // 已经有ac开头的了 + String tempScopeIndex = tempScope.getScopeIndex(); + if (Integer.valueOf(currArr[1]) < Integer.valueOf(tempScopeIndex.split("_")[1])) { + orgLevelScopes.put(currArr[0], scope); } } else { - // 占位,否则空map存不到redis中 - settings.put("-", "-"); + orgLevelScopes.put(currArr[0], scope); } - roleAccessSettingRedis.set(settings, roleId, operationKey); } - return settings; + HashSet scopeStrs = new HashSet<>(); + Set> entries = orgLevelScopes.entrySet(); + for (Map.Entry entry : entries) { + scopeStrs.add(entry.getValue().getScopeKey()); + } + OpeScopeFilterResultBean resultBean = new OpeScopeFilterResultBean(); + resultBean.setOrgLevelScopes(scopeStrs); + resultBean.setSwitchScopes(switchScopes); + resultBean.setAllScopes(all); + return resultBean; } - @Override - public List listAllRoleOperationScopesByRoleId(String roleId) { - List roleAllOpeScopes = roleOpeScopeRedis.getRoleAllOpeScopes(roleId); - if (roleAllOpeScopes == null) { - roleAllOpeScopes = operationScopeDao.listAllRoleOperationScopesByRoleId(roleId); - roleOpeScopeRedis.setRoleAllOpeScopes(roleId, roleAllOpeScopes); + /** + * 生成组织上下级关系系列的sql过滤片段 + * @param sb + * @param orgIdPath + * @param tableAlias + * @return + */ + private void genOrgLevelScopeSqlFilter(StringBuilder sb, HashSet scopes, String orgIdPath, String tableAlias) { + // 取出父组织ID path 和当前组织ID + //String parentOrgIDPath = orgIdPath.substring(0, orgIdPath.lastIndexOf(orgIdPathSpliter)); + //String currOrgID = orgIdPath.substring(orgIdPath.lastIndexOf(orgIdPathSpliter) + 1); + + for (String scope : scopes) { + switch (scope) { + // 当前单位(可以用ORG_ID_PATH,也可以用ORG_ID判断) + case OpeScopeConstant.ORG_CURR: + if (StringUtils.isBlank(tableAlias)) { + sb.append(" ORG_ID_PATH = '").append(orgIdPath).append("' OR "); + //sb.append(" ORG_ID = '").append(currOrgID).append("' OR "); + } else { + sb.append(" ").append(tableAlias).append(".ORG_ID_PATH = '").append(orgIdPath).append("' OR "); + //sb.append(" ").append(tableAlias).append(".ORG_ID = '").append(currOrgID).append("' OR "); + } + break; + // 本单位及其子级单位 + case OpeScopeConstant.ORG_CURR_AND_SUB: + if (StringUtils.isBlank(tableAlias)) { + sb.append(" ORG_ID_PATH like '").append(orgIdPath).append("%' OR "); + } else { + sb.append(" ").append(tableAlias).append(".ORG_ID_PATH like '").append(orgIdPath).append("%' OR "); + } + break; + // 本单位的子级单位 + case OpeScopeConstant.ORG_CURR_SUB: + if (StringUtils.isBlank(tableAlias)) { + sb.append(" ORG_ID_PATH like '").append(orgIdPath).append(":%' OR "); + } else { + sb.append(" ").append(tableAlias).append(".ORG_ID_PATH like '").append(orgIdPath).append(":%' OR "); + } + break; + //当前单位的父级单位 + case OpeScopeConstant.ORG_CURR_SUP: + if (StringUtils.isBlank(tableAlias)) { + sb.append(" '").append(orgIdPath).append("' like CONCAT(").append("ORG_ID_PATH,':%') OR "); + } else { + sb.append(" '").append(orgIdPath).append("' like CONCAT(").append(tableAlias).append(".ORG_ID_PATH,':%') OR "); + } + break; + // 当前单位及其父级单位 + case OpeScopeConstant.ORG_CURR_AND_SUP: + if (StringUtils.isBlank(tableAlias)) { + sb.append(" '").append(orgIdPath).append("' like CONCAT(").append("ORG_ID_PATH,'%') OR "); + } else { + sb.append(" '").append(orgIdPath).append("' like CONCAT(").append(tableAlias).append(".ORG_ID_PATH,'%' ) OR "); + } + break; + case OpeScopeConstant.ORG_EQUAL: + // todo 同级 + //sb.append(" OR "); + break; + case OpeScopeConstant.ORG_EQUAL_AND_SUB: + // todo 同级及其子级 + //sb.append(" OR "); + break; + case OpeScopeConstant.ORG_EQUAL_SUB: + // todo 同级的子级 + //sb.append(" OR "); + break; + case OpeScopeConstant.ORG_EQUAL_AND_SUP: + // todo 同级及其上级 + //sb.append(" OR "); + break; + case OpeScopeConstant.ORG_EQUAL_SUP: + // todo 同级的上级 + //sb.append(" OR "); + break; + } } - return roleAllOpeScopes; + + sb.replace(sb.lastIndexOf("OR"), sb.lastIndexOf("OR") + 3, ""); + hasConditions.set(true); } } diff --git a/epmet-module/gov-access/gov-access-server/src/main/resources/mapper/AccessSettingDao.xml b/epmet-module/gov-access/gov-access-server/src/main/resources/mapper/AccessSettingDao.xml deleted file mode 100644 index 1449da2fc0..0000000000 --- a/epmet-module/gov-access/gov-access-server/src/main/resources/mapper/AccessSettingDao.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - DELETE - FROM access_setting - WHERE ROLE_ID = #{roleId} - AND OPERATION_KEY = #{operationKey} - AND SETTING_KEY IN - - #{settingKey} - - - - - - - - UPDATE access_setting s - SET DEL_FLAG = 0 - WHERE s.ROLE_ID = #{roleId} - AND s.OPERATION_KEY = #{operationKey} - AND s.SETTING_KEY = #{settingKey} - - \ No newline at end of file diff --git a/epmet-module/gov-access/gov-access-server/src/main/resources/mapper/AccessSettingOptionsDao.xml b/epmet-module/gov-access/gov-access-server/src/main/resources/mapper/AccessSettingOptionsDao.xml deleted file mode 100644 index bce8884f0f..0000000000 --- a/epmet-module/gov-access/gov-access-server/src/main/resources/mapper/AccessSettingOptionsDao.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/epmet-module/gov-access/gov-access-server/src/main/resources/mapper/OperationScopeDao.xml b/epmet-module/gov-access/gov-access-server/src/main/resources/mapper/OperationScopeDao.xml index 89a3256e3e..c1772b7c54 100644 --- a/epmet-module/gov-access/gov-access-server/src/main/resources/mapper/OperationScopeDao.xml +++ b/epmet-module/gov-access/gov-access-server/src/main/resources/mapper/OperationScopeDao.xml @@ -7,6 +7,9 @@ + + + @@ -29,7 +32,7 @@ diff --git a/epmet-module/gov-access/gov-access-server/src/test/java/com/epmet/test/govaccess/AccessSettingTest.java b/epmet-module/gov-access/gov-access-server/src/test/java/com/epmet/test/govaccess/AccessSettingTest.java deleted file mode 100644 index c40e1c2463..0000000000 --- a/epmet-module/gov-access/gov-access-server/src/test/java/com/epmet/test/govaccess/AccessSettingTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.epmet.test.govaccess; - -import com.epmet.dao.AccessSettingDao; -import com.epmet.dto.result.AccessSettingResultDTO; -import com.epmet.redis.RoleAccessSettingRedis; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class AccessSettingTest { - - @Autowired - private AccessSettingDao roleAccessSettingDao; - - @Autowired - private RoleAccessSettingRedis roleAccessSettingRedis; - - @Test - public void addAccessSettings2Redis() { - List settings = roleAccessSettingDao.listAccessSettingsByRoleId("1", "org_staff_list"); - HashMap objectObjectHashMap = new HashMap<>(); - settings.forEach(setting -> { - objectObjectHashMap.put(setting.getSettingKey(), setting.getSettingValue()); - }); - roleAccessSettingRedis.set(objectObjectHashMap, "1", "org_staff_list"); - Map map = roleAccessSettingRedis.get("1", "org_staff_list"); - System.out.println(map); - } - -}