Skip to content

Commit 92c396c

Browse files
committed
请求参数校验:REFUSE 新增支持 !key 排除禁止字段,优化 MUST 和 REFUSE 处理性能
1 parent 0e2b645 commit 92c396c

File tree

1 file changed

+65
-28
lines changed

1 file changed

+65
-28
lines changed

APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public abstract class AbstractVerifier<T extends Object> implements Verifier<T>,
103103

104104
// 共享 STRUCTURE_MAP 则不能 remove 等做任何变更,否则在并发情况下可能会出错,加锁效率又低,所以这里改为忽略对应的 key
105105
public static Map<String, Entry<String, Object>> ROLE_MAP;
106-
106+
107107
public static List<String> OPERATION_KEY_LIST;
108108

109109
// <TableName, <METHOD, allowRoles>>
@@ -129,7 +129,7 @@ public abstract class AbstractVerifier<T extends Object> implements Verifier<T>,
129129
ROLE_MAP.put(CIRCLE, new Entry<String, Object>("userId-()", "verifyCircle()")); // "userId{}", "circleIdList")); // 还是 {"userId":"currentUserId", "userId{}": "contactIdList", "@combine": "userId,userId{}" } ?
130130
ROLE_MAP.put(OWNER, new Entry<String, Object>("userId", "userId"));
131131
ROLE_MAP.put(ADMIN, new Entry<String, Object>("userId-()", "verifyAdmin()"));
132-
132+
133133
OPERATION_KEY_LIST = new ArrayList<>();
134134
OPERATION_KEY_LIST.add(TYPE.name());
135135
OPERATION_KEY_LIST.add(VERIFY.name());
@@ -204,7 +204,7 @@ public String getIdKey(String database, String schema, String datasource, String
204204
public String getUserIdKey(String database, String schema, String datasource, String table) {
205205
return apijson.JSONObject.KEY_USER_ID;
206206
}
207-
207+
208208
@SuppressWarnings("unchecked")
209209
@Override
210210
public T newId(RequestMethod method, String database, String schema, String datasource, String table) {
@@ -247,7 +247,7 @@ public boolean verifyAccess(SQLConfig config) throws Exception {
247247
if (table == null) {
248248
return true;
249249
}
250-
250+
251251
String role = config.getRole();
252252
if (role == null) {
253253
role = UNKNOWN;
@@ -265,10 +265,10 @@ public boolean verifyAccess(SQLConfig config) throws Exception {
265265

266266
RequestMethod method = config.getMethod();
267267
verifyRole(config, table, method, role);
268-
268+
269269
return true;
270270
}
271-
271+
272272
@Override
273273
public void verifyRole(SQLConfig config, String table, RequestMethod method, String role) throws Exception {
274274
verifyAllowRole(config, table, method, role); //验证允许的角色
@@ -289,15 +289,15 @@ public void verifyAllowRole(SQLConfig config, String table, RequestMethod method
289289
if (table == null) {
290290
table = config == null ? null : config.getTable();
291291
}
292-
292+
293293
if (table != null) {
294294
if (method == null) {
295295
method = config == null ? GET : config.getMethod();
296296
}
297297
if (role == null) {
298298
role = config == null ? UNKNOWN : config.getRole();
299299
}
300-
300+
301301
Map<RequestMethod, String[]> map = ACCESS_MAP.get(table);
302302

303303
if (map == null || Arrays.asList(map.get(method)).contains(role) == false) {
@@ -329,7 +329,7 @@ public void verifyUseRole(SQLConfig config, String table, RequestMethod method,
329329
if (role == null) {
330330
role = config == null ? UNKNOWN : config.getRole();
331331
}
332-
332+
333333
Object requestId;
334334
switch (role) {
335335
case LOGIN://verifyRole通过就行
@@ -882,11 +882,15 @@ public static <T extends Object> JSONObject parse(@NotNull final RequestMethod m
882882

883883
// 判断必要字段是否都有<<<<<<<<<<<<<<<<<<<
884884
String[] musts = StringUtil.split(must);
885-
List<String> mustList = musts == null ? new ArrayList<String>() : Arrays.asList(musts);
886-
for (String s : mustList) {
887-
if (real.get(s) == null) { // 可能传null进来,这里还会通过 real.containsKey(s) == false) {
888-
throw new IllegalArgumentException(method + "请求," + name
889-
+ " 里面不能缺少 " + s + " 等[" + must + "]内的任何字段!");
885+
Set<String> mustSet = new HashSet<String>();
886+
887+
if (musts != null && musts.length > 0) {
888+
for (String s : musts) {
889+
if (real.get(s) == null) { // 可能传null进来,这里还会通过 real.containsKey(s) == false) {
890+
throw new IllegalArgumentException(method + "请求," + name + " 里面不能缺少 " + s + " 等[" + must + "]内的任何字段!");
891+
}
892+
893+
mustSet.add(s);
890894
}
891895
}
892896
//判断必要字段是否都有>>>>>>>>>>>>>>>>>>>
@@ -947,28 +951,61 @@ public static <T extends Object> JSONObject parse(@NotNull final RequestMethod m
947951
Set<String> rkset = real.keySet(); //解析内容并没有改变rkset
948952

949953
//解析不允许的字段<<<<<<<<<<<<<<<<<<<
950-
List<String> refuseList = new ArrayList<String>();
951-
if ("!".equals(refuse)) {//所有非 must,改成 !must 更好
952-
for (String key : rkset) {//对@key放行,@role,@column,自定义@position等
953-
if (key != null && key.startsWith("@") == false
954-
&& mustList.contains(key) == false && objKeySet.contains(key) == false) {
955-
refuseList.add(key);
954+
String[] refuses = StringUtil.split(refuse);
955+
Set<String> refuseSet = new HashSet<String>();
956+
957+
if (refuses != null && refuses.length > 0) {
958+
Set<String> notRefuseSet = new HashSet<String>();
959+
960+
for (String rfs : refuses) {
961+
if (rfs == null) { // StringUtil.isEmpty(rfs, true) {
962+
continue;
963+
}
964+
965+
if (rfs.startsWith("!")) {
966+
rfs = rfs.substring(1);
967+
968+
if (notRefuseSet.contains(rfs)) {
969+
throw new ConflictException(REFUSE.name() + ":value 中出现了重复的 !" + rfs + " !不允许重复,也不允许一个 key 和取反 !key 同时使用!");
970+
}
971+
if (refuseSet.contains(rfs)) {
972+
throw new ConflictException(REFUSE.name() + ":value 中同时出现了 " + rfs + " 和 !" + rfs + " !不允许重复,也不允许一个 key 和取反 !key 同时使用!");
973+
}
974+
975+
if (rfs.equals("")) { // 所有非 MUST
976+
for (String key : rkset) { // 对@key放行,@role,@column,自定义@position等, @key:{ "Table":{} } 不会解析内部
977+
if (key == null || key.startsWith("@") || notRefuseSet.contains(key) || mustSet.contains(key) || objKeySet.contains(key)) {
978+
continue;
979+
}
980+
981+
refuseSet.add(key);
982+
}
983+
}
984+
else { // 排除 !key 后再禁传其它的
985+
notRefuseSet.add(rfs);
986+
}
987+
}
988+
else {
989+
if (refuseSet.contains(rfs)) {
990+
throw new ConflictException(REFUSE.name() + ":value 中出现了重复的 " + rfs + " !不允许重复,也不允许一个 key 和取反 !key 同时使用!");
991+
}
992+
if (notRefuseSet.contains(rfs)) {
993+
throw new ConflictException(REFUSE.name() + ":value 中同时出现了 " + rfs + " 和 !" + rfs + " !不允许重复,也不允许一个 key 和取反 !key 同时使用!");
994+
}
995+
996+
refuseSet.add(rfs);
956997
}
957-
}
958-
} else {
959-
String[] refuses = StringUtil.split(refuse);
960-
if (refuses != null && refuses.length > 0) {
961-
refuseList.addAll(Arrays.asList(refuses));
962998
}
963999
}
1000+
9641001
//解析不允许的字段>>>>>>>>>>>>>>>>>>>
9651002

9661003

9671004
//判断不允许传的key<<<<<<<<<<<<<<<<<<<<<<<<<
9681005
for (String rk : rkset) {
969-
if (refuseList.contains(rk)) { //不允许的字段
1006+
if (refuseSet.contains(rk)) { //不允许的字段
9701007
throw new IllegalArgumentException(method + "请求," + name
971-
+ " 里面不允许传 " + rk + " 等" + StringUtil.getString(refuseList) + "内的任何字段!");
1008+
+ " 里面不允许传 " + rk + " 等" + StringUtil.getString(refuseSet) + "内的任何字段!");
9721009
}
9731010

9741011
if (rk == null) { //无效的key
@@ -1391,7 +1428,7 @@ private static void verifyCondition(@NotNull String funChar, @NotNull JSONObject
13911428
} finally {
13921429
executor.close();
13931430
}
1394-
1431+
13951432
if (result != null && JSONResponse.isExist(result.getIntValue(JSONResponse.KEY_COUNT)) == false) {
13961433
throw new IllegalArgumentException(rk + ":value 中value不合法!必须匹配 '" + tk + "': '" + tv + "' !");
13971434
}

0 commit comments

Comments
 (0)