refactor: CheckOwner 支持验证中间表
This commit is contained in:
parent
8e52dd5c8d
commit
631f8c5f2c
|
@ -7,6 +7,8 @@ import java.util.List;
|
||||||
public interface ExtCheckOwnerMapper {
|
public interface ExtCheckOwnerMapper {
|
||||||
boolean checkoutOwner(@Param("table") String resourceType, @Param("userId") String userId, @Param("ids") List<String> ids);
|
boolean checkoutOwner(@Param("table") String resourceType, @Param("userId") String userId, @Param("ids") List<String> ids);
|
||||||
|
|
||||||
|
boolean checkoutRelationOwner(@Param("table") String resourceType, @Param("relationTable") String relationType, @Param("userId") String userId, @Param("ids") List<String> ids);
|
||||||
|
|
||||||
boolean checkoutOrganizationOwner(@Param("table") String resourceType, @Param("userId") String userId, @Param("ids") List<String> ids);
|
boolean checkoutOrganizationOwner(@Param("table") String resourceType, @Param("userId") String userId, @Param("ids") List<String> ids);
|
||||||
|
|
||||||
boolean checkoutOrganization(@Param("userId") String userId, @Param("ids") List<String> ids);
|
boolean checkoutOrganization(@Param("userId") String userId, @Param("ids") List<String> ids);
|
||||||
|
|
|
@ -13,6 +13,19 @@
|
||||||
AND user_id = #{userId}
|
AND user_id = #{userId}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="checkoutRelationOwner" resultType="boolean">
|
||||||
|
SELECT count(1) > 0
|
||||||
|
FROM user_role_relation
|
||||||
|
WHERE source_id IN (SELECT project_id
|
||||||
|
FROM ${table} JOIN ${relationTable} ON ${table}.id = ${relationTable}.${table}_id
|
||||||
|
JOIN project ON ${table}.project_id = project.id AND project.enable = TRUE
|
||||||
|
WHERE ${table}.id IN
|
||||||
|
<foreach collection="ids" item="id" separator="," open="(" close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>)
|
||||||
|
AND user_id = #{userId}
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="checkoutOrganizationOwner" resultType="boolean">
|
<select id="checkoutOrganizationOwner" resultType="boolean">
|
||||||
SELECT count(1) > 0
|
SELECT count(1) > 0
|
||||||
FROM user_role_relation
|
FROM user_role_relation
|
||||||
|
|
|
@ -9,4 +9,6 @@ public @interface CheckOwner {
|
||||||
String resourceId();
|
String resourceId();
|
||||||
|
|
||||||
String resourceType();
|
String resourceType();
|
||||||
|
|
||||||
|
String relationType() default "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,13 @@ import io.metersphere.sdk.util.Translator;
|
||||||
import io.metersphere.system.mapper.ExtCheckOwnerMapper;
|
import io.metersphere.system.mapper.ExtCheckOwnerMapper;
|
||||||
import io.metersphere.system.utils.SessionUtils;
|
import io.metersphere.system.utils.SessionUtils;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||||
|
import org.apache.shiro.web.util.WebUtils;
|
||||||
import org.aspectj.lang.JoinPoint;
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.After;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
import org.aspectj.lang.annotation.Before;
|
import org.aspectj.lang.annotation.Before;
|
||||||
import org.aspectj.lang.annotation.Pointcut;
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
@ -20,6 +25,8 @@ import org.springframework.expression.ExpressionParser;
|
||||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.request.RequestAttributes;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -42,6 +49,17 @@ public class CheckOwnerAspect {
|
||||||
|
|
||||||
@Before("pointcut()")
|
@Before("pointcut()")
|
||||||
public void before(JoinPoint joinPoint) {
|
public void before(JoinPoint joinPoint) {
|
||||||
|
|
||||||
|
// apikey 过来的请求
|
||||||
|
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
|
||||||
|
if (requestAttributes != null) {
|
||||||
|
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
|
||||||
|
if (ApiKeyHandler.isApiKeyCall(request) && !SecurityUtils.getSubject().isAuthenticated()) {
|
||||||
|
String userId = ApiKeyHandler.getUser(WebUtils.toHttp(request));
|
||||||
|
SecurityUtils.getSubject().login(new UsernamePasswordToken(userId, "no_pass"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//从切面织入点处通过反射机制获取织入点处的方法
|
//从切面织入点处通过反射机制获取织入点处的方法
|
||||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
//获取切入点所在的方法
|
//获取切入点所在的方法
|
||||||
|
@ -67,13 +85,23 @@ public class CheckOwnerAspect {
|
||||||
|
|
||||||
String resourceId = checkOwner.resourceId();
|
String resourceId = checkOwner.resourceId();
|
||||||
String resourceType = checkOwner.resourceType();
|
String resourceType = checkOwner.resourceType();
|
||||||
|
String relationType = checkOwner.relationType();
|
||||||
Expression titleExp = parser.parseExpression(resourceId);
|
Expression titleExp = parser.parseExpression(resourceId);
|
||||||
Object v = titleExp.getValue(context, Object.class);
|
Object v = titleExp.getValue(context, Object.class);
|
||||||
|
// 归属组织的资源
|
||||||
if (orgResources.contains(resourceType)) {
|
if (orgResources.contains(resourceType)) {
|
||||||
handleOrganizationResource(v, resourceType);
|
handleOrganizationResource(v, resourceType);
|
||||||
} else if (StringUtils.equals(resourceType, "organization")) {
|
}
|
||||||
|
// 组织自身
|
||||||
|
else if (StringUtils.equals(resourceType, "organization")) {
|
||||||
handleOrganization(v);
|
handleOrganization(v);
|
||||||
} else {
|
}
|
||||||
|
// 中间表
|
||||||
|
else if (StringUtils.isNotBlank(relationType)) {
|
||||||
|
handleProjectResource(v, resourceType, relationType);
|
||||||
|
}
|
||||||
|
// 归属项目的资源
|
||||||
|
else {
|
||||||
handleProjectResource(v, resourceType);
|
handleProjectResource(v, resourceType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +132,20 @@ public class CheckOwnerAspect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleProjectResource(Object v, String resourceType, String relationType) {
|
||||||
|
if (v instanceof String id) {
|
||||||
|
if (!extCheckOwnerMapper.checkoutRelationOwner(resourceType, relationType, SessionUtils.getUserId(), List.of(id))) {
|
||||||
|
throw new MSException(Translator.get("check_owner_case"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (v instanceof List ids) {
|
||||||
|
if (!extCheckOwnerMapper.checkoutRelationOwner(resourceType, relationType, SessionUtils.getUserId(), ids)) {
|
||||||
|
throw new MSException(Translator.get("check_owner_case"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void handleOrganizationResource(Object v, String resourceType) {
|
private void handleOrganizationResource(Object v, String resourceType) {
|
||||||
if (v instanceof String id) {
|
if (v instanceof String id) {
|
||||||
if (!extCheckOwnerMapper.checkoutOrganizationOwner(resourceType, SessionUtils.getUserId(), List.of(id))) {
|
if (!extCheckOwnerMapper.checkoutOrganizationOwner(resourceType, SessionUtils.getUserId(), List.of(id))) {
|
||||||
|
@ -117,4 +159,16 @@ public class CheckOwnerAspect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After("pointcut()")
|
||||||
|
public void after() {
|
||||||
|
// apikey 过来的请求
|
||||||
|
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
|
||||||
|
if (requestAttributes != null) {
|
||||||
|
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
|
||||||
|
// apikey 退出
|
||||||
|
if (ApiKeyHandler.isApiKeyCall(WebUtils.toHttp(request)) && SecurityUtils.getSubject().isAuthenticated()) {
|
||||||
|
SecurityUtils.getSubject().logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue