63 lines
3.1 KiB
Java
63 lines
3.1 KiB
Java
package com.yunhai.flowcenter.service;
|
|
|
|
import com.yunhai.flowcenter.entity.FlwInstance;
|
|
import com.yunhai.flowcenter.repository.FlwInstanceRepository;
|
|
import com.yunhai.flowcenter.repository.FlwTaskRepository;
|
|
import com.yunhai.platform.apistd.BizException;
|
|
import com.yunhai.platform.utils.exception.ErrorCode;
|
|
import lombok.RequiredArgsConstructor;
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.web.context.request.RequestContextHolder;
|
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
import org.springframework.web.servlet.HandlerInterceptor;
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
/** Authenticated request scope; no user-supplied source/header is trusted. */
|
|
@Component @RequiredArgsConstructor
|
|
public class FlowOapiSourceScope implements HandlerInterceptor {
|
|
private static final String ATTRIBUTE = FlowOapiSourceScope.class.getName();
|
|
private final FlowSourcePrincipalResolver resolver;
|
|
private final FlwInstanceRepository instances;
|
|
private final FlwTaskRepository tasks;
|
|
|
|
@Override
|
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
|
String source = resolver.resolve((String) request.getAttribute("yh.app.auth")).id;
|
|
request.setAttribute(ATTRIBUTE, source);
|
|
String id = request.getParameter("instanceId");
|
|
java.util.regex.Matcher pathId = java.util.regex.Pattern.compile("/instance/(\\d+)(?:/|$)").matcher(request.getRequestURI());
|
|
if (id == null && pathId.find()) id = pathId.group(1);
|
|
String taskId = request.getParameter("taskId");
|
|
java.util.regex.Matcher taskPath = java.util.regex.Pattern.compile("/task/(\\d+)(?:/|$)").matcher(request.getRequestURI());
|
|
if (taskId == null && taskPath.find()) taskId = taskPath.group(1);
|
|
if (id != null) requireOwn(parse(id), source);
|
|
if (taskId != null) {
|
|
Long task = parse(taskId);
|
|
requireOwn(tasks.findById(task).orElseThrow(() -> denied()).getInstanceId(), source);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private void requireOwn(Long id, String source) {
|
|
FlwInstance instance = instances.findById(id).orElseThrow(() -> denied());
|
|
if (!source.equals(instance.getSourcePrincipalId())) throw denied();
|
|
}
|
|
|
|
public static String current() {
|
|
String source = currentOr(null);
|
|
if (source == null) throw denied();
|
|
return source;
|
|
}
|
|
public static String currentOr(String fallback) {
|
|
if (!(RequestContextHolder.getRequestAttributes() instanceof ServletRequestAttributes)) return fallback;
|
|
Object value = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getAttribute(ATTRIBUTE);
|
|
return value instanceof String ? (String) value : fallback;
|
|
}
|
|
private Long parse(String value) {
|
|
try { return Long.valueOf(value); } catch (NumberFormatException e) { throw denied(); }
|
|
}
|
|
private static BizException denied() { return new BizException(ErrorCode.FORBIDDEN, "仅允许访问本应用来源的流程事实"); }
|
|
}
|