画像事件验证

This commit is contained in:
zren25
2025-06-04 16:41:43 +08:00
parent c47e0879c2
commit 32ee3891a9
15 changed files with 1483 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
package com.volvo.ai.analytic.center.constant;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = XssValidator.class)
public @interface XssClean {
String message() default "当前字符串存在xss注入";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@@ -0,0 +1,44 @@
package com.volvo.ai.analytic.center.constant;
import com.alibaba.cloud.commons.lang.StringUtils;
import lombok.extern.slf4j.Slf4j;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
@Slf4j
public class XssValidator implements ConstraintValidator<XssClean, String> {
private static final Pattern SCRIPT_PATTERN = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
private static final Pattern TAG_PATTERN = Pattern.compile("<[^>]*>", Pattern.CASE_INSENSITIVE);
private static final Pattern SRC_PATTERN = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private static final Pattern SRC_CASE_PATTERN = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private static final Pattern SCRIPT_END_PATTERN = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
private static final Pattern SCRIPT_START_PATTERN = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private static final Pattern EVAL_PATTERN = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private static final Pattern EXPRESSION_PATTERN = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private static final Pattern JAVA_SCRIPT_PATTERN = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
private static final Pattern VB_SCRIPT_PATTERN = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
private static final Pattern ONLOAD_PATTERN = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private static final Pattern IMG_PATTERN = Pattern.compile("<(.*?)img(.*?)src=(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
if (StringUtils.isBlank(s)) {
return true;
}
return !containXss(s);
}
private static boolean containXss(String s) {
return SCRIPT_PATTERN.matcher(s).find() || SRC_PATTERN.matcher(s).find() || SRC_CASE_PATTERN.matcher(s).find() ||
// Remove any lonesome </script> tag Remove any lonesome <script ...> tag Avoid eval(...) e­xpressions
SCRIPT_END_PATTERN.matcher(s).find() || SCRIPT_START_PATTERN.matcher(s).find() || EVAL_PATTERN.matcher(s).find() ||
// Avoid e­xpression(...) e­xpressions Avoid javascript:... e­xpressions Avoid vbscript:... e­xpressions
EXPRESSION_PATTERN.matcher(s).find() || JAVA_SCRIPT_PATTERN.matcher(s).find() || VB_SCRIPT_PATTERN.matcher(s).find() ||
// Avoid οnlοad= e­xpressions
ONLOAD_PATTERN.matcher(s).find() || IMG_PATTERN.matcher(s).find() || TAG_PATTERN.matcher(s).find();
}
}

View File

@@ -0,0 +1,58 @@
package com.volvo.ai.analytic.center.dto.event;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class ListSubscriptionsRequestDto {
/**
* 所属事件通道ID
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty(value = "channel_id")
private String channelId;
/**
* 偏移量表示从此偏移量开始查询偏移量不能小于0
* 最小值0
* 最大值100
* 缺省值0
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty(value = "offset")
private Integer offset;
/**
* 每页显示的条目数量不能小于0
* 最小值0
* 最大值100
* 缺省值15
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty(value = "limit")
private Integer limit;
/**
* 指定查询排序
* 缺省值created_time:DESC
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty(value = "sort")
private String sort;
/**
* 指定查询的事件订阅名称,精准匹配
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty(value = "name")
private String name;
/**
* 指定查询的事件订阅名称,模糊匹配
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty(value = "fuzzy_name")
private String fuzzyName;
}

View File

@@ -0,0 +1,36 @@
package com.volvo.ai.analytic.center.dto.event;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Data
@Slf4j
@Schema(description = "")
public class SendEventDto<T> {
/**
* 事件来源上下文标识串source+id可以唯一确定一个事件
*/
@Schema(description = "事件来源上下文标识串source+id可以唯一确定一个事件")
private String source;
/**
* 事件类型
*/
@Schema(description = "事件类型")
private String type;
/**
* 事件发生的主题或对象,用以标识哪个具体对象发生了当前事件
*/
@Schema(description = "事件发生的主题或对象,用以标识哪个具体对象发生了当前事件")
private String subject;
/**
* 事件的负载内容
*/
@Schema(description = "事件的负载内容")
private T data;
}

View File

@@ -0,0 +1,19 @@
package com.volvo.ai.analytic.center.dto.event;
import lombok.Data;
@Data
public class SourceChannelDto {
private String channelId;
private String sourceName;
public SourceChannelDto() {
}
public SourceChannelDto(String channelId, String sourceName) {
this.channelId = channelId;
this.sourceName = sourceName;
}
}

View File

@@ -0,0 +1,12 @@
package com.volvo.ai.analytic.center.dto.event;
import lombok.Data;
@Data
public class SourceDto {
private String id;
private String name;
private String channelId;
}

View File

@@ -0,0 +1,52 @@
package com.volvo.ai.analytic.center.dto.event;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.huaweicloud.sdk.eg.v1.model.SubscriptionSource;
import com.huaweicloud.sdk.eg.v1.model.SubscriptionTarget;
import lombok.Data;
import java.util.List;
@Data
public class SubscriptionCreateReqDto {
/**
* 所属事件通道ID
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty(value = "channel_id")
private String channelId;
/**
* 订阅名称,租户下唯一,由字母、数字、点、下划线和中划线组成,必须字母或数字开头
* 最小长度1
* 最大长度128
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty("name")
private String name;
/**
* 订阅描述
* 最大长度255
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty("description")
private String description;
/**
* 订阅的事件源
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty("sources")
private SubscriptionSource sources = null;
/**
* 事件目标列表,至少订阅一个事件目标
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty("targets")
private List<SubscriptionTarget> targets = null;
}

View File

@@ -0,0 +1,17 @@
package com.volvo.ai.analytic.center.dto.event;
import lombok.Data;
@Data
public class SubscriptionOperateReqDto {
/**
* 事件订阅ID
*/
private String subscriptionId;
/**
* 0-禁用 1-启用
*/
private int status;
}

View File

@@ -16,4 +16,53 @@ public class ResultDTO<T> implements Serializable {
private String errMsg;
private T data;
public ResultDTO() {
}
public static <T> ResultDTO<T> success() {
return success("200", "成功");
}
public static <T> ResultDTO<T> success(T t) {
return success("200", "成功", t);
}
public static <T> ResultDTO<T> success(String successCode, String successMessage) {
return success(successCode, successMessage, null);
}
public static <T> ResultDTO<T> success(String successCode, String successMessage, T t) {
ResultDTO<T> responseDTO = new ResultDTO<>();
responseDTO.setReturnCode(successCode);
responseDTO.setReturnMessage(successMessage);
responseDTO.setData(t);
return responseDTO;
}
public static <T> ResultDTO<T> failure() {
return failure("500", "处理异常");
}
public static <T> ResultDTO<T> failure(T t) {
return failure("500", "处理异常", t);
}
public static <T> ResultDTO<T> failure(String failureCode, String failureMessage) {
return failure(failureCode, failureMessage, null);
}
public static <T> ResultDTO<T> failure(String failureMessage) {
return failure("500", failureMessage, null);
}
public static <T> ResultDTO<T> failure(String failureCode, String failureMessage, T t) {
ResultDTO<T> responseDTO = new ResultDTO<>();
responseDTO.setReturnCode(failureCode);
responseDTO.setReturnMessage(failureMessage);
responseDTO.setData(t);
return responseDTO;
}
}