Skip to content

Commit

Permalink
feat: api security check (#772)
Browse files Browse the repository at this point in the history
  • Loading branch information
masaimu authored Jan 3, 2024
1 parent 44a9bf0 commit f7934c3
Show file tree
Hide file tree
Showing 20 changed files with 987 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
package io.holoinsight.server.home.common.service.query;

import lombok.Data;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* @author masaimu
Expand All @@ -15,12 +20,39 @@ public class QueryDetailResponse {

private List<DetailResult> results;

public void distinct() {
if (CollectionUtils.isEmpty(results)) {
return;
}
for (DetailResult detailResult : results) {
detailResult.distinct();
}
}

@Data
public static class DetailResult {
private List<String> tables;
private String sql;
private List<String> headers;
private List<Object[]> values;

public void distinct() {
if (CollectionUtils.isEmpty(values)) {
return;
}
List<Object[]> distinctValues = new ArrayList<>();
Set<Object> set = new HashSet<>();
for (Object[] v : values) {
if (v.length != 1) {
distinctValues.add(v);
} else {
set.add(v[0]);
}
}
for (Object v : set) {
distinctValues.add(new Object[] {v});
}
this.values = distinctValues;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*/
package io.holoinsight.server.home.facade.utils;

import io.holoinsight.server.common.dao.entity.MetricInfo;

import java.util.List;
import java.util.Map;

Expand All @@ -21,4 +23,6 @@ boolean checkFilter(String metricTable, Map<String, List<Object>> filters, Strin

boolean isGlobalMetric(String metricTable);

MetricInfo getMetricInfo(String metricTable);

}
8 changes: 8 additions & 0 deletions server/home/home-web/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,13 @@
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.velocity/velocity -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>

</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
package io.holoinsight.server.home.web.config;

import io.holoinsight.server.home.web.interceptor.MonitorScopeAuthInterceptor;
import io.holoinsight.server.home.web.security.LevelAuthorizationAccess;
import io.holoinsight.server.home.web.security.LevelAuthorizationInterceptor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
Expand Down Expand Up @@ -57,6 +60,20 @@ public DefaultPointcutAdvisor defaultPointcutAdvisor2() {
return advisor;
}

@Bean("levelAuthPointcutAdvisor")
public DefaultPointcutAdvisor defaultPointcutAdvisor3() {

DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(
AnnotationMatchingPointcut.forMethodAnnotation(LevelAuthorizationAccess.class),
levelAuthorizationInterceptor());
return advisor;
}

@Bean
public LevelAuthorizationInterceptor levelAuthorizationInterceptor() {
return new LevelAuthorizationInterceptor();
}

@Bean
public HttpMessageConverter<String> responseBodyStringConverter() {
return new StringHttpMessageConverter(StandardCharsets.UTF_8);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import io.holoinsight.server.home.web.common.ParaCheckUtil;
import io.holoinsight.server.home.web.common.SecurityResource;
import io.holoinsight.server.home.web.interceptor.MonitorScopeAuth;
import io.holoinsight.server.home.web.security.CheckTypeEnum;
import io.holoinsight.server.home.web.security.LevelAuthorizationAccess;
import io.holoinsight.server.home.web.security.ParameterSecurityService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -103,6 +105,9 @@ public class AlarmRuleFacadeImpl extends BaseFacade {
@Value("${holoinsight.home.domain}")
private String domain;

@LevelAuthorizationAccess(paramConfigs = {"PARAMETER" + ":$!alarmRuleDTO"},
contentContainer = "CUSTOM", checkType = CheckTypeEnum.CUSTOMCHECK,
levelAuthorizationCheckeClass = "io.holoinsight.server.home.web.security.custom.AlarmRuleLevelAuthorizationChecker")
@PostMapping("/create")
@ResponseBody
@MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.EDIT)
Expand Down Expand Up @@ -161,6 +166,10 @@ public static Map<String, Map<String, String>> getMetricPage() {
new TypeToken<Map<String, Map<String, String>>>() {});
}

@LevelAuthorizationAccess(paramConfigs = {"PARAMETER" + ":$!alarmRuleDTO"},
contentContainer = "CUSTOM", checkType = CheckTypeEnum.CUSTOMCHECK,
levelAuthorizationCheckeClass = "io.holoinsight.server.home.web.security.custom.AlarmRuleLevelAuthorizationChecker",
contentTargetCollectClass = "")
@PostMapping("/update")
@ResponseBody
@MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.EDIT)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public boolean isGlobalMetric(String metricTable) {
return StringUtils.equals(metricInfo.getWorkspace(), "-");
}

private MetricInfo getMetricInfo(String metricTable) {
@Override
public MetricInfo getMetricInfo(String metricTable) {
if (StringUtils.isEmpty(metricTable)) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0.
*/
package io.holoinsight.server.home.web.security;

import org.aopalliance.intercept.MethodInvocation;

import java.util.List;

/**
* @author masaimu
* @version 2024-01-02 10:45:00
*/
public interface CheckTargetCollector {

/**
* 提供给业务自定义使用的通用待校验目标获取方法 获取单个待校验的目标
*
* @param paramters
* @param methodInvocation
* @return
*/
public String getCheckTarget(List<String> paramters, MethodInvocation methodInvocation);

/**
* 提供给业务自定义使用的通用待校验目标获取方法 获取待校验目标的list
*
* @param paramters
* @param methodInvocation
* @return
*/
public List<String> getCheckTargetList(List<String> paramters, MethodInvocation methodInvocation);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0.
*/
package io.holoinsight.server.home.web.security;

/**
* @author masaimu
* @version 2024-01-02 10:44:00
*/
public class CheckTypeEnum {

/**
* 参数校验
*/
public static final String PARAMETERCHECK = "ParameterCheck";

/**
* 目标对象校验
*/
public static final String TARGETCHECK = "TargetCheck";

/**
* 自定义校验
*/
public static final String CUSTOMCHECK = "CustomCheck";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0.
*/
package io.holoinsight.server.home.web.security;

import org.aopalliance.intercept.MethodInvocation;

import java.util.List;

/**
* @author masaimu
* @version 2024-01-02 10:34:00
*/
public interface ContentTargetCollector {

/**
* 提供给业务自定义使用的通用上下文目标获取方法 获取单个待校验的目标
*
* @param parameters
* @param methodInvocation
* @return
*/
public String getContentTarget(List<String> parameters, MethodInvocation methodInvocation);

/**
* 提供给业务自定义使用的通用上下文目标获取方法 获取待校验目标的list
*
* @param parameters
* @param methodInvocation
* @return
*/
public List<String> getContentTargetList(List<String> parameters,
MethodInvocation methodInvocation);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0.
*/
package io.holoinsight.server.home.web.security;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @author masaimu
* @version 2023-12-28 20:35:00
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LevelAuthContentGet {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0.
*/
package io.holoinsight.server.home.web.security;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @author masaimu
* @version 2023-12-28 18:06:00
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LevelAuthorizationAccess {

/**
* 待校验参数配置信息
*
* @return
*/
public String[] paramConfigs() default "";

/**
* 获取上下文的容器,默认值是CUSTOM
*
* @return
*/
public String contentContainer() default "CUSTOM";

/**
* 获取上下文的key,默认值是空白,配套CUSTOM
*
* @return
*/
public String contentKey() default "";

/**
* 校验方式,目前支持equal、contains
*
* @return
*/
public String checkMode() default "Equal";

/**
* 获取用户自定义校验目标的类名
*
* @return
*/
public String checkTargetCollectClass() default "";

/**
* 获取用户自定义上下文目标的类名
*
* @return
*/
public String contentTargetCollectClass() default "";

/**
* 校验类型,目前支持3种 ParameterCheck,参数校验 TargetCheck,目标对象校验 CustomCheck,自定义校验模式,默认设置
*
* @return
*/
public String checkType() default "CustomCheck";

/**
* 决策模式,目前支持2种 ALLMATCH,全部匹配模式,默认设置 EACHMATCH,任意一条匹配模式
*
* @return
*/
public String decisionMode() default "ALLMATCH";

/**
* 用户自定义的水平权限校验方法的类名
*
* @return
*/
public String levelAuthorizationCheckeClass() default "";

/**
* 拦截器所属位置,目前支持2种 Before,前置拦截,默认设置 After,后置拦截
*
* @return
*/
public String interceptorSeat() default "Before";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0.
*/
package io.holoinsight.server.home.web.security;

import io.holoinsight.server.home.facade.utils.ParaCheckUtil;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang3.StringUtils;

/**
* @author masaimu
* @version 2023-12-28 19:06:00
*/
public interface LevelAuthorizationCheck {

public boolean check(LevelAuthorizationMetaData levelAuthMetaData,
MethodInvocation methodInvocation);

default boolean checkSqlField(String sqlField) {
if (StringUtils.isNotEmpty(sqlField)) {
return ParaCheckUtil.sqlFieldCheck(sqlField);
}
return true;
}

default boolean checkSqlName(String sqlName) {
if (StringUtils.isNotEmpty(sqlName)) {
return ParaCheckUtil.sqlNameCheck(sqlName);
}
return true;
}
}
Loading

0 comments on commit f7934c3

Please sign in to comment.