1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
| @Slf4j public class DataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor {
private static final Map<String, DataScope> DATA_SCOPE_CACHE = new ConcurrentHashMap<>(); private static final Map<String, Method> DATA_SCOPE_METHOD_CACHE = new ConcurrentHashMap<>();
private static final Set<String> IGNORE_METHOD_CACHE = new ConcurrentHashSet<>();
@Override public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { DataScope dataScope = getDataScope(ms.getId()); if (dataScope == null) { return; } PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql); mpBs.sql(parserSingle(mpBs.sql(), ms.getId())); } @Override protected void processSelect(Select select, int index, Object obj) { PlainSelect plainSelect = (PlainSelect) select.getSelectBody(); Expression where = plainSelect.getWhere(); try { final String methodName = "getSqlSegment"; final Class[] methodParmeters = {Expression.class, String.class, DataScope.class, Method.class}; final String mappedStatementId = Func.toStr(obj); DataScope dataScope = getDataScope(mappedStatementId); Class<? extends DataPermissionHandler> handler = Objects.requireNonNull(dataScope).handler(); Method getSqlSegmentMethod = ClassUtil.getDeclaredMethod(handler, methodName, methodParmeters); Assert.notNull(getSqlSegmentMethod, "[%s]未找到处理方法[%s]", handler.getName(), methodName); Method method = DATA_SCOPE_METHOD_CACHE.get(mappedStatementId); Object sqlSegment = ReflectUtil.invoke(Singleton.get(handler), getSqlSegmentMethod, where, mappedStatementId, dataScope, method); if (Func.isNotEmpty(sqlSegment)) { plainSelect.setWhere((Expression) sqlSegment); } } catch (Exception e) { EqualsTo equalsTo = new EqualsTo(); equalsTo.setLeftExpression(new LongValue(1)); equalsTo.setRightExpression(new LongValue(2)); plainSelect.setWhere(equalsTo); throw e; } } private void addAllMethod(List<Class> clazzs, List<Method> allMethods) { if (clazzs == null) { return; } clazzs.forEach(c -> { if (c != null) { allMethods.addAll(Arrays.asList(c.getMethods())); Class[] interfaces = c.getInterfaces(); addAllMethod(Arrays.asList(interfaces), allMethods); } }); }
private DataScope getDataScope(String mappedStatementId) { if(IGNORE_METHOD_CACHE.contains(mappedStatementId)){ return null; } if (DATA_SCOPE_CACHE.containsKey(mappedStatementId)) { return DATA_SCOPE_CACHE.get(mappedStatementId); } String className = StringUtil.subBefore(mappedStatementId, StringPool.DOT, true); String methodName = StringUtil.subAfter(mappedStatementId, StringPool.DOT, true); if (Func.isAnyBlank(className, methodName)) { IGNORE_METHOD_CACHE.add(mappedStatementId); return null; } Class<?> aClass = ClassLoaderUtil.loadClass(Objects.requireNonNull(className)); if (Func.isEmpty(aClass)) { IGNORE_METHOD_CACHE.add(mappedStatementId); return null; } List<Method> allMethods = Lists.newLinkedList(); addAllMethod(Lists.newArrayList(aClass),allMethods); Method method = null; for (Method m : allMethods) { if(Func.equals(m.getName(),methodName)){ method = m; break; } } if (Func.isEmpty(method)) { IGNORE_METHOD_CACHE.add(mappedStatementId); return null; } DataScope annotation = Func.getAnnotation(method, DataScope.class); if(annotation == null){ IGNORE_METHOD_CACHE.add(mappedStatementId); return null; } DATA_SCOPE_CACHE.put(mappedStatementId, annotation); DATA_SCOPE_METHOD_CACHE.put(mappedStatementId, method); return annotation; }
}
|