Skip to content

Commit 30084d9

Browse files
committed
Server: RemoteFunction 内强制校验远程函数必须符合 Function 表的配置;Function 表新增 methods,tag,version 用于限制远程函数的使用范围
1 parent 5810ecf commit 30084d9

File tree

6 files changed

+123
-41
lines changed

6 files changed

+123
-41
lines changed

APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/APIJSONApplication.java

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,44 +42,46 @@ public static void main(String[] args) throws Exception {
4242

4343
System.out.println("\n\n\n\n\n<<<<<<<<<<<<<<<<<<<<<<<<< APIJSON 开始启动 >>>>>>>>>>>>>>>>>>>>>>>>\n");
4444

45-
System.out.println("开始测试:远程函数 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
45+
System.out.println("\n\n\n开始初始化:远程函数配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
4646
try {
47-
DemoFunction.test();
47+
DemoFunction.init(true);
4848
}
4949
catch (Exception e) {
5050
e.printStackTrace();
5151
}
52-
System.out.println("\n完成测试:远程函数 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
53-
54-
55-
System.out.println("\n\n\n开始测试:请求校验 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
52+
System.out.println("\n完成初始化:远程函数配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
53+
54+
System.out.println("开始测试:远程函数 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
5655
try {
57-
StructureUtil.test();
56+
DemoFunction.test();
5857
}
5958
catch (Exception e) {
6059
e.printStackTrace();
6160
}
62-
System.out.println("\n完成测试:请求校验 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
61+
System.out.println("\n完成测试:远程函数 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
62+
6363

6464

65-
System.out.println("\n\n\n开始初始化:远程函数配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
65+
System.out.println("\n\n\n开始初始化:请求校验配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
6666
try {
67-
DemoFunction.init(true);
67+
StructureUtil.init(true);
6868
}
6969
catch (Exception e) {
7070
e.printStackTrace();
7171
}
72-
System.out.println("\n完成初始化:远程函数配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
73-
74-
System.out.println("\n\n\n开始初始化:请求校验配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
72+
System.out.println("\n完成初始化:请求校验配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
73+
74+
System.out.println("\n\n\n开始测试:请求校验 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
7575
try {
76-
StructureUtil.init(true);
76+
StructureUtil.test();
7777
}
7878
catch (Exception e) {
7979
e.printStackTrace();
8080
}
81-
System.out.println("\n完成初始化:请求校验配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
82-
81+
System.out.println("\n完成测试:请求校验 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
82+
83+
84+
8385
System.out.println("\n\n\n开始初始化:权限校验配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
8486
try {
8587
DemoVerifier.init(true);

APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/DemoFunction.java

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,9 @@
4545
public class DemoFunction extends RemoteFunction {
4646
private static final String TAG = "DemoFunction";
4747

48-
private final RequestMethod method;
4948
private final HttpSession session;
50-
public DemoFunction(RequestMethod method, HttpSession session) {
51-
this.method = method;
49+
public DemoFunction(RequestMethod method, String tag, int version, HttpSession session) {
50+
super(method, tag, version);
5251
this.session = session;
5352
}
5453

@@ -78,11 +77,11 @@ public static void test() throws Exception {
7877
request.put("object", object);
7978

8079

81-
Log.i(TAG, "plus(1,-2) = " + new DemoFunction(null, null).invoke("plus(i0,i1)", request));
82-
Log.i(TAG, "count([1,2,4,10]) = " + new DemoFunction(null, null).invoke("countArray(array)", request));
83-
Log.i(TAG, "isContain([1,2,4,10], 10) = " + new DemoFunction(null, null).invoke("isContain(array,id)", request));
84-
Log.i(TAG, "getFromArray([1,2,4,10], 0) = " + new DemoFunction(null, null).invoke("getFromArray(array,@position)", request));
85-
Log.i(TAG, "getFromObject({key:true}, key) = " + new DemoFunction(null, null).invoke("getFromObject(object,key)", request));
80+
Log.i(TAG, "plus(1,-2) = " + new DemoFunction(null, null, 1, null).invoke("plus(i0,i1)", request));
81+
Log.i(TAG, "count([1,2,4,10]) = " + new DemoFunction(null, null, 1, null).invoke("countArray(array)", request));
82+
Log.i(TAG, "isContain([1,2,4,10], 10) = " + new DemoFunction(null, null, 1, null).invoke("isContain(array,id)", request));
83+
Log.i(TAG, "getFromArray([1,2,4,10], 0) = " + new DemoFunction(null, null, 1, null).invoke("getFromArray(array,@position)", request));
84+
Log.i(TAG, "getFromObject({key:true}, key) = " + new DemoFunction(null, null, 1, null).invoke("getFromObject(object,key)", request));
8685

8786
}
8887

@@ -112,7 +111,7 @@ public static JSONObject init(boolean shutdownWhenServerError) throws ServerExce
112111
request.putAll(functionItem.toArray(0, 0, FUNCTION_));
113112
} //Function[]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
114113

115-
114+
116115
JSONObject response = new DemoParser(RequestMethod.GET, true).parseResponse(request);
117116
if (JSONResponse.isSuccess(response) == false) {
118117
onServerError("\n\n\n\n\n !!!! 查询远程函数异常 !!!\n" + response.getString(JSONResponse.KEY_MSG) + "\n\n\n\n\n", shutdownWhenServerError);
@@ -135,15 +134,28 @@ public static JSONObject init(boolean shutdownWhenServerError) throws ServerExce
135134
if (demo == null) {
136135
onServerError("字段 demo 的值必须为合法且非 null 的 JSONObejct 字符串!", shutdownWhenServerError);
137136
}
137+
String name = item.getString("name");
138138
if (demo.containsKey("result()") == false) {
139-
demo.put("result()", getFunctionCall(item.getString("name"), item.getString("arguments")));
139+
demo.put("result()", getFunctionCall(name, item.getString("arguments")));
140140
}
141-
demo.put(JSONRequest.KEY_COLUMN, "id,name,arguments,demo");
141+
// demo.put(JSONRequest.KEY_TAG, item.getString(JSONRequest.KEY_TAG));
142+
// demo.put(JSONRequest.KEY_VERSION, item.getInteger(JSONRequest.KEY_VERSION));
143+
144+
FUNCTION_MAP.put(name, item); //必须在测试 invoke 前!
145+
146+
String[] methods = StringUtil.split(item.getString("methods"));
147+
JSONObject r = new DemoParser(
148+
methods == null || methods.length <= 0 ? RequestMethod.GET : RequestMethod.valueOf(methods[0])
149+
, true
150+
)
151+
.setTag(item.getString(JSONRequest.KEY_TAG))
152+
.setVersion(item.getInteger(JSONRequest.KEY_VERSION))
153+
.parseResponse(demo);
142154

143-
JSONObject r = new DemoParser(RequestMethod.GET, true).parseResponse(demo);
144155
if (JSONResponse.isSuccess(r) == false) {
145156
onServerError(JSONResponse.getMsg(r), shutdownWhenServerError);
146157
}
158+
147159
}
148160

149161
return response;
@@ -223,10 +235,6 @@ public Object verifyURLList(@NotNull JSONObject request, @NotNull String urlList
223235
* @throws Exception
224236
*/
225237
public int deleteCommentOfMoment(@NotNull JSONObject rq, @NotNull String momentId) throws Exception {
226-
if (method != RequestMethod.DELETE) {
227-
throw new UnsupportedOperationException("远程函数 deleteCommentOfMoment 只支持 DELETE 方法!");
228-
}
229-
230238
long mid = rq.getLongValue(momentId);
231239
if (mid <= 0 || rq.getIntValue(JSONResponse.KEY_COUNT) <= 0) {
232240
return 0;
@@ -254,10 +262,6 @@ public int deleteCommentOfMoment(@NotNull JSONObject rq, @NotNull String momentI
254262
* @return
255263
*/
256264
public int deleteChildComment(@NotNull JSONObject rq, @NotNull String toId) throws Exception {
257-
if (method != RequestMethod.DELETE) { //TODO 如果这样的判断太多,可以把 DemoFunction 分成对应不同 RequestMethod 的 GetFunciton 等,创建时根据 method 判断用哪个
258-
throw new UnsupportedOperationException("远程函数 deleteChildComment 只支持 DELETE 方法!");
259-
}
260-
261265
long tid = rq.getLongValue(toId);
262266
if (tid <= 0 || rq.getIntValue(JSONResponse.KEY_COUNT) <= 0) {
263267
return 0;

APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/DemoParser.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
package apijson.demo.server;
1616

17-
import java.util.List;
1817
import java.util.Map;
1918
import java.util.Set;
2019

@@ -25,10 +24,7 @@
2524
import zuo.biao.apijson.RequestMethod;
2625
import zuo.biao.apijson.server.AbstractParser;
2726
import zuo.biao.apijson.server.JSONRequest;
28-
import zuo.biao.apijson.server.Join;
2927
import zuo.biao.apijson.server.SQLConfig;
30-
import zuo.biao.apijson.server.SQLExecutor;
31-
import zuo.biao.apijson.server.exception.NotExistException;
3228

3329

3430
/**请求解析器
@@ -98,7 +94,7 @@ public JSONObject parseResponse(JSONObject request) {
9894
@Override
9995
public Object onFunctionParse(JSONObject json, String fun) throws Exception {
10096
if (function == null) {
101-
function = new DemoFunction(requestMethod, session);
97+
function = new DemoFunction(requestMethod, tag, version, session);
10298
}
10399
return function.invoke(fun, json);
104100
}

APIJSON-Java-Server/APIJSONORM/src/main/java/zuo/biao/apijson/server/AbstractParser.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,28 @@ public AbstractParser<T> setMethod(RequestMethod method) {
120120
this.transactionIsolation = RequestMethod.isQueryMethod(method) ? Connection.TRANSACTION_NONE : Connection.TRANSACTION_REPEATABLE_READ;
121121
return this;
122122
}
123+
124+
protected int version;
125+
@Override
126+
public int getVersion() {
127+
return version;
128+
}
129+
@Override
130+
public AbstractParser<T> setVersion(int version) {
131+
this.version = version;
132+
return this;
133+
}
134+
135+
protected String tag;
136+
@Override
137+
public String getTag() {
138+
return tag;
139+
}
140+
@Override
141+
public AbstractParser<T> setTag(String tag) {
142+
this.tag = tag;
143+
return this;
144+
}
123145

124146
protected JSONObject requestObject;
125147
@Override
@@ -571,6 +593,8 @@ public JSONObject parseCorrectRequest() throws Exception {
571593
if (StringUtil.isNotEmpty(tag, true) == false) {
572594
throw new IllegalArgumentException("请在最外层设置tag!一般是Table名,例如 \"tag\": \"User\" ");
573595
}
596+
setTag(tag);
597+
574598
int version = requestObject.getIntValue(JSONRequest.KEY_VERSION);
575599

576600
JSONObject object = null;

APIJSON-Java-Server/APIJSONORM/src/main/java/zuo/biao/apijson/server/Parser.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ public interface Parser<T> {
4747
RequestMethod getMethod();
4848
Parser<T> setMethod(@NotNull RequestMethod method);
4949

50+
int getVersion();
51+
Parser<T> setVersion(int version);
52+
53+
String getTag();
54+
Parser<T> setTag(String tag);
55+
5056
JSONObject getRequest();
5157
Parser<T> setRequest(JSONObject request);
5258

APIJSON-Java-Server/APIJSONORM/src/main/java/zuo/biao/apijson/server/RemoteFunction.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,18 @@
1515
package zuo.biao.apijson.server;
1616

1717
import java.lang.reflect.InvocationTargetException;
18+
import java.util.Arrays;
19+
import java.util.HashMap;
20+
import java.util.List;
21+
import java.util.Map;
1822

1923
import javax.activation.UnsupportedDataTypeException;
2024

2125
import com.alibaba.fastjson.JSONArray;
2226
import com.alibaba.fastjson.JSONObject;
2327

2428
import zuo.biao.apijson.NotNull;
29+
import zuo.biao.apijson.RequestMethod;
2530
import zuo.biao.apijson.StringUtil;
2631

2732
/**可远程调用的函数类
@@ -30,6 +35,32 @@
3035
public class RemoteFunction {
3136
// private static final String TAG = "RemoteFunction";
3237

38+
// <methodName, JSONObject>
39+
// <isContain, <arguments:"array,key", tag:null, methods:null>>
40+
public static final Map<String, JSONObject> FUNCTION_MAP;
41+
static {
42+
FUNCTION_MAP = new HashMap<>();
43+
}
44+
45+
private final RequestMethod method;
46+
private final String tag;
47+
private final int version;
48+
public RemoteFunction(RequestMethod method, String tag, int version) {
49+
this.method = method == null ? RequestMethod.GET : method;
50+
this.tag = tag;
51+
this.version = version;
52+
}
53+
54+
public RequestMethod getMethod() {
55+
return method;
56+
}
57+
public String getTag() {
58+
return tag;
59+
}
60+
public int getVersion() {
61+
return version;
62+
}
63+
3364
/**反射调用
3465
* @param fun
3566
* @param request
@@ -39,6 +70,25 @@ public class RemoteFunction {
3970
public static Object invoke(@NotNull RemoteFunction fun, @NotNull JSONObject request, @NotNull String function) throws Exception {
4071

4172
FunctionBean fb = parseFunction(function, request, false);
73+
74+
JSONObject row = FUNCTION_MAP.get(fb.getMethod());
75+
if (row == null) {
76+
throw new UnsupportedOperationException("不允许调用远程函数 " + fb.getMethod() + " !");
77+
}
78+
79+
int v = row.getIntValue("version");
80+
if (v < fun.getVersion()) {
81+
throw new UnsupportedOperationException("不允许 version = " + fun.getVersion() + " 的请求调用远程函数 " + fb.getMethod() + " ! 必须满足 version >= " + v + " !");
82+
}
83+
String t = row.getString("tag");
84+
if (t != null && t.equals(fun.getTag()) == false) {
85+
throw new UnsupportedOperationException("不允许 tag = " + fun.getTag() + " 的请求调用远程函数 " + fb.getMethod() + " ! 必须满足 tag = " + t + " !");
86+
}
87+
String[] methods = StringUtil.split(row.getString("methods"));
88+
List<String> ml = methods == null || methods.length <= 0 ? null : Arrays.asList(methods);
89+
if (ml != null && ml.contains(fun.getMethod().toString()) == false) {
90+
throw new UnsupportedOperationException("不允许 method = " + fun.getMethod() + " 的请求调用远程函数 " + fb.getMethod() + " ! 必须满足 method 在 " + methods + "内 !");
91+
}
4292

4393
try {
4494
return invoke(fun, fb.getMethod(), fb.getTypes(), fb.getValues());

0 commit comments

Comments
 (0)