mirror of
https://gitee.com/ssssssss-team/magic-api.git
synced 2026-06-01 03:21:25 +08:00
权限校验
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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()))
|
||||
|
||||
@@ -27,7 +27,8 @@ public class MagicResourceController extends MagicController implements MagicExc
|
||||
|
||||
@PostMapping("/resource/folder/save")
|
||||
@ResponseBody
|
||||
public JsonBean<String> saveFolder(@RequestBody Group group) {
|
||||
public JsonBean<String> 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<String> saveFolder(String src, String target) {
|
||||
public JsonBean<String> 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<Boolean> 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<Boolean> move(String src, String groupId) {
|
||||
public JsonBean<Boolean> 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<Boolean> 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<Boolean> 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<Map<String, TreeNode<Attributes<Object>>>> resources() {
|
||||
public JsonBean<Map<String, TreeNode<Attributes<Object>>>> resources(HttpServletRequest request) {
|
||||
Map<String, TreeNode<Group>> tree = service.tree();
|
||||
Map<String, TreeNode<Attributes<Object>>> 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<Attributes<Object>> process(TreeNode<Group> groupNode) {
|
||||
private TreeNode<Attributes<Object>> process(TreeNode<Group> groupNode, HttpServletRequest request) {
|
||||
TreeNode<Attributes<Object>> 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<MagicEntity, TreeNode<Attributes<Object>>>) TreeNode::new)
|
||||
.forEach(value::addChild);
|
||||
|
||||
@@ -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<SelectedResource> resources) throws IOException {
|
||||
public ResponseEntity<?> download(String groupId, @RequestBody(required = false) List<SelectedResource> 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<Boolean> upload(MultipartFile file, String mode) throws IOException {
|
||||
public JsonBean<Boolean> 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<SelectedResource> resources) {
|
||||
@RequestHeader("magic-push-mode") String mode, @RequestBody List<SelectedResource> resources,
|
||||
HttpServletRequest request) {
|
||||
isTrue(allowVisit(request, Authorization.PUSH), PERMISSION_INVALID);
|
||||
return magicAPIService.push(target, secretKey, mode, resources);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,6 +95,19 @@ public class Group extends Attributes<Object> {
|
||||
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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -93,6 +93,8 @@ public interface MagicResourceService {
|
||||
|
||||
<T extends MagicEntity> T file(String id);
|
||||
|
||||
Group getGroup(String id);
|
||||
|
||||
void export(String groupId, List<SelectedResource> resources, OutputStream os) throws IOException;
|
||||
|
||||
boolean lock(String id);
|
||||
|
||||
@@ -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<T extends PathMagicEntity> implements MagicResourceStorage<T> {
|
||||
public abstract class AbstractPathMagicResourceStorage<T extends PathMagicEntity> implements MagicResourceStorage<T>, JsonCodeConstants {
|
||||
|
||||
|
||||
protected MagicResourceService magicResourceService;
|
||||
@@ -37,4 +38,10 @@ public abstract class AbstractPathMagicResourceStorage<T extends PathMagicEntity
|
||||
String fullGroupPath = magicResourceService.getGroupPath(entity.getGroupId());
|
||||
return PathUtils.replaceSlash(String.format("/%s/%s(/%s/%s)", fullGroupName, entity.getName(), fullGroupPath, entity.getPath()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(T entity) {
|
||||
notBlank(entity.getPath(), REQUEST_PATH_REQUIRED);
|
||||
notBlank(entity.getScript(), SCRIPT_REQUIRED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,4 +19,9 @@ public class ApiInfoMagicResourceStorage extends AbstractPathMagicResourceStorag
|
||||
return info.getMethod().toUpperCase() + ":" + buildMappingKey(info, magicResourceService.getGroupPath(info.getGroupId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(ApiInfo entity) {
|
||||
notBlank(entity.getMethod(), REQUEST_METHOD_REQUIRED);
|
||||
super.validate(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -560,6 +560,11 @@ public class DefaultMagicResourceService implements MagicResourceService, JsonCo
|
||||
return (T) fileCache.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group getGroup(String id) {
|
||||
return groupCache.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void export(String groupId, List<SelectedResource> resources, OutputStream os) throws IOException {
|
||||
if (StringUtils.isNotBlank(groupId)) {
|
||||
|
||||
@@ -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<FunctionInfo> {
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user