diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/config/WebSocketSessionManager.java b/magic-api/src/main/java/org/ssssssss/magicapi/config/WebSocketSessionManager.java index b9a20f00..2b251a92 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/config/WebSocketSessionManager.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/config/WebSocketSessionManager.java @@ -103,7 +103,11 @@ public class WebSocketSessionManager { public static void sendBySession(MagicConsoleSession session, String content) { try { - session.getWebSocketSession().sendMessage(new TextMessage(content)); + if(session != null){ + synchronized (session.getId()){ + session.getWebSocketSession().sendMessage(new TextMessage(content)); + } + } } catch (IOException e) { logger.error("发送WebSocket消息失败", e); } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/controller/MagicController.java b/magic-api/src/main/java/org/ssssssss/magicapi/controller/MagicController.java index b6bff29c..64150498 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/controller/MagicController.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/controller/MagicController.java @@ -80,7 +80,7 @@ public class MagicController implements JsonCodeConstants { .stream() .flatMap(it -> it.flat().stream()) .filter(it -> !Constants.ROOT_ID.equals(it.getId())) - .filter(it -> allowVisit(request, authorization)) + .filter(it -> allowVisit(request, authorization, it)) .flatMap(it -> service.listFiles(it.getId()).stream()) .filter(it -> allowVisit(request, authorization, it)) .filter(it -> Objects.nonNull(it.getScript())) diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/controller/MagicResourceController.java b/magic-api/src/main/java/org/ssssssss/magicapi/controller/MagicResourceController.java index 958aa054..c242ebfb 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/controller/MagicResourceController.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/controller/MagicResourceController.java @@ -27,7 +27,8 @@ public class MagicResourceController extends MagicController implements MagicExc @PostMapping("/resource/folder/save") @ResponseBody - public JsonBean saveFolder(@RequestBody Group group) { + public JsonBean saveFolder(@RequestBody Group group, HttpServletRequest request) { + isTrue(allowVisit(request, Authorization.SAVE, group), PERMISSION_INVALID); if (service.saveGroup(group)) { return new JsonBean<>(group.getId()); } @@ -36,13 +37,29 @@ public class MagicResourceController extends MagicController implements MagicExc @PostMapping("/resource/folder/copy") @ResponseBody - public JsonBean saveFolder(String src, String target) { + public JsonBean saveFolder(String src, String target, HttpServletRequest request) { + Group srcGroup = service.getGroup(src); + notNull(srcGroup, GROUP_NOT_FOUND); + isTrue(allowVisit(request, Authorization.VIEW, srcGroup), PERMISSION_INVALID); + Group targetGroup = srcGroup.copy(); + targetGroup.setId(null); + targetGroup.setParentId(target); + targetGroup.setType(srcGroup.getType()); + isTrue(allowVisit(request, Authorization.SAVE, targetGroup), PERMISSION_INVALID); return new JsonBean<>(service.copyGroup(src, target)); } @PostMapping("/resource/delete") @ResponseBody public JsonBean delete(String id, HttpServletRequest request) { + Group group = service.getGroup(id); + if(group == null){ + MagicEntity entity = service.file(id); + notNull(entity, FILE_NOT_FOUND); + isTrue(allowVisit(request, Authorization.DELETE, entity), PERMISSION_INVALID); + } else { + isTrue(allowVisit(request, Authorization.DELETE, group), PERMISSION_INVALID); + } return new JsonBean<>(service.delete(id)); } @@ -80,7 +97,19 @@ public class MagicResourceController extends MagicController implements MagicExc @PostMapping("/resource/move") @ResponseBody - public JsonBean move(String src, String groupId) { + public JsonBean move(String src, String groupId, HttpServletRequest request) { + Group group = service.getGroup(src); + if(group == null){ + MagicEntity entity = service.file(src); + notNull(entity, FILE_NOT_FOUND); + entity = entity.copy(); + entity.setGroupId(groupId); + isTrue(allowVisit(request, Authorization.SAVE, entity), PERMISSION_INVALID); + } else { + group = group.copy(); + group.setParentId(groupId); + isTrue(allowVisit(request, Authorization.DELETE, group), PERMISSION_INVALID); + } return new JsonBean<>(service.move(src, groupId)); } @@ -88,6 +117,7 @@ public class MagicResourceController extends MagicController implements MagicExc @ResponseBody public JsonBean lock(String id, HttpServletRequest request) { MagicEntity entity = service.file(id); + notNull(entity, FILE_NOT_FOUND); isTrue(allowVisit(request, Authorization.LOCK, entity), PERMISSION_INVALID); return new JsonBean<>(service.lock(id)); } @@ -96,27 +126,32 @@ public class MagicResourceController extends MagicController implements MagicExc @ResponseBody public JsonBean unlock(String id, HttpServletRequest request) { MagicEntity entity = service.file(id); + notNull(entity, FILE_NOT_FOUND); isTrue(allowVisit(request, Authorization.UNLOCK, entity), PERMISSION_INVALID); return new JsonBean<>(service.unlock(id)); } @GetMapping("/resource") @ResponseBody - public JsonBean>>> resources() { + public JsonBean>>> resources(HttpServletRequest request) { Map> tree = service.tree(); Map>> result = new HashMap<>(); - tree.forEach((key, value) -> result.put(key, process(value))); + tree.forEach((key, value) -> result.put(key, process(value, request))); return new JsonBean<>(result); } - private TreeNode> process(TreeNode groupNode) { + private TreeNode> process(TreeNode groupNode, HttpServletRequest request) { TreeNode> value = new TreeNode<>(); value.setNode(groupNode.getNode()); - groupNode.getChildren().stream().map(this::process).forEach(value::addChild); + groupNode.getChildren().stream() + .filter(it -> allowVisit(request, Authorization.VIEW, it.getNode())) + .map(it -> process(it, request)) + .forEach(value::addChild); if (!Constants.ROOT_ID.equals(groupNode.getNode().getId())) { service .listFiles(groupNode.getNode().getId()) .stream() + .filter(it -> allowVisit(request, Authorization.VIEW, it)) .map(MagicEntity::simple) .map((Function>>) TreeNode::new) .forEach(value::addChild); diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/controller/MagicWorkbenchController.java b/magic-api/src/main/java/org/ssssssss/magicapi/controller/MagicWorkbenchController.java index 7f392592..68886f32 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/controller/MagicWorkbenchController.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/controller/MagicWorkbenchController.java @@ -229,7 +229,8 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @RequestMapping("/download") @Valid(authorization = Authorization.DOWNLOAD) @ResponseBody - public ResponseEntity download(String groupId, @RequestBody(required = false) List resources) throws IOException { + public ResponseEntity download(String groupId, @RequestBody(required = false) List resources, HttpServletRequest request) throws IOException { + isTrue(allowVisit(request, Authorization.DOWNLOAD), PERMISSION_INVALID); ByteArrayOutputStream os = new ByteArrayOutputStream(); magicAPIService.download(groupId, resources, os); if (StringUtils.isBlank(groupId)) { @@ -242,8 +243,9 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @RequestMapping("/upload") @Valid(readonly = false, authorization = Authorization.UPLOAD) @ResponseBody - public JsonBean upload(MultipartFile file, String mode) throws IOException { + public JsonBean upload(MultipartFile file, String mode, HttpServletRequest request) throws IOException { notNull(file, FILE_IS_REQUIRED); + isTrue(allowVisit(request, Authorization.UPLOAD), PERMISSION_INVALID); return new JsonBean<>(magicAPIService.upload(file.getInputStream(), mode)); } @@ -251,7 +253,9 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @ResponseBody @Valid(authorization = Authorization.PUSH) public JsonBean push(@RequestHeader("magic-push-target") String target, @RequestHeader("magic-push-secret-key") String secretKey, - @RequestHeader("magic-push-mode") String mode, @RequestBody List resources) { + @RequestHeader("magic-push-mode") String mode, @RequestBody List resources, + HttpServletRequest request) { + isTrue(allowVisit(request, Authorization.PUSH), PERMISSION_INVALID); return magicAPIService.push(target, secretKey, mode, resources); } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/model/Group.java b/magic-api/src/main/java/org/ssssssss/magicapi/model/Group.java index 9d16dd2d..88dec829 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/model/Group.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/model/Group.java @@ -95,6 +95,19 @@ public class Group extends Attributes { this.options = options; } + public Group copy(){ + Group group = new Group(); + group.setId(this.id); + group.setName(this.name); + group.setType(this.type); + group.setPaths(this.paths); + group.setPath(this.path); + group.setProperties(this.properties); + group.setParentId(this.parentId); + group.setOptions(this.options); + return group; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/model/JsonCodeConstants.java b/magic-api/src/main/java/org/ssssssss/magicapi/model/JsonCodeConstants.java index 607b4ea4..339f79e4 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/model/JsonCodeConstants.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/model/JsonCodeConstants.java @@ -97,8 +97,6 @@ public interface JsonCodeConstants { JsonCode FILE_SAVE_FAILURE = new JsonCode(0, "保存失败,同一组下分组名称不能重复且不能包含特殊字符。"); - JsonCode GROUP_CONFLICT = new JsonCode(-20, "修改分组后,名称或路径会有冲突,请检查!"); - JsonCode PARAMETER_INVALID = new JsonCode(0, "参数验证失败"); JsonCode HEADER_INVALID = new JsonCode(0, "header验证失败"); @@ -109,25 +107,10 @@ public interface JsonCodeConstants { JsonCode FILE_IS_REQUIRED = new JsonCode(0, "请上传文件"); - JsonCode SIGN_IS_INVALID = new JsonCode(0, "签名验证失败"); - - JsonCode UPLOAD_PATH_CONFLICT = new JsonCode(0, "上传后%s路径会有冲突,请检查"); + JsonCode SIGN_IS_INVALID = new JsonCode(0, "签名验证失败,请检查秘钥是否正确"); JsonCode API_NOT_FOUND = new JsonCode(1001, "api not found"); - JsonCode FUNCTION_NOT_FOUND = new JsonCode(1002, "function not found"); - - JsonCode WEBSOCKET_NOT_FOUND = new JsonCode(1003, "websocket not found"); - - JsonCode DATASOURCE_KEY_REQUIRED = new JsonCode(0, "数据源Key不能为空"); - - JsonCode DATASOURCE_KEY_EXISTS = new JsonCode(0, "数据源%s已存在或名称重复"); - - JsonCode DATASOURCE_TYPE_NOT_FOUND = new JsonCode(0, "%s not found"); - JsonCode DATASOURCE_NOT_FOUND = new JsonCode(0, "找不到对应的数据源"); - - JsonCode DATASOURCE_TYPE_NOT_SET = new JsonCode(0, "请设置数据源类型"); - default void notNull(Object value, JsonCode jsonCode) { if (value == null) { throw new InvalidArgumentException(jsonCode); diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/service/MagicResourceService.java b/magic-api/src/main/java/org/ssssssss/magicapi/service/MagicResourceService.java index f2660eea..bae9a73c 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/service/MagicResourceService.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/service/MagicResourceService.java @@ -93,6 +93,8 @@ public interface MagicResourceService { T file(String id); + Group getGroup(String id); + void export(String groupId, List resources, OutputStream os) throws IOException; boolean lock(String id); diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/service/impl/AbstractPathMagicResourceStorage.java b/magic-api/src/main/java/org/ssssssss/magicapi/service/impl/AbstractPathMagicResourceStorage.java index 4deb9606..de376b5e 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/service/impl/AbstractPathMagicResourceStorage.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/service/impl/AbstractPathMagicResourceStorage.java @@ -1,5 +1,6 @@ package org.ssssssss.magicapi.service.impl; +import org.ssssssss.magicapi.model.JsonCodeConstants; import org.ssssssss.magicapi.model.PathMagicEntity; import org.ssssssss.magicapi.provider.MagicResourceStorage; import org.ssssssss.magicapi.service.MagicResourceService; @@ -7,7 +8,7 @@ import org.ssssssss.magicapi.utils.PathUtils; import java.util.Objects; -public abstract class AbstractPathMagicResourceStorage implements MagicResourceStorage { +public abstract class AbstractPathMagicResourceStorage implements MagicResourceStorage, JsonCodeConstants { protected MagicResourceService magicResourceService; @@ -37,4 +38,10 @@ public abstract class AbstractPathMagicResourceStorage resources, OutputStream os) throws IOException { if (StringUtils.isNotBlank(groupId)) { diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/service/impl/FunctionInfoMagicResourceStorage.java b/magic-api/src/main/java/org/ssssssss/magicapi/service/impl/FunctionInfoMagicResourceStorage.java index 52191e3b..3405eac0 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/service/impl/FunctionInfoMagicResourceStorage.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/service/impl/FunctionInfoMagicResourceStorage.java @@ -1,5 +1,6 @@ package org.ssssssss.magicapi.service.impl; +import org.ssssssss.magicapi.model.ApiInfo; import org.ssssssss.magicapi.model.FunctionInfo; public class FunctionInfoMagicResourceStorage extends AbstractPathMagicResourceStorage { @@ -18,4 +19,9 @@ public class FunctionInfoMagicResourceStorage extends AbstractPathMagicResourceS public String buildMappingKey(FunctionInfo info) { return buildMappingKey(info, magicResourceService.getGroupPath(info.getGroupId())); } + + @Override + public void validate(FunctionInfo entity) { + notBlank(entity.getPath(), FUNCTION_PATH_REQUIRED); + } }