Parcourir la source

提供页面按钮权限接口

mxd il y a 5 ans
Parent
commit
405a0681fc

+ 27 - 0
src/main/java/org/ssssssss/magicapi/config/ApiInfo.java

@@ -6,22 +6,49 @@ import java.util.Map;
 
 public class ApiInfo {
 
+	/**
+	 * 接口ID
+	 */
 	private String id;
 
+	/**
+	 * 请求方法
+	 */
 	private String method;
 
+	/**
+	 * 请求路径
+	 */
 	private String path;
 
+	/**
+	 * 脚本内容
+	 */
 	private String script;
 
+	/**
+	 * 接口名称
+	 */
 	private String name;
 
+	/**
+	 * 接口分组名称
+	 */
 	private String groupName;
 
+	/**
+	 * 设置的请求参数
+	 */
 	private String parameter;
 
+	/**
+	 * 设置的接口选项
+	 */
 	private String option;
 
+	/**
+	 * 接口选项json->map
+	 */
 	private Map optionMap;
 
 	public String getId() {

+ 34 - 21
src/main/java/org/ssssssss/magicapi/config/RequestInterceptor.java

@@ -2,31 +2,44 @@ package org.ssssssss.magicapi.config;
 
 import org.ssssssss.script.MagicScriptContext;
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * 请求拦截器
  */
 public interface RequestInterceptor {
 
-    /**
-     * 请求之前执行
-     *
-     * @return 当返回对象时,直接将此对象返回到页面,返回null时,继续执行后续操作
-     * @throws Exception
-     */
-    default Object preHandle(ApiInfo info, MagicScriptContext context) throws Exception {
-        return null;
-    }
-
-
-    /**
-     * 执行完毕之后执行
-     *
-     * @param value 即将要返回到页面的值
-     * @return 返回到页面的对象, 当返回null时执行后续拦截器,否则直接返回该值,不执行后续拦截器
-     * @throws Exception
-     */
-    default Object postHandle(ApiInfo info, MagicScriptContext context, Object value) throws Exception {
-        return null;
-    }
+	enum Authorization {
+		SAVE, DETAIL, RUN, DELETE,
+	}
+
+	/**
+	 * 是否拥有页面按钮的权限
+	 */
+	default boolean allowVisit(HttpServletRequest request, Authorization authorization) {
+		return true;
+	}
+
+	/**
+	 * 请求之前执行
+	 *
+	 * @return 当返回对象时,直接将此对象返回到页面,返回null时,继续执行后续操作
+	 * @throws Exception
+	 */
+	default Object preHandle(ApiInfo info, MagicScriptContext context) throws Exception {
+		return null;
+	}
+
+
+	/**
+	 * 执行完毕之后执行
+	 *
+	 * @param value 即将要返回到页面的值
+	 * @return 返回到页面的对象, 当返回null时执行后续拦截器,否则直接返回该值,不执行后续拦截器
+	 * @throws Exception
+	 */
+	default Object postHandle(ApiInfo info, MagicScriptContext context, Object value) throws Exception {
+		return null;
+	}
 
 }

+ 133 - 15
src/main/java/org/ssssssss/magicapi/config/WebUIController.java

@@ -12,33 +12,59 @@ import org.ssssssss.magicapi.model.JsonBodyBean;
 import org.ssssssss.magicapi.provider.ApiServiceProvider;
 import org.ssssssss.magicapi.provider.MagicAPIService;
 import org.ssssssss.magicapi.provider.ResultProvider;
-import org.ssssssss.script.*;
+import org.ssssssss.script.MagicModuleLoader;
+import org.ssssssss.script.MagicScriptDebugContext;
+import org.ssssssss.script.MagicScriptEngine;
+import org.ssssssss.script.ScriptClass;
 import org.ssssssss.script.exception.MagicScriptAssertException;
 import org.ssssssss.script.exception.MagicScriptException;
 import org.ssssssss.script.parsing.Span;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 public class WebUIController {
 
 	private static Logger logger = LoggerFactory.getLogger(WebUIController.class);
 
+	/**
+	 * debug 超时时间
+	 */
 	private int debugTimeout;
 
+	/**
+	 * 接口映射
+	 */
 	private MappingHandlerMapping mappingHandlerMapping;
 
+	/**
+	 * 接口查询service
+	 */
 	private ApiServiceProvider magicApiService;
 
+	/**
+	 * 自定义结果
+	 */
 	private ResultProvider resultProvider;
 
+	/**
+	 * 拦截器
+	 */
+	private List<RequestInterceptor> requestInterceptors = new ArrayList<>();
+
 	public WebUIController() {
+		// 给前端添加代码提示
 		MagicScriptEngine.addScriptClass(DatabaseQuery.class);
 		MagicScriptEngine.addScriptClass(MagicAPIService.class);
 	}
 
+	public void addRequestInterceptor(RequestInterceptor requestInterceptor) {
+		this.requestInterceptors.add(requestInterceptor);
+	}
+
 	public void setResultProvider(ResultProvider resultProvider) {
 		this.resultProvider = resultProvider;
 	}
@@ -64,12 +90,21 @@ public class WebUIController {
 		System.out.println("                  |___/                        " + WebUIController.class.getPackage().getImplementationVersion());
 	}
 
+	/**
+	 * 删除接口
+	 * @param request
+	 * @param id      接口ID
+	 * @return
+	 */
 	@RequestMapping("/delete")
 	@ResponseBody
-	public JsonBean<Boolean> delete(String id) {
+	public JsonBean<Boolean> delete(HttpServletRequest request, String id) {
+		if (!allowVisit(request, RequestInterceptor.Authorization.DELETE)) {
+			return new JsonBean<>(-10, "无权限执行删除方法");
+		}
 		try {
 			boolean success = this.magicApiService.delete(id);
-			if(success){
+			if (success) {
 				mappingHandlerMapping.unregisterMapping(id);
 			}
 			return new JsonBean<>(success);
@@ -79,12 +114,23 @@ public class WebUIController {
 		}
 	}
 
+	/**
+	 * 删除接口分组
+	 *
+	 * @param request
+	 * @param apiIds    接口ID列表,逗号分隔
+	 * @param groupName 分组名称
+	 * @return
+	 */
 	@RequestMapping("/group/delete")
 	@ResponseBody
-	public JsonBean<Boolean> deleteGroup(String apiIds, String groupName) {
+	public JsonBean<Boolean> deleteGroup(HttpServletRequest request, String apiIds, String groupName) {
+		if (!allowVisit(request, RequestInterceptor.Authorization.DELETE)) {
+			return new JsonBean<>(-10, "无权限执行删除方法");
+		}
 		try {
 			boolean success = this.magicApiService.deleteGroup(groupName);
-			if(success){
+			if (success) {
 				if (StringUtils.isNotBlank(apiIds)) {
 					String[] ids = apiIds.split(",");
 					if (ids != null && ids.length > 0) {
@@ -101,6 +147,11 @@ public class WebUIController {
 		}
 	}
 
+	/**
+	 * 查询所有接口
+	 *
+	 * @return
+	 */
 	@RequestMapping("/list")
 	@ResponseBody
 	public JsonBean<List<ApiInfo>> list() {
@@ -112,6 +163,12 @@ public class WebUIController {
 		}
 	}
 
+	/**
+	 * debug 恢复断点
+	 *
+	 * @param id
+	 * @return
+	 */
 	@RequestMapping("/continue")
 	@ResponseBody
 	public JsonBean<Object> debugContinue(String id) {
@@ -120,11 +177,11 @@ public class WebUIController {
 			return new JsonBean<>(0, "debug session not found!", resultProvider.buildResult(0, "debug session not found!"));
 		}
 		try {
-			context.singal();
+			context.singal();    //等待语句执行到断点或执行完毕
 		} catch (InterruptedException e) {
 			e.printStackTrace();
 		}
-		if (context.isRunning()) {
+		if (context.isRunning()) {    //判断是否执行完毕
 			return new JsonBodyBean<>(1000, context.getId(), resultProvider.buildResult(1000, context.getId()), context.getDebugInfo());
 		} else if (context.isException()) {
 			return resolveThrowable((Throwable) context.getReturnValue());
@@ -132,6 +189,9 @@ public class WebUIController {
 		return new JsonBodyBean<>(resultProvider.buildResult(context.getReturnValue()), context.getReturnValue());
 	}
 
+	/**
+	 * 获取所有class
+	 */
 	@RequestMapping("/classes")
 	@ResponseBody
 	public JsonBean<Map<String, ScriptClass>> classes() {
@@ -140,15 +200,31 @@ public class WebUIController {
 		return new JsonBean<>(classMap);
 	}
 
+	/**
+	 * 获取单个class
+	 *
+	 * @param className 类名
+	 * @return
+	 */
 	@RequestMapping("/class")
 	@ResponseBody
 	public JsonBean<List<ScriptClass>> clazz(String className) {
 		return new JsonBean<>(MagicScriptEngine.getScriptClass(className));
 	}
 
+	/**
+	 * 测试运行
+	 *
+	 * @param servletRequest
+	 * @param request        请求参数
+	 * @return
+	 */
 	@RequestMapping("/test")
 	@ResponseBody
-	public JsonBean<Object> test(@RequestBody(required = false) Map<String, Object> request) {
+	public JsonBean<Object> test(HttpServletRequest servletRequest, @RequestBody(required = false) Map<String, Object> request) {
+		if (!allowVisit(servletRequest, RequestInterceptor.Authorization.RUN)) {
+			return new JsonBean<>(-10, "无权限执行测试方法");
+		}
 		Object script = request.get("script");
 		if (script != null) {
 			request.remove("script");
@@ -165,12 +241,12 @@ public class WebUIController {
 				return new JsonBean<>(0, "请求参数填写错误", resultProvider.buildResult(0, "请求参数填写错误"));
 			}
 			try {
-				context.setBreakpoints((List<Integer>) breakpoints);
-				context.setTimeout(this.debugTimeout);
+				context.setBreakpoints((List<Integer>) breakpoints);    //设置断点
+				context.setTimeout(this.debugTimeout);    //设置断点超时时间
 				Object result = MagicScriptEngine.execute(MagicScriptCompiler.compile(script.toString()), context);
-				if (context.isRunning()) {
+				if (context.isRunning()) {    //判断是否执行完毕
 					return new JsonBodyBean<>(1000, context.getId(), resultProvider.buildResult(1000, context.getId(), result), result);
-				} else if (context.isException()) {
+				} else if (context.isException()) {    //判断是否出现异常
 					return resolveThrowable((Throwable) context.getReturnValue());
 				}
 				return new JsonBean<>(resultProvider.buildResult(result));
@@ -181,6 +257,9 @@ public class WebUIController {
 		return new JsonBean<>(resultProvider.buildResult(0, "脚本不能为空"));
 	}
 
+	/**
+	 * 解决异常
+	 */
 	private JsonBean<Object> resolveThrowable(Throwable root) {
 		MagicScriptException se = null;
 		Throwable parent = root;
@@ -201,9 +280,19 @@ public class WebUIController {
 		return new JsonBean<>(-1, root.getMessage(), resultProvider.buildResult(-1, root.getMessage()));
 	}
 
+	/**
+	 * 查询接口详情
+	 *
+	 * @param request
+	 * @param id      接口ID
+	 * @return
+	 */
 	@RequestMapping("/get")
 	@ResponseBody
-	public JsonBean<ApiInfo> get(String id) {
+	public JsonBean<ApiInfo> get(HttpServletRequest request, String id) {
+		if (!allowVisit(request, RequestInterceptor.Authorization.DETAIL)) {
+			return new JsonBean<>(-10, "无权限执行查看详情方法");
+		}
 		try {
 			return new JsonBean<>(this.magicApiService.get(id));
 		} catch (Exception e) {
@@ -212,9 +301,19 @@ public class WebUIController {
 		}
 	}
 
+	/**
+	 * 保存接口
+	 *
+	 * @param request
+	 * @param info    接口信息
+	 * @return
+	 */
 	@RequestMapping("/save")
 	@ResponseBody
-	public JsonBean<String> save(ApiInfo info) {
+	public JsonBean<String> save(HttpServletRequest request, ApiInfo info) {
+		if (!allowVisit(request, RequestInterceptor.Authorization.SAVE)) {
+			return new JsonBean<>(-10, "无权限执行保存方法");
+		}
 		try {
 			if (StringUtils.isBlank(info.getMethod())) {
 				return new JsonBean<>(0, "请求方法不能为空");
@@ -229,16 +328,19 @@ public class WebUIController {
 				return new JsonBean<>(0, "脚本内容不能为空");
 			}
 			if (StringUtils.isBlank(info.getId())) {
+				// 先判断接口是否存在
 				if (magicApiService.exists(info.getMethod(), info.getPath())) {
 					return new JsonBean<>(0, String.format("接口%s:%s已存在", info.getMethod(), info.getPath()));
 				}
 				magicApiService.insert(info);
 			} else {
+				// 先判断接口是否存在
 				if (magicApiService.existsWithoutId(info.getMethod(), info.getPath(), info.getId())) {
 					return new JsonBean<>(0, String.format("接口%s:%s已存在", info.getMethod(), info.getPath()));
 				}
 				magicApiService.update(info);
 			}
+			// 注册接口
 			mappingHandlerMapping.registerMapping(info);
 			return new JsonBean<>(info.getId());
 		} catch (Exception e) {
@@ -246,4 +348,20 @@ public class WebUIController {
 			return new JsonBean<>(-1, e.getMessage());
 		}
 	}
+
+	/**
+	 * 判断是否有权限访问按钮
+	 *
+	 * @param request
+	 * @param authorization
+	 * @return
+	 */
+	private boolean allowVisit(HttpServletRequest request, RequestInterceptor.Authorization authorization) {
+		for (RequestInterceptor requestInterceptor : requestInterceptors) {
+			if (!requestInterceptor.allowVisit(request, authorization)) {
+				return false;
+			}
+		}
+		return true;
+	}
 }