作者 朱兆平

brench-update:

1. 转关运抵列表接口增加数据权限过滤-增加列过滤.

Signed-off-by: mrz <17966059@qq.com>
1 package com.tianbo.analysis.intercept; 1 package com.tianbo.analysis.intercept;
2 2
  3 +import com.alibaba.fastjson.JSON;
3 import com.alibaba.fastjson.JSONArray; 4 import com.alibaba.fastjson.JSONArray;
4 import com.alibaba.fastjson.JSONObject; 5 import com.alibaba.fastjson.JSONObject;
5 import com.tianbo.analysis.thread.SessionUserContext; 6 import com.tianbo.analysis.thread.SessionUserContext;
6 import lombok.extern.slf4j.Slf4j; 7 import lombok.extern.slf4j.Slf4j;
7 import net.sf.jsqlparser.expression.Expression; 8 import net.sf.jsqlparser.expression.Expression;
8 import net.sf.jsqlparser.parser.CCJSqlParserUtil; 9 import net.sf.jsqlparser.parser.CCJSqlParserUtil;
  10 +import net.sf.jsqlparser.schema.Column;
9 import net.sf.jsqlparser.schema.Table; 11 import net.sf.jsqlparser.schema.Table;
10 import net.sf.jsqlparser.statement.Statement; 12 import net.sf.jsqlparser.statement.Statement;
11 -import net.sf.jsqlparser.statement.select.Join;  
12 -import net.sf.jsqlparser.statement.select.PlainSelect;  
13 -import net.sf.jsqlparser.statement.select.Select;  
14 -import net.sf.jsqlparser.statement.select.SelectItem; 13 +import net.sf.jsqlparser.statement.select.*;
  14 +import org.apache.commons.lang.StringUtils;
15 import org.apache.ibatis.cache.CacheKey; 15 import org.apache.ibatis.cache.CacheKey;
16 import org.apache.ibatis.executor.Executor; 16 import org.apache.ibatis.executor.Executor;
17 import org.apache.ibatis.mapping.BoundSql; 17 import org.apache.ibatis.mapping.BoundSql;
@@ -25,9 +25,11 @@ import org.apache.ibatis.session.RowBounds; @@ -25,9 +25,11 @@ import org.apache.ibatis.session.RowBounds;
25 import org.springframework.stereotype.Component; 25 import org.springframework.stereotype.Component;
26 26
27 import java.text.SimpleDateFormat; 27 import java.text.SimpleDateFormat;
  28 +import java.util.ArrayList;
28 import java.util.Date; 29 import java.util.Date;
29 import java.util.List; 30 import java.util.List;
30 31
  32 +
31 @Intercepts({ 33 @Intercepts({
32 @Signature(type= Executor.class, 34 @Signature(type= Executor.class,
33 method = "query", 35 method = "query",
@@ -80,16 +82,33 @@ public class DataPermissionInterceptor implements Interceptor { @@ -80,16 +82,33 @@ public class DataPermissionInterceptor implements Interceptor {
80 * todo: 条件值怎么获取? 82 * todo: 条件值怎么获取?
81 */ 83 */
82 String dataScope = "els"; 84 String dataScope = "els";
83 - JSONArray rowPermList = SessionUserContext.getSessionUser();  
84 - //取出来后 清理  
85 - SessionUserContext.clearSessionUser();  
86 - if (rowPermList!=null && !rowPermList.isEmpty()) {  
87 - // 用户配置了数据权限  
88 - //获取该用户所具有的角色的数据权限dataScope  
89 - dataScope = "usr";  
90 - }else {  
91 - //用户未配置数据权限  
92 - dataScope = "*"; 85 + JSONObject user = SessionUserContext.getSessionUser();
  86 + String username = user.getString("username");
  87 + Integer userId = user.getInteger("userId");
  88 + JSONArray dataPermissions = user.getJSONArray("dataPermissions");
  89 + //存储行条件数据权限
  90 + ArrayList<JSONObject> rowConditions = new ArrayList<>();
  91 + JSONArray colConditions = new JSONArray();
  92 +
  93 + if (dataPermissions!=null && !dataPermissions.isEmpty()){
  94 + for (Object item : dataPermissions) {
  95 + JSONObject datapermission = (JSONObject) JSON.toJSON(item);
  96 + /**
  97 + * 一个组织绑定了同一个接口的多个数据权限,循环到这里 会出现 * 条件和 usr条件混乱,
  98 + * 目前 以循环 最后取到的row_condition为准,所以需要保持 数据权限配置数据正确
  99 + */
  100 + dataScope = datapermission.getString("perm_type");
  101 + String colListStr = datapermission.getString("cols_list");
  102 + if (StringUtils.isNotEmpty(colListStr)){
  103 + if ("*".equals(colListStr)) {
  104 + //查询全部列,不改
  105 + }else{
  106 + JSONArray cloArrayList = JSONArray.parseArray(colListStr);
  107 + colConditions.addAll(cloArrayList);
  108 + }
  109 + }
  110 + rowConditions.add(datapermission);
  111 + }
93 } 112 }
94 113
95 String deptsUser= "admin"; 114 String deptsUser= "admin";
@@ -108,6 +127,7 @@ public class DataPermissionInterceptor implements Interceptor { @@ -108,6 +127,7 @@ public class DataPermissionInterceptor implements Interceptor {
108 PlainSelect plain = (PlainSelect) selectStatement.getSelectBody(); 127 PlainSelect plain = (PlainSelect) selectStatement.getSelectBody();
109 //获取所有外连接 128 //获取所有外连接
110 List<Join> joins = plain.getJoins(); 129 List<Join> joins = plain.getJoins();
  130 +
111 //获取到原始sql语句 131 //获取到原始sql语句
112 String sql = processSql; 132 String sql = processSql;
113 StringBuffer whereSql = new StringBuffer(); 133 StringBuffer whereSql = new StringBuffer();
@@ -123,22 +143,22 @@ public class DataPermissionInterceptor implements Interceptor { @@ -123,22 +143,22 @@ public class DataPermissionInterceptor implements Interceptor {
123 case "usr": 143 case "usr":
124 if(joins==null || joins.isEmpty()){ 144 if(joins==null || joins.isEmpty()){
125 String and = " and "; 145 String and = " and ";
126 - for (int i = 0; i < rowPermList.size(); i++) {  
127 - JSONObject o = (JSONObject)rowPermList.get(i); 146 + for (int i = 0; i < rowConditions.size(); i++) {
  147 + JSONObject dataPermission = rowConditions.get(i);
128 if (i==0){ 148 if (i==0){
129 whereSql 149 whereSql
130 //条件字段 150 //条件字段
131 - .append(o.get("colName")) 151 + .append(dataPermission.get("row_condition"))
132 .append(" = ") 152 .append(" = ")
133 // 条件值 153 // 条件值
134 - .append(getSqlValue(o.get("colValue"))); 154 + .append(getSqlValue(user.get(dataPermission.getString("row_condition_property"))));
135 }else { 155 }else {
136 whereSql.append(and) 156 whereSql.append(and)
137 //条件字段 157 //条件字段
138 - .append(o.get("colName")) 158 + .append(dataPermission.get("row_condition"))
139 .append(" = ") 159 .append(" = ")
140 // 条件值 160 // 条件值
141 - .append(getSqlValue(o.get("colValue"))); 161 + .append(getSqlValue(user.get(dataPermission.getString("row_condition_property"))));
142 } 162 }
143 163
144 } 164 }
@@ -189,6 +209,13 @@ public class DataPermissionInterceptor implements Interceptor { @@ -189,6 +209,13 @@ public class DataPermissionInterceptor implements Interceptor {
189 whereSql.append("1=2"); 209 whereSql.append("1=2");
190 break; 210 break;
191 } 211 }
  212 + /**
  213 + * 替换select 节点
  214 + */
  215 + if (!colConditions.isEmpty()){
  216 + List<SelectItem> selectExpressionItems = resetColumn(colConditions);
  217 + plain.setSelectItems(selectExpressionItems);
  218 + }
192 219
193 /** 220 /**
194 * 获取where节点 221 * 获取where节点
@@ -240,4 +267,18 @@ public class DataPermissionInterceptor implements Interceptor { @@ -240,4 +267,18 @@ public class DataPermissionInterceptor implements Interceptor {
240 return value.toString(); 267 return value.toString();
241 } 268 }
242 } 269 }
  270 +
  271 + /**
  272 + * 重新设置select的字段
  273 + * @param newSelectItems 要重设置的字段列表
  274 + * @return 重新设置后的字段列表
  275 + */
  276 + private List<SelectItem> resetColumn(JSONArray newSelectItems){
  277 + List<SelectItem> newSelectExpressionItems = new ArrayList<>();
  278 + for (Object newSelectItem : newSelectItems) {
  279 + SelectItem selectExpressionItem = new SelectExpressionItem(new Column(newSelectItem.toString()));
  280 + newSelectExpressionItems.add(selectExpressionItem);
  281 + }
  282 + return newSelectExpressionItems;
  283 + }
243 } 284 }
1 package com.tianbo.analysis.intercept; 1 package com.tianbo.analysis.intercept;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 -import com.alibaba.fastjson.JSONArray;  
5 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
  5 +import com.tianbo.analysis.exception.TransArriveException;
6 import com.tianbo.analysis.feign.UserCenterAPI; 6 import com.tianbo.analysis.feign.UserCenterAPI;
7 import com.tianbo.analysis.model.ResultJson; 7 import com.tianbo.analysis.model.ResultJson;
8 import com.tianbo.analysis.thread.SessionUserContext; 8 import com.tianbo.analysis.thread.SessionUserContext;
@@ -10,7 +10,6 @@ import lombok.extern.slf4j.Slf4j; @@ -10,7 +10,6 @@ import lombok.extern.slf4j.Slf4j;
10 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.beans.factory.annotation.Autowired;
11 import org.springframework.core.env.Environment; 11 import org.springframework.core.env.Environment;
12 import org.springframework.stereotype.Component; 12 import org.springframework.stereotype.Component;
13 -import org.springframework.util.AntPathMatcher;  
14 import org.springframework.web.servlet.HandlerInterceptor; 13 import org.springframework.web.servlet.HandlerInterceptor;
15 14
16 import javax.annotation.PostConstruct; 15 import javax.annotation.PostConstruct;
@@ -38,65 +37,39 @@ public class UserCenterHanlerInterceptor implements HandlerInterceptor { @@ -38,65 +37,39 @@ public class UserCenterHanlerInterceptor implements HandlerInterceptor {
38 37
39 @Override 38 @Override
40 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 39 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  40 + log.debug("进入HTTPServletRequest 拦截器");
41 String serviceName = _THIS.environment.getProperty("spring.application.name"); 41 String serviceName = _THIS.environment.getProperty("spring.application.name");
42 String permPath = "/" + serviceName + request.getRequestURI(); 42 String permPath = "/" + serviceName + request.getRequestURI();
43 log.info("path = {}, serviceName= {}",request.getRequestURI(),serviceName); 43 log.info("path = {}, serviceName= {}",request.getRequestURI(),serviceName);
44 - AntPathMatcher pathMatcher = new AntPathMatcher();  
45 - boolean match = pathMatcher.match(permPath, request.getRequestURI());  
46 44
47 String authHeader = request.getHeader("Authorization"); 45 String authHeader = request.getHeader("Authorization");
48 if (authHeader != null && authHeader.startsWith("Bearer ")) { 46 if (authHeader != null && authHeader.startsWith("Bearer ")) {
49 47
  48 + /**
  49 + * 根据访问接口地址和token信息获取用户权限信息
  50 + * 参数为request 中的接口地址和的 auth 的token信息
  51 + * 样例实体类如下:
  52 + * todo:后期返回数据 要增加用户所属的同级组织机构的用户列表dep,或者 同公司下的用户列表com
  53 + */
50 ResultJson resultJson = _THIS.userCenterAPI.getDataPerm(permPath, authHeader); 54 ResultJson resultJson = _THIS.userCenterAPI.getDataPerm(permPath, authHeader);
51 if (resultJson.getData()!=null){ 55 if (resultJson.getData()!=null){
52 - 56 + /**
  57 + * 下面JSONObject user为 cloud-user-center中的users类.
  58 + * 为了方便,使用jsonObject进行使用.
  59 + */
  60 + JSONObject user = (JSONObject) JSON.toJSON(resultJson.getData());
  61 + SessionUserContext.setSessionUser(user);
  62 + }else{
  63 + throw new TransArriveException("无用户数据权限获取失败,无法访问");
53 } 64 }
54 - JSONObject user = (JSONObject) JSON.toJSON(resultJson.getData());  
55 log.info(resultJson.toString()); 65 log.info(resultJson.toString());
56 } 66 }
57 67
58 - /**  
59 - * 根据访问接口地址和token信息获取用户权限信息  
60 - * 参数为request 中的接口地址和的 auth 的token信息  
61 - * 样例实体类如下:  
62 - */  
63 -  
64 - String userDataPermJsonDemoStr = "{\n" +  
65 - "\t\"username\":\"nmms\",\n" +  
66 - "\t\"userId\": \"80\",\n" +  
67 - "\t\"userDataPerm\":{\n" +  
68 - "\t\t\"rowCondition\": \"usr\",\n" +  
69 - "\t\t\"rowDataPermConditions\":[\n" +  
70 - "\t\t\t{\n" +  
71 - "\t\t\t\t\"colName\": \"USERNAME\"\n" +  
72 - "\t\t\t},\n" +  
73 - "\t\t\t{\n" +  
74 - "\t\t\t\t\"colName\": \"BILLNO\"\n" +  
75 - "\t\t\t}\n" +  
76 - "\t\t],\n" +  
77 - "\t}\t\n" +  
78 - "}";  
79 - JSONObject userInfo = JSONObject.parseObject(userDataPermJsonDemoStr);  
80 -  
81 -  
82 - JSONObject userDataPerm = userInfo.getJSONObject("userDataPerm");  
83 - String rowCondition = userDataPerm.getString("rowCondition");  
84 - JSONArray rowDataPermConditions = userDataPerm.getJSONArray("rowDataPermConditions");  
85 -  
86 - JSONObject userDataPermModel = new JSONObject();  
87 - userDataPermModel.put("colName","USERNAME");  
88 -  
89 - //获取token中的user的值  
90 - userDataPermModel.put("colValue","nmms");  
91 -// JSONObject userDataPermModel1 = new JSONObject();  
92 -// userDataPermModel1.put("colName","BILLNO");  
93 -// userDataPermModel1.put("colValue","78464771722");  
94 -  
95 - JSONArray userDataPermArray = new JSONArray();  
96 - userDataPermArray.add(userDataPermModel);  
97 -// userDataPermArray.add(userDataPermModel1);  
98 - SessionUserContext.setSessionUser(userDataPermArray);  
99 - log.info("进入HTTPServletRequest 拦截器");  
100 return true; 68 return true;
101 } 69 }
  70 +
  71 + @Override
  72 + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  73 + SessionUserContext.clearSessionUser();
  74 + }
102 } 75 }
1 package com.tianbo.analysis.thread; 1 package com.tianbo.analysis.thread;
2 2
3 -import com.alibaba.fastjson.JSONArray;  
4 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
5 4
6 public class SessionUserContext { 5 public class SessionUserContext {
7 6
8 - private static final ThreadLocal<JSONArray> SESSION_USER_THREAD_LOCAL = new ThreadLocal(); 7 + private static final ThreadLocal<JSONObject> SESSION_USER_THREAD_LOCAL = new ThreadLocal();
9 8
10 - public static void setSessionUser(JSONArray sessionUser){ 9 + public static void setSessionUser(JSONObject sessionUser){
11 SESSION_USER_THREAD_LOCAL.set(sessionUser); 10 SESSION_USER_THREAD_LOCAL.set(sessionUser);
12 } 11 }
13 12
@@ -15,8 +14,8 @@ public class SessionUserContext { @@ -15,8 +14,8 @@ public class SessionUserContext {
15 SESSION_USER_THREAD_LOCAL.remove(); 14 SESSION_USER_THREAD_LOCAL.remove();
16 } 15 }
17 16
18 - public static JSONArray getSessionUser(){  
19 - return (JSONArray) SESSION_USER_THREAD_LOCAL.get(); 17 + public static JSONObject getSessionUser(){
  18 + return (JSONObject) SESSION_USER_THREAD_LOCAL.get();
20 } 19 }
21 20
22 /** 下面可以添加获取用户ID或者用户名的方法例子: 21 /** 下面可以添加获取用户ID或者用户名的方法例子:
@@ -96,25 +96,26 @@ @@ -96,25 +96,26 @@
96 ) t2 ON t1.AUTOID = t2.CLIENTSEQNO 96 ) t2 ON t1.AUTOID = t2.CLIENTSEQNO
97 AND t2.rn = 1 97 AND t2.rn = 1
98 ) t3 98 ) t3
99 - where 1=1  
100 - <if test="customscode != null and customscode != ''" >  
101 - and CustomsCode = #{customscode,jdbcType=VARCHAR}  
102 - </if>  
103 - <if test="username != null and username != ''">  
104 - and USERNAME = #{username,jdbcType=VARCHAR}  
105 - </if>  
106 - <if test="trnmode != null and trnmode != ''" >  
107 - and TrnMode = #{trnmode,jdbcType=VARCHAR}  
108 - </if>  
109 - <if test="unloadcode != null and unloadcode != ''" >  
110 - and UnloadCode = #{unloadcode,jdbcType=VARCHAR}  
111 - </if>  
112 - <if test="billno != null and billno != ''" >  
113 - and BillNo = #{billno,jdbcType=VARCHAR}  
114 - </if>  
115 - <if test="creattimeStart != null and creattimeEnd != null" >  
116 - and CREATTIME between #{creattimeStart,jdbcType=TIMESTAMP} and #{creattimeEnd,jdbcType=TIMESTAMP}  
117 - </if> 99 + <where>
  100 + <if test="customscode != null and customscode != ''" >
  101 + and CustomsCode = #{customscode,jdbcType=VARCHAR}
  102 + </if>
  103 + <if test="username != null and username != ''">
  104 + and USERNAME = #{username,jdbcType=VARCHAR}
  105 + </if>
  106 + <if test="trnmode != null and trnmode != ''" >
  107 + and TrnMode = #{trnmode,jdbcType=VARCHAR}
  108 + </if>
  109 + <if test="unloadcode != null and unloadcode != ''" >
  110 + and UnloadCode = #{unloadcode,jdbcType=VARCHAR}
  111 + </if>
  112 + <if test="billno != null and billno != ''" >
  113 + and BillNo = #{billno,jdbcType=VARCHAR}
  114 + </if>
  115 + <if test="creattimeStart != null and creattimeEnd != null" >
  116 + and CREATTIME between #{creattimeStart,jdbcType=TIMESTAMP} and #{creattimeEnd,jdbcType=TIMESTAMP}
  117 + </if>
  118 + </where>
118 order by CREATTIME desc 119 order by CREATTIME desc
119 </select> 120 </select>
120 <delete id="deleteByPrimaryKey" parameterType="java.lang.String" > 121 <delete id="deleteByPrimaryKey" parameterType="java.lang.String" >