Compare commits
9 Commits
main
...
dev-pcap-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f8084eaf8 | ||
|
|
5e52c711bc | ||
|
|
c0623e8ca5 | ||
|
|
da051af99f | ||
|
|
79146845b9 | ||
|
|
5a4c15b00a | ||
|
|
9e5709d1f1 | ||
|
|
e85811b805 | ||
|
|
58431f9053 |
81
.gitlab-ci.yml
Normal file
81
.gitlab-ci.yml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
# 定义全局docker镜像
|
||||||
|
image: git.mesalab.cn:7443/nezha/nz-build-env:1.6
|
||||||
|
# 定义全局变量
|
||||||
|
variables:
|
||||||
|
MINIO_HOST: 'http://192.168.40.48:2020/'
|
||||||
|
MINIO_USER: 'admin'
|
||||||
|
MINIO_PWD: "Nezha@02!"
|
||||||
|
MAVEN_REPO: "/etc/maven/repository/"
|
||||||
|
# mariadb 数据库定义(非必须)
|
||||||
|
MYSQL_DATABASE: "test"
|
||||||
|
# mariadb 密码配置(必须),注意变量名是 MYSQL_ROOT_PASSWORD
|
||||||
|
MYSQL_ROOT_PASSWORD: '111111'
|
||||||
|
# 定义全局依赖的docker服务,即 这条流水线 pipeline 中的任务都用这里的服务
|
||||||
|
services:
|
||||||
|
- mariadb:10.2.14
|
||||||
|
# 开始执行脚本前所需执行脚本
|
||||||
|
before_script:
|
||||||
|
- echo "begin ci"
|
||||||
|
# 脚本执行完后的钩子,执行所需脚本
|
||||||
|
after_script:
|
||||||
|
- echo "end ci"
|
||||||
|
# 该ci pipeline适合的场景,按照定义的顺序执行任务
|
||||||
|
stages:
|
||||||
|
- build
|
||||||
|
- test
|
||||||
|
# paths主要是来指定需要被缓存的文件路径,需要特别指出的是这里的 paths 是相对路径,是相对于gitlab中项目目录的路径,也就是说被缓存的文件都是在项目目录之内的
|
||||||
|
# maven setting /usr/share/maven/conf/settings.xml
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- $MAVEN_REPO
|
||||||
|
|
||||||
|
# 定义的任务
|
||||||
|
build_rpm:
|
||||||
|
stage: build
|
||||||
|
# 所需执行的脚本
|
||||||
|
script:
|
||||||
|
- env | sort
|
||||||
|
- pwd
|
||||||
|
- export FILE_NAME=$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA.tar.gz
|
||||||
|
- mvn clean install -Dmaven.test.skip=true
|
||||||
|
- cd ./target
|
||||||
|
- tar -zcvf $FILE_NAME asw-controller.jar
|
||||||
|
# 将 文件 上传到 minio
|
||||||
|
- mc alias set asw $MINIO_HOST $MINIO_USER $MINIO_PWD
|
||||||
|
- mc cp $FILE_NAME asw/release/asw-controller/$FILE_NAME
|
||||||
|
- cd ../
|
||||||
|
# 在哪个分支上可用
|
||||||
|
only:
|
||||||
|
- /^rel-.*$/i
|
||||||
|
# 指定哪个ci runner跑该工作
|
||||||
|
tags:
|
||||||
|
- asw
|
||||||
|
|
||||||
|
# 定义的任务
|
||||||
|
dev_build:
|
||||||
|
stage: test
|
||||||
|
# 所需执行的脚本
|
||||||
|
script:
|
||||||
|
- env | sort
|
||||||
|
- pwd
|
||||||
|
- export FILE_NAME=$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA.tar.gz
|
||||||
|
- mvn clean install -Dmaven.test.skip=true
|
||||||
|
- cd ./target
|
||||||
|
- "git log -100 --pretty=format:'%ad : %s' > git-log.html"
|
||||||
|
- tar -zcvf $FILE_NAME asw-controller.jar git-log.html
|
||||||
|
- md5sum $FILE_NAME > $CI_PROJECT_NAME-$CI_COMMIT_REF_NAME-latest.tar.gz.md5sum.txt
|
||||||
|
# 将 文件 上传到 minio
|
||||||
|
- mc alias set asw $MINIO_HOST $MINIO_USER $MINIO_PWD
|
||||||
|
- mc cp $FILE_NAME asw/ci-cd/asw-controller/$FILE_NAME
|
||||||
|
- mc cp $FILE_NAME asw/ci-cd/asw-controller/$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME-latest.tar.gz
|
||||||
|
- mc cp $CI_PROJECT_NAME-$CI_COMMIT_REF_NAME-latest.tar.gz.md5sum.txt asw/ci-cd/asw-controller/$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME-latest.tar.gz.md5sum.txt
|
||||||
|
- cd ../
|
||||||
|
# 在哪个分支上可用
|
||||||
|
only:
|
||||||
|
- /^dev-.*$/i
|
||||||
|
# 指定不执行的标签
|
||||||
|
except:
|
||||||
|
- schedules
|
||||||
|
# 指定哪个ci runner跑该工作
|
||||||
|
tags:
|
||||||
|
- asw
|
||||||
122
src/main/java/net/geedge/asw/common/config/I18nConfig.java
Normal file
122
src/main/java/net/geedge/asw/common/config/I18nConfig.java
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
package net.geedge.asw.common.config;
|
||||||
|
|
||||||
|
import cn.hutool.log.Log;
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import net.geedge.asw.common.util.Constants;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.sys.entity.SysI18nEntity;
|
||||||
|
import net.geedge.asw.module.sys.service.ISysI18nService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ResourceLoaderAware;
|
||||||
|
import org.springframework.context.support.AbstractMessageSource;
|
||||||
|
import org.springframework.core.io.DefaultResourceLoader;
|
||||||
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class I18nConfig extends AbstractMessageSource implements ResourceLoaderAware {
|
||||||
|
|
||||||
|
private static final Log log = Log.get();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysI18nService sysI18nService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际化缓存
|
||||||
|
*/
|
||||||
|
public static final Map<String, Map<String, String>> I18N_CACHE = new HashMap<>();
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重新将数据库中的国际化配置加载
|
||||||
|
*/
|
||||||
|
public void reload() {
|
||||||
|
I18N_CACHE.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected ResourceLoader resourceLoader;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResourceLoader(ResourceLoader resourceLoader) {
|
||||||
|
this.resourceLoader = (resourceLoader == null ? new DefaultResourceLoader() : resourceLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MessageFormat resolveCode(String code, Locale locale) {
|
||||||
|
String msg = this.getSourceFromCache(code, locale);
|
||||||
|
MessageFormat messageFormat = new MessageFormat(msg, locale);
|
||||||
|
return messageFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String resolveCodeWithoutArguments(String code, Locale locale) {
|
||||||
|
return this.getSourceFromCache(code, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从缓存中取出国际化配置对应的数据 或者从父级获取
|
||||||
|
*
|
||||||
|
* @param code
|
||||||
|
* @param locale
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getSourceFromCache(String code, Locale locale, Object... param) {
|
||||||
|
String language = locale.getLanguage();
|
||||||
|
if (T.ObjectUtil.isEmpty(I18N_CACHE)) {
|
||||||
|
this.loadAllMessageResourcesFromDB();
|
||||||
|
}
|
||||||
|
Map<String, String> props = I18N_CACHE.get(language);
|
||||||
|
if (null != props && props.containsKey(code)) {
|
||||||
|
String msg = props.get(code);
|
||||||
|
if (T.ObjectUtil.isEmpty(param)) {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
return MessageFormat.format(msg, param);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (null != this.getParentMessageSource()) {
|
||||||
|
return this.getParentMessageSource().getMessage(code, param, locale);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从数据库中获取所有国际化配置
|
||||||
|
*/
|
||||||
|
public void loadAllMessageResourcesFromDB() {
|
||||||
|
List<SysI18nEntity> list = sysI18nService.list();
|
||||||
|
if (T.CollUtil.isNotEmpty(list)) {
|
||||||
|
try {
|
||||||
|
for (String lang : Constants.LANG_LIST) {
|
||||||
|
Map<String, String> langMap = I18N_CACHE.get(lang);
|
||||||
|
langMap = T.ObjectUtil.defaultIfNull(langMap, new HashMap<>());
|
||||||
|
I18N_CACHE.put(lang, langMap);
|
||||||
|
|
||||||
|
List<SysI18nEntity> dataList = list.stream().filter(pojo -> T.StrUtil.equals(lang, pojo.getLang())).collect(Collectors.toList());
|
||||||
|
for (SysI18nEntity entity : dataList) {
|
||||||
|
langMap.put(entity.getCode(), entity.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
66
src/main/java/net/geedge/asw/common/config/LocaleConfig.java
Normal file
66
src/main/java/net/geedge/asw/common/config/LocaleConfig.java
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package net.geedge.asw.common.config;
|
||||||
|
|
||||||
|
import cn.hutool.log.Log;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
|
import org.springframework.web.servlet.LocaleResolver;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
||||||
|
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@ComponentScan
|
||||||
|
public class LocaleConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public LocaleResolver localeResolver() {
|
||||||
|
SessionLocaleResolver slr = new SessionLocaleResolver();
|
||||||
|
// 默认语言
|
||||||
|
slr.setDefaultLocale(Locale.of("en"));
|
||||||
|
return slr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public LocaleChangeInterceptor localeChangeInterceptor() {
|
||||||
|
MyI18nInterceptor lci = new MyI18nInterceptor();
|
||||||
|
// 参数名
|
||||||
|
lci.setParamName("Language");
|
||||||
|
return lci;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
|
registry.addInterceptor(localeChangeInterceptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyI18nInterceptor extends LocaleChangeInterceptor {
|
||||||
|
|
||||||
|
private static final Log log = Log.get();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||||
|
try {
|
||||||
|
String language = request.getHeader(getParamName());
|
||||||
|
if (T.ObjectUtil.isNotEmpty(language)) {
|
||||||
|
Locale locale = parseLocaleValue(language);
|
||||||
|
LocaleContextHolder.setLocale(locale);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e, "[preHandle] [error]");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -47,7 +47,7 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
|||||||
// 注册 Sa-Token 拦截器,打开注解式鉴权功能
|
// 注册 Sa-Token 拦截器,打开注解式鉴权功能
|
||||||
registry.addInterceptor(new SaInterceptor(handler -> {
|
registry.addInterceptor(new SaInterceptor(handler -> {
|
||||||
SaRouter.match("/file/**").notMatch("/file/content/*").check(r -> StpUtil.checkLogin());
|
SaRouter.match("/file/**").notMatch("/file/content/*").check(r -> StpUtil.checkLogin());
|
||||||
SaRouter.match("/sys/**").notMatch("/sys/login").check(r -> StpUtil.checkLogin());
|
SaRouter.match("/api/v1/**").notMatch("/api/v1/login").check(r -> StpUtil.checkLogin());
|
||||||
})).addPathPatterns("/**");
|
})).addPathPatterns("/**");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package net.geedge.asw.common.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Context 工具类
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class SpringContextUtils implements ApplicationContextAware {
|
||||||
|
|
||||||
|
private static ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
SpringContextUtils.applicationContext = applicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object getBean(String name) {
|
||||||
|
return applicationContext.getBean(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T getBean(Class<T> requiredType) {
|
||||||
|
return applicationContext.getBean(requiredType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getProperty(String key, String defaultValue) {
|
||||||
|
return applicationContext.getEnvironment().getProperty(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T getBean(String name, Class<T> requiredType) {
|
||||||
|
return applicationContext.getBean(name, requiredType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<? extends Object> getType(String name) {
|
||||||
|
return applicationContext.getType(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,18 +1,20 @@
|
|||||||
package net.geedge.asw.common.config.exception;
|
package net.geedge.asw.common.config.exception;
|
||||||
|
|
||||||
import org.apache.catalina.connector.ClientAbortException;
|
|
||||||
import org.springframework.dao.DuplicateKeyException;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
|
||||||
|
|
||||||
import cn.dev33.satoken.exception.NotLoginException;
|
import cn.dev33.satoken.exception.NotLoginException;
|
||||||
import cn.hutool.log.Log;
|
import cn.hutool.log.Log;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import net.geedge.asw.common.util.ASWException;
|
import net.geedge.asw.common.util.ASWException;
|
||||||
import net.geedge.asw.common.util.R;
|
import net.geedge.asw.common.util.R;
|
||||||
import net.geedge.asw.common.util.RCode;
|
import net.geedge.asw.common.util.RCode;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.sys.service.ISysI18nService;
|
||||||
|
import org.apache.catalina.connector.ClientAbortException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常处理器
|
* 异常处理器
|
||||||
@@ -22,6 +24,9 @@ public class ASWExceptionHandler {
|
|||||||
|
|
||||||
private static final Log log = Log.get();
|
private static final Log log = Log.get();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysI18nService sysI18nService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理自定义异常
|
* 处理自定义异常
|
||||||
*/
|
*/
|
||||||
@@ -29,7 +34,19 @@ public class ASWExceptionHandler {
|
|||||||
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
|
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
|
||||||
public R handleDHException(ASWException e, HttpServletRequest request) {
|
public R handleDHException(ASWException e, HttpServletRequest request) {
|
||||||
log.warn(e, "Request uri: {}", request.getRequestURI());
|
log.warn(e, "Request uri: {}", request.getRequestURI());
|
||||||
return R.error(e.getCode(), e.getMsg());
|
R r = new R();
|
||||||
|
r.put("code", e.getCode());
|
||||||
|
String msg = "";
|
||||||
|
// by code
|
||||||
|
if (T.ObjectUtil.isNotEmpty(e.getCode())) {
|
||||||
|
msg = sysI18nService.queryValueByName(T.StrUtil.toString(e.getCode()), e.getParam());
|
||||||
|
}
|
||||||
|
if (T.StrUtil.isEmpty(msg) && (T.ObjectUtil.isEmpty(e.getRCode()) || T.ObjectUtil.equals(msg, e.getRCode().toString()))) {
|
||||||
|
r.put("msg", e.getMsg());
|
||||||
|
} else {
|
||||||
|
r.put("msg", msg);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,7 +66,8 @@ public class ASWExceptionHandler {
|
|||||||
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
|
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
|
||||||
public R handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) {
|
public R handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) {
|
||||||
log.error(e, "Request uri: {}", request.getRequestURI());
|
log.error(e, "Request uri: {}", request.getRequestURI());
|
||||||
return R.error(RCode.SYS_DUPLICATE_RECORD);
|
String msg = sysI18nService.queryValueByName(RCode.SYS_DUPLICATE_RECORD.getCode().toString());
|
||||||
|
return R.error(RCode.SYS_DUPLICATE_RECORD.getCode(), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(Exception.class)
|
@ExceptionHandler(Exception.class)
|
||||||
|
|||||||
@@ -12,12 +12,14 @@ public class ASWException extends RuntimeException {
|
|||||||
private String msg = RCode.ERROR.getMsg();
|
private String msg = RCode.ERROR.getMsg();
|
||||||
private int code = RCode.ERROR.getCode();
|
private int code = RCode.ERROR.getCode();
|
||||||
private Object[] param = new Object[] {};
|
private Object[] param = new Object[] {};
|
||||||
|
private RCode rCode;
|
||||||
|
|
||||||
public ASWException(RCode rCode) {
|
public ASWException(RCode rCode) {
|
||||||
super(rCode.getMsg());
|
super(rCode.getMsg());
|
||||||
this.code = rCode.getCode();
|
this.code = rCode.getCode();
|
||||||
this.msg = rCode.getMsg();
|
this.msg = rCode.getMsg();
|
||||||
this.param = rCode.getParam();
|
this.param = rCode.getParam();
|
||||||
|
this.rCode = rCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ASWException(String msg) {
|
public ASWException(String msg) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.geedge.asw.common.util;
|
package net.geedge.asw.common.util;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Constants {
|
public class Constants {
|
||||||
|
|
||||||
@@ -14,6 +15,9 @@ public class Constants {
|
|||||||
*/
|
*/
|
||||||
public static final String TEMP_PATH = System.getProperty("user.dir") + File.separator + "tmp";
|
public static final String TEMP_PATH = System.getProperty("user.dir") + File.separator + "tmp";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际化语言列表
|
||||||
|
*/
|
||||||
|
public static final List<String> LANG_LIST = T.ListUtil.of("en", "zh");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import java.text.MessageFormat;
|
|||||||
public enum RCode {
|
public enum RCode {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 10**** : 系统认证 或 通用错误提示 20**** : screen module
|
* 10**** : 系统认证 或 通用错误提示 20**** : sys module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ERROR(999, "error"), // 通用错误/未知错误
|
ERROR(999, "error"), // 通用错误/未知错误
|
||||||
@@ -20,27 +20,26 @@ public enum RCode {
|
|||||||
SYS_RECORD_NOT_FOUND(100008, "record not found"),// 未找到记录
|
SYS_RECORD_NOT_FOUND(100008, "record not found"),// 未找到记录
|
||||||
|
|
||||||
|
|
||||||
SCREEN_ID_CANNOT_EMPTY(200001, "id cannot be empty"),
|
// Application
|
||||||
|
APP_ID_CANNOT_EMPTY(201001, "application id cannot be empty"),
|
||||||
|
|
||||||
SCREE_DATASOURCE_DEFAULT_CANNOT_BE_DELETE(300001,"The default data source cannot be deleted."),
|
|
||||||
SCREE_DATASOURCE_REPEAT(300002,"Screen datasource name duplicate"),
|
|
||||||
|
|
||||||
/**
|
// Package
|
||||||
* import
|
PACKAGE_ID_CANNOT_EMPTY(202001, "package id cannot be empty"),
|
||||||
*/
|
PACKAGE_DESCRIPTION_CANNOT_EMPTY(202002, "package description cannot be empty"),
|
||||||
EXCELFILE_TYPE_ERROR(400001, "The type can only be xlsx, json, csv"),
|
|
||||||
EXCELFILE_PARSE_ERROR(400002, "Import file resolution failed"),
|
|
||||||
EXCELFILE_HEADER_TEMPLATE_ERROR(400003,"The header row of the import template is inconsistent with the system template"),
|
|
||||||
EXCELFILE_HEADER_LANGUAGE_ERROR(400004, "Language must be en, zh or ru"),
|
|
||||||
EXCELFILE_IMPORT_FILE_ISNULL(400005, "Import file is null"),
|
|
||||||
EXCELFILE_HEADER_LANGUAGE_ISNULL(400006, "Language can not be empty"),
|
|
||||||
EXCELFILE_IMPORT_ERROR(400007, "File import error"),
|
|
||||||
EXCELFILE_SCHEDULE_TASK_IS_NULL(400008, "Schedule task can not be empty"),
|
|
||||||
EXCELFILE_SCHEDULE_CRON_IS_NULL(400009, "Schedule cron can not be empty"),
|
|
||||||
EXCELFILE_SCHEDULE_ENABLE_IS_NULL(400010, "Schedule enable can not be empty"),
|
|
||||||
EXCELFILE_SCHEDULE_SCRIPT_IS_NULL(400011, "Schedule script can not be empty"),
|
|
||||||
|
|
||||||
|
|
||||||
|
// Runner
|
||||||
|
RUNNER_ID_CANNOT_EMPTY(301001, "runner id cannot be empty"),
|
||||||
|
|
||||||
|
|
||||||
|
// Playbook
|
||||||
|
PLAYBOOK_ID_CANNOT_EMPTY(302001, "playbook id cannot be empty"),
|
||||||
|
|
||||||
|
|
||||||
|
// Workspace
|
||||||
|
WORKSPACE_ID_CANNOT_EMPTY(401001, "workspace id cannot be empty"),
|
||||||
|
|
||||||
SUCCESS(200, "success"); // 成功
|
SUCCESS(200, "success"); // 成功
|
||||||
|
|
||||||
private RCode(Integer code, String msg) {
|
private RCode(Integer code, String msg) {
|
||||||
|
|||||||
@@ -1,27 +1,9 @@
|
|||||||
package net.geedge.asw.common.util;
|
package net.geedge.asw.common.util;
|
||||||
|
|
||||||
import java.awt.Graphics;
|
import cn.hutool.core.date.DateTime;
|
||||||
import java.awt.Robot;
|
import cn.hutool.log.Log;
|
||||||
import java.lang.ref.PhantomReference;
|
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||||
import java.lang.ref.Reference;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import java.lang.ref.ReferenceQueue;
|
|
||||||
import java.lang.ref.SoftReference;
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.temporal.Temporal;
|
|
||||||
import java.time.temporal.TemporalAccessor;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Spliterator;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.KeyGenerator;
|
import javax.crypto.KeyGenerator;
|
||||||
@@ -29,10 +11,23 @@ import javax.crypto.SecretKey;
|
|||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
|
import java.awt.*;
|
||||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
import java.io.File;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import cn.hutool.core.date.DateTime;
|
import java.lang.ref.*;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.temporal.Temporal;
|
||||||
|
import java.time.temporal.TemporalAccessor;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class T {
|
public class T {
|
||||||
|
|
||||||
@@ -315,6 +310,27 @@ public class T {
|
|||||||
* @author xiaoleilu
|
* @author xiaoleilu
|
||||||
*/
|
*/
|
||||||
public static class PageUtil extends cn.hutool.core.util.PageUtil {
|
public static class PageUtil extends cn.hutool.core.util.PageUtil {
|
||||||
|
public static final Integer DEFAULT_PAGENO = 1;
|
||||||
|
public static final Integer DEFAULT_PAGESIZE = 20;
|
||||||
|
|
||||||
|
public static Page getPage(Map<String, Object> params) {
|
||||||
|
// 分页参数
|
||||||
|
Integer pageNo = T.MapUtil.getInt(params, "current", DEFAULT_PAGENO);
|
||||||
|
Integer pageSize = T.MapUtil.getInt(params, "size", DEFAULT_PAGESIZE);
|
||||||
|
if (pageSize == -1) {
|
||||||
|
pageNo = 0;
|
||||||
|
pageSize = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Page page = Page.of(pageNo, pageSize);
|
||||||
|
|
||||||
|
String orderBy = T.MapUtil.getStr(params, "orderBy");
|
||||||
|
if (T.StrUtil.isNotEmpty(orderBy)) {
|
||||||
|
page.addOrder(T.PageUtil.decodeOrderByStr(orderBy));
|
||||||
|
}
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
public static OrderItem decodeOrderByStr(String orderBy) {
|
public static OrderItem decodeOrderByStr(String orderBy) {
|
||||||
if (cn.hutool.core.util.StrUtil.isBlank(orderBy)) {
|
if (cn.hutool.core.util.StrUtil.isBlank(orderBy)) {
|
||||||
return null;
|
return null;
|
||||||
@@ -1526,4 +1542,37 @@ public class T {
|
|||||||
super(value);
|
super(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取项目中各种路径
|
||||||
|
*
|
||||||
|
* @author ThinkPad
|
||||||
|
*/
|
||||||
|
public static class WebPathUtil {
|
||||||
|
private static final Log log = Log.get();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果已打成jar包,则返回jar包所在目录
|
||||||
|
* 如果未打成jar,则返回target所在目录
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getClassPath() {
|
||||||
|
try {
|
||||||
|
// 项目的编译文件的根目录
|
||||||
|
String path = URLDecoder.decode(System.getProperty("user.dir"), "utf-8");
|
||||||
|
log.debug("root path:{}", path);
|
||||||
|
return path;
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getRootPath() {
|
||||||
|
File file = T.FileUtil.file(WebPathUtil.getClassPath());
|
||||||
|
return file.getAbsolutePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package net.geedge.asw.module.app.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import net.geedge.asw.common.util.R;
|
||||||
|
import net.geedge.asw.common.util.RCode;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.app.entity.PackageEntity;
|
||||||
|
import net.geedge.asw.module.app.service.IPackageService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/package")
|
||||||
|
public class PackageController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IPackageService packageService;
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public R detail(@PathVariable("id") String id) {
|
||||||
|
PackageEntity entity = packageService.getById(id);
|
||||||
|
return R.ok().putData("record", entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public R list(@RequestParam Map<String, Object> params) {
|
||||||
|
T.VerifyUtil.is(params).notNull()
|
||||||
|
.and(T.MapUtil.getStr(params, "workspaceId")).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY);
|
||||||
|
Page page = packageService.queryList(params);
|
||||||
|
return R.ok(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public R add(@RequestBody PackageEntity entity) {
|
||||||
|
T.VerifyUtil.is(entity).notNull()
|
||||||
|
.and(entity.getName()).notEmpty(RCode.NAME_CANNOT_EMPTY)
|
||||||
|
.and(entity.getDescription()).notEmpty(RCode.PACKAGE_DESCRIPTION_CANNOT_EMPTY)
|
||||||
|
.and(entity.getWorkspaceId()).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY);
|
||||||
|
|
||||||
|
PackageEntity pkgEntity = packageService.savePackage(entity);
|
||||||
|
return R.ok().putData("id", pkgEntity.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
public R update(@RequestBody PackageEntity entity) {
|
||||||
|
T.VerifyUtil.is(entity).notNull()
|
||||||
|
.and(entity.getId()).notEmpty(RCode.ID_CANNOT_EMPTY)
|
||||||
|
.and(entity.getName()).notEmpty(RCode.NAME_CANNOT_EMPTY)
|
||||||
|
.and(entity.getDescription()).notEmpty(RCode.PACKAGE_DESCRIPTION_CANNOT_EMPTY)
|
||||||
|
.and(entity.getWorkspaceId()).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY);
|
||||||
|
|
||||||
|
PackageEntity pkgEntity = packageService.updatePackage(entity);
|
||||||
|
return R.ok().putData("id", pkgEntity.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping
|
||||||
|
public R delete(String[] ids) {
|
||||||
|
T.VerifyUtil.is(ids).notEmpty();
|
||||||
|
packageService.removePackage(T.ListUtil.of(ids));
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.geedge.asw.module.app.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import net.geedge.asw.module.app.entity.ApplicationEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface ApplicationDao extends BaseMapper<ApplicationEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
16
src/main/java/net/geedge/asw/module/app/dao/PackageDao.java
Normal file
16
src/main/java/net/geedge/asw/module/app/dao/PackageDao.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package net.geedge.asw.module.app.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import net.geedge.asw.module.app.entity.PackageEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface PackageDao extends BaseMapper<PackageEntity>{
|
||||||
|
|
||||||
|
List<PackageEntity> queryList(Page page, Map<String, Object> params);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.geedge.asw.module.app.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import net.geedge.asw.module.app.entity.SignatureEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SignatureDao extends BaseMapper<SignatureEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package net.geedge.asw.module.app.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("application")
|
||||||
|
public class ApplicationEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String longName;
|
||||||
|
private String properties;
|
||||||
|
private String description;
|
||||||
|
private String surrogates;
|
||||||
|
|
||||||
|
private Long createTimestamp;
|
||||||
|
private Long updateTimestamp;
|
||||||
|
private String createUserId;
|
||||||
|
private String updateUserId;
|
||||||
|
|
||||||
|
private String workspaceId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package net.geedge.asw.module.app.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("package")
|
||||||
|
public class PackageEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String logo;
|
||||||
|
private String description;
|
||||||
|
private String platform;
|
||||||
|
private String version;
|
||||||
|
private String identifier;
|
||||||
|
|
||||||
|
private Long createTimestamp;
|
||||||
|
private Long updateTimestamp;
|
||||||
|
private String createUserId;
|
||||||
|
private String updateUserId;
|
||||||
|
|
||||||
|
private String workspaceId;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String workbookId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package net.geedge.asw.module.app.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("signature")
|
||||||
|
public class SignatureEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
private String id;
|
||||||
|
private String appId;
|
||||||
|
private String name;
|
||||||
|
private String tags;
|
||||||
|
private String description;
|
||||||
|
private Integer displayFlag;
|
||||||
|
private String conditions;
|
||||||
|
private Long opVersion;
|
||||||
|
|
||||||
|
private Long createTimestamp;
|
||||||
|
private Long updateTimestamp;
|
||||||
|
private String createUserId;
|
||||||
|
private String updateUserId;
|
||||||
|
|
||||||
|
private String workspaceId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package net.geedge.asw.module.app.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.app.entity.ApplicationEntity;
|
||||||
|
|
||||||
|
public interface IApplicationService extends IService<ApplicationEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package net.geedge.asw.module.app.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.app.entity.PackageEntity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface IPackageService extends IService<PackageEntity>{
|
||||||
|
|
||||||
|
Page queryList(Map<String, Object> params);
|
||||||
|
|
||||||
|
PackageEntity savePackage(PackageEntity entity);
|
||||||
|
|
||||||
|
PackageEntity updatePackage(PackageEntity entity);
|
||||||
|
|
||||||
|
void removePackage(List<String> ids);
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package net.geedge.asw.module.app.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.app.entity.SignatureEntity;
|
||||||
|
|
||||||
|
public interface ISignatureService extends IService<SignatureEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package net.geedge.asw.module.app.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.module.app.dao.ApplicationDao;
|
||||||
|
import net.geedge.asw.module.app.entity.ApplicationEntity;
|
||||||
|
import net.geedge.asw.module.app.service.IApplicationService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ApplicationServiceImpl extends ServiceImpl<ApplicationDao, ApplicationEntity> implements IApplicationService {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package net.geedge.asw.module.app.service.impl;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.common.util.ASWException;
|
||||||
|
import net.geedge.asw.common.util.RCode;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.app.dao.PackageDao;
|
||||||
|
import net.geedge.asw.module.app.entity.PackageEntity;
|
||||||
|
import net.geedge.asw.module.app.service.IPackageService;
|
||||||
|
import net.geedge.asw.module.workbook.service.IWorkbookResourceService;
|
||||||
|
import net.geedge.asw.module.workbook.util.WorkbookConstant;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class PackageServiceImpl extends ServiceImpl<PackageDao, PackageEntity> implements IPackageService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IWorkbookResourceService workbookResourceService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page queryList(Map<String, Object> params) {
|
||||||
|
Page page = T.PageUtil.getPage(params);
|
||||||
|
List<PackageEntity> packageList = this.getBaseMapper().queryList(page, params);
|
||||||
|
page.setRecords(packageList);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public PackageEntity savePackage(PackageEntity entity) {
|
||||||
|
PackageEntity one = this.getOne(new LambdaQueryWrapper<PackageEntity>()
|
||||||
|
.eq(PackageEntity::getWorkspaceId, entity.getWorkspaceId())
|
||||||
|
.eq(PackageEntity::getName, entity.getName()));
|
||||||
|
if (T.ObjectUtil.isNotNull(one)) {
|
||||||
|
throw ASWException.builder().rcode(RCode.SYS_DUPLICATE_RECORD).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.setCreateTimestamp(System.currentTimeMillis());
|
||||||
|
entity.setUpdateTimestamp(System.currentTimeMillis());
|
||||||
|
entity.setCreateUserId(StpUtil.getLoginIdAsString());
|
||||||
|
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
|
||||||
|
|
||||||
|
// save
|
||||||
|
this.save(entity);
|
||||||
|
|
||||||
|
// workbook resource
|
||||||
|
workbookResourceService.saveResource(entity.getWorkbookId(), entity.getId(), WorkbookConstant.ResourceType.PACKAGE.getValue());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public PackageEntity updatePackage(PackageEntity entity) {
|
||||||
|
PackageEntity one = this.getOne(new LambdaQueryWrapper<PackageEntity>()
|
||||||
|
.eq(PackageEntity::getWorkspaceId, entity.getWorkspaceId())
|
||||||
|
.eq(PackageEntity::getName, entity.getName())
|
||||||
|
.ne(PackageEntity::getId, entity.getId()));
|
||||||
|
if (T.ObjectUtil.isNotNull(one)) {
|
||||||
|
throw ASWException.builder().rcode(RCode.SYS_DUPLICATE_RECORD).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.setUpdateTimestamp(System.currentTimeMillis());
|
||||||
|
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
|
||||||
|
|
||||||
|
// update
|
||||||
|
this.updateById(entity);
|
||||||
|
|
||||||
|
// workbook resource
|
||||||
|
workbookResourceService.saveResource(entity.getWorkbookId(), entity.getId(), WorkbookConstant.ResourceType.PACKAGE.getValue());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void removePackage(List<String> ids) {
|
||||||
|
// remove
|
||||||
|
this.removeBatchByIds(ids);
|
||||||
|
// workbook resource
|
||||||
|
workbookResourceService.removeResource(ids, WorkbookConstant.ResourceType.PACKAGE.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package net.geedge.asw.module.app.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.module.app.dao.SignatureDao;
|
||||||
|
import net.geedge.asw.module.app.entity.SignatureEntity;
|
||||||
|
import net.geedge.asw.module.app.service.ISignatureService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SignatureServiceImpl extends ServiceImpl<SignatureDao, SignatureEntity> implements ISignatureService {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package net.geedge.asw.module.runner.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import net.geedge.asw.common.util.R;
|
||||||
|
import net.geedge.asw.common.util.RCode;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.runner.entity.JobEntity;
|
||||||
|
import net.geedge.asw.module.runner.service.IJobService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/job")
|
||||||
|
public class JobController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IJobService jobService;
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public R detail(@PathVariable("id") String id) {
|
||||||
|
JobEntity jobEntity = jobService.queryInfo(id);
|
||||||
|
return R.ok().putData("record", jobEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public R list(@RequestParam Map<String, Object> params) {
|
||||||
|
T.VerifyUtil.is(params).notNull()
|
||||||
|
.and(T.MapUtil.getStr(params, "workspaceId")).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY);
|
||||||
|
Page page = jobService.queryList(params);
|
||||||
|
return R.ok(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public R add(@RequestBody JobEntity entity) {
|
||||||
|
T.VerifyUtil.is(entity).notNull()
|
||||||
|
.and(entity.getRunnerId()).notEmpty(RCode.RUNNER_ID_CANNOT_EMPTY)
|
||||||
|
.and(entity.getPackageId()).notEmpty(RCode.PACKAGE_ID_CANNOT_EMPTY)
|
||||||
|
.and(entity.getWorkspaceId()).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY);
|
||||||
|
|
||||||
|
JobEntity jobEntity = jobService.saveJob(entity);
|
||||||
|
return R.ok().putData("id", jobEntity.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping
|
||||||
|
public R delete(String[] ids) {
|
||||||
|
T.VerifyUtil.is(ids).notEmpty();
|
||||||
|
jobService.removeJob(T.ListUtil.of(ids));
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/cancel")
|
||||||
|
public R cancel(String[] ids) {
|
||||||
|
T.VerifyUtil.is(ids).notEmpty();
|
||||||
|
// TODO 其他处理
|
||||||
|
|
||||||
|
// update state
|
||||||
|
jobService.update(new LambdaUpdateWrapper<JobEntity>()
|
||||||
|
.in(JobEntity::getId, ids)
|
||||||
|
.set(JobEntity::getStatus, "cancel")
|
||||||
|
);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package net.geedge.asw.module.runner.controller;
|
||||||
|
|
||||||
|
import cn.hutool.log.Log;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import net.geedge.asw.common.util.R;
|
||||||
|
import net.geedge.asw.common.util.RCode;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.runner.entity.PcapEntity;
|
||||||
|
import net.geedge.asw.module.runner.service.IPcapService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/pcap")
|
||||||
|
public class PcapController {
|
||||||
|
|
||||||
|
private static final Log log = Log.get();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IPcapService pcapService;
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public R detail(@PathVariable("id") String id) {
|
||||||
|
PcapEntity pcapEntity = pcapService.queryInfo(id);
|
||||||
|
return R.ok().putData("record", pcapEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public R list(@RequestParam Map<String, Object> params) {
|
||||||
|
T.VerifyUtil.is(params).notNull()
|
||||||
|
.and(T.MapUtil.getStr(params, "workspaceId")).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY);
|
||||||
|
|
||||||
|
Page page = pcapService.queryList(params);
|
||||||
|
return R.ok(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public R add(@RequestParam(value = "file", required = true) MultipartFile file,
|
||||||
|
@RequestParam(required = false) String tags,
|
||||||
|
@RequestParam(required = false) String workbookId,
|
||||||
|
@RequestParam(required = false) String workspaceId) throws IOException {
|
||||||
|
T.VerifyUtil.is(workspaceId).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY);
|
||||||
|
|
||||||
|
PcapEntity pcapEntity = pcapService.savePcap(file.getResource(), tags, workbookId, workspaceId);
|
||||||
|
return R.ok().putData("id", pcapEntity.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public R delete(@PathVariable("id") String id) {
|
||||||
|
pcapService.deletePcap(id);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
package net.geedge.asw.module.runner.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaIgnore;
|
||||||
|
import cn.hutool.core.lang.Opt;
|
||||||
|
import cn.hutool.log.Log;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import net.geedge.asw.common.util.R;
|
||||||
|
import net.geedge.asw.common.util.RCode;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.app.entity.PackageEntity;
|
||||||
|
import net.geedge.asw.module.runner.entity.JobEntity;
|
||||||
|
import net.geedge.asw.module.runner.entity.PlaybookEntity;
|
||||||
|
import net.geedge.asw.module.runner.entity.RunnerEntity;
|
||||||
|
import net.geedge.asw.module.runner.service.IJobService;
|
||||||
|
import net.geedge.asw.module.runner.service.IRunnerService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/runner")
|
||||||
|
public class RunnerController {
|
||||||
|
|
||||||
|
private static final Log log = Log.get();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IJobService jobService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IRunnerService runnerService;
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public R detail(@PathVariable("id") String id) {
|
||||||
|
RunnerEntity runnerEntity = runnerService.getById(id);
|
||||||
|
return R.ok().putData("record", runnerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public R list(@RequestParam Map<String, Object> params) {
|
||||||
|
T.VerifyUtil.is(params).notNull()
|
||||||
|
.and(T.MapUtil.getStr(params, "workspaceId")).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY);
|
||||||
|
|
||||||
|
Page page = runnerService.queryList(params);
|
||||||
|
return R.ok(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public R add(@RequestBody RunnerEntity entity) {
|
||||||
|
T.VerifyUtil.is(entity).notNull()
|
||||||
|
.and(entity.getWorkspaceId()).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY);
|
||||||
|
|
||||||
|
RunnerEntity runner = runnerService.saveRunner(entity);
|
||||||
|
return R.ok().putData("record", runner);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
public R update(@RequestBody RunnerEntity entity) {
|
||||||
|
T.VerifyUtil.is(entity).notNull()
|
||||||
|
.and(entity.getId()).notEmpty(RCode.ID_CANNOT_EMPTY)
|
||||||
|
.and(entity.getWorkspaceId()).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY);
|
||||||
|
|
||||||
|
RunnerEntity runner = runnerService.updateRunner(entity);
|
||||||
|
return R.ok().putData("record", runner);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public R delete(@PathVariable("id") String id) {
|
||||||
|
runnerService.removeById(id);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SaIgnore
|
||||||
|
@PostMapping("/register")
|
||||||
|
public void register(@RequestHeader("Authorization") String token, HttpServletResponse response) throws IOException {
|
||||||
|
RunnerEntity runner = runnerService.getOne(new LambdaUpdateWrapper<RunnerEntity>().eq(RunnerEntity::getToken, token));
|
||||||
|
String status = Opt.ofNullable(runner).map(RunnerEntity::getStatus).orElseGet(() -> null);
|
||||||
|
if (!T.StrUtil.equals("online", status)) {
|
||||||
|
log.warn("[register] [runner is offline] [token: {}]", token);
|
||||||
|
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Runner is offline");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SaIgnore
|
||||||
|
@PostMapping("/heartbeat")
|
||||||
|
public void heartbeat(@RequestHeader("Authorization") String token, @RequestBody Map<String, Integer> platformMap,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
RunnerEntity runner = runnerService.getOne(new LambdaUpdateWrapper<RunnerEntity>().eq(RunnerEntity::getToken, token));
|
||||||
|
String status = Opt.ofNullable(runner).map(RunnerEntity::getStatus).orElseGet(() -> null);
|
||||||
|
if (!T.StrUtil.equals("online", status)) {
|
||||||
|
log.warn("[heartbeat] [runner is offline] [token: {}]", token);
|
||||||
|
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Runner is offline");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update last_heartbeat_timestamp
|
||||||
|
runnerService.update(new LambdaUpdateWrapper<RunnerEntity>()
|
||||||
|
.set(RunnerEntity::getLastHeartbeatTimestamp, System.currentTimeMillis())
|
||||||
|
.eq(RunnerEntity::getId, runner.getId()));
|
||||||
|
|
||||||
|
// findjob by platform
|
||||||
|
String platform = platformMap.entrySet().stream().filter(entry -> entry.getValue() > 0).findFirst().map(entry -> entry.getKey()).orElseGet(null);
|
||||||
|
JobEntity job = jobService.assignPendingJob(runner.getId(), platform);
|
||||||
|
if (T.ObjectUtil.isNotNull(job)) {
|
||||||
|
// package
|
||||||
|
PackageEntity pkg = job.getPkg();
|
||||||
|
Map<String, String> pkgInfo = T.MapUtil.builder("id", pkg.getId())
|
||||||
|
.put("platform", pkg.getPlatform())
|
||||||
|
.put("identifier", pkg.getIdentifier())
|
||||||
|
.put("version", pkg.getVersion())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// playbook
|
||||||
|
PlaybookEntity playbook = job.getPlaybook();
|
||||||
|
Map<String, String> pbInfo = T.MapUtil.builder("id", playbook.getId())
|
||||||
|
.put("name", playbook.getName())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// response job info
|
||||||
|
Map<Object, Object> responseData = T.MapUtil.builder()
|
||||||
|
.put("id", job.getId())
|
||||||
|
.put("pkg", pkgInfo)
|
||||||
|
.put("playbook", pbInfo)
|
||||||
|
.build();
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
response.setContentType("text/html; charset=UTF-8");
|
||||||
|
response.getWriter().write(T.JSONUtil.toJsonStr(responseData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SaIgnore
|
||||||
|
@PutMapping("/trace/{jobId}")
|
||||||
|
public void trace(@RequestHeader("Authorization") String token, @PathVariable String jobId, @RequestBody byte[] bytes,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
RunnerEntity runner = runnerService.getOne(new LambdaUpdateWrapper<RunnerEntity>().eq(RunnerEntity::getToken, token));
|
||||||
|
String status = Opt.ofNullable(runner).map(RunnerEntity::getStatus).orElseGet(() -> null);
|
||||||
|
if (!T.StrUtil.equals("online", status)) {
|
||||||
|
log.warn("[trace] [runner is offline] [token: {}]", token);
|
||||||
|
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Runner is offline");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 追加到文件中
|
||||||
|
String content = T.StrUtil.str(bytes, T.CharsetUtil.CHARSET_UTF_8);
|
||||||
|
jobService.appendTraceLogStrToFile(jobId, content);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[trace] [error] [job: {}]", jobId);
|
||||||
|
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SaIgnore
|
||||||
|
@PutMapping("/jobResult/{jobId}")
|
||||||
|
public void jobResult(@RequestHeader("Authorization") String token, @PathVariable String jobId, @RequestParam String state,
|
||||||
|
@RequestParam(value = "file", required = false) MultipartFile pcapFile,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
RunnerEntity runner = runnerService.getOne(new LambdaUpdateWrapper<RunnerEntity>().eq(RunnerEntity::getToken, token));
|
||||||
|
String status = Opt.ofNullable(runner).map(RunnerEntity::getStatus).orElseGet(() -> null);
|
||||||
|
if (!T.StrUtil.equals("online", status)) {
|
||||||
|
log.warn("[trace] [runner is offline] [token: {}]", token);
|
||||||
|
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Runner is offline");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新任务状态
|
||||||
|
jobService.updateJobResult(jobId, state, pcapFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.geedge.asw.module.runner.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import net.geedge.asw.module.runner.entity.DecodeRecordEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface DecodeRecordDao extends BaseMapper<DecodeRecordEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
19
src/main/java/net/geedge/asw/module/runner/dao/JobDao.java
Normal file
19
src/main/java/net/geedge/asw/module/runner/dao/JobDao.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package net.geedge.asw.module.runner.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import net.geedge.asw.module.runner.entity.JobEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface JobDao extends BaseMapper<JobEntity>{
|
||||||
|
|
||||||
|
List<JobEntity> queryList(IPage page, Map<String, Object> params);
|
||||||
|
|
||||||
|
JobEntity getPendingJobByPlatform(@Param("platform") String platform);
|
||||||
|
|
||||||
|
}
|
||||||
16
src/main/java/net/geedge/asw/module/runner/dao/PcapDao.java
Normal file
16
src/main/java/net/geedge/asw/module/runner/dao/PcapDao.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package net.geedge.asw.module.runner.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import net.geedge.asw.module.runner.entity.PcapEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface PcapDao extends BaseMapper<PcapEntity>{
|
||||||
|
|
||||||
|
List<PcapEntity> queryList(Page page, Map<String, Object> params);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.geedge.asw.module.runner.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import net.geedge.asw.module.runner.entity.PlaybookEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface PlaybookDao extends BaseMapper<PlaybookEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package net.geedge.asw.module.runner.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import net.geedge.asw.module.runner.entity.RunnerEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface RunnerDao extends BaseMapper<RunnerEntity>{
|
||||||
|
|
||||||
|
List<RunnerEntity> queryList(Page page, Map<String, Object> params);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package net.geedge.asw.module.runner.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("decode_record")
|
||||||
|
public class DecodeRecordEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
private String id;
|
||||||
|
private String pcapId;
|
||||||
|
private Long streamId;
|
||||||
|
private String streamAttributes;
|
||||||
|
private String workspaceId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package net.geedge.asw.module.runner.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import net.geedge.asw.module.app.entity.ApplicationEntity;
|
||||||
|
import net.geedge.asw.module.app.entity.PackageEntity;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("job")
|
||||||
|
public class JobEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
private String id;
|
||||||
|
private String playbookId;
|
||||||
|
private String packageId;
|
||||||
|
private String runnerId;
|
||||||
|
private String scheduleId;
|
||||||
|
private String signatureIds;
|
||||||
|
private String tags;
|
||||||
|
private Long startTimestamp;
|
||||||
|
private Long endTimestamp;
|
||||||
|
private String status;
|
||||||
|
private String pcapId;
|
||||||
|
private String logPath;
|
||||||
|
|
||||||
|
private Long createTimestamp;
|
||||||
|
private Long updateTimestamp;
|
||||||
|
private String createUserId;
|
||||||
|
private String updateUserId;
|
||||||
|
|
||||||
|
private String workspaceId;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String workbookId;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private ApplicationEntity application;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
@JsonProperty(value = "package")
|
||||||
|
private PackageEntity pkg;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private RunnerEntity runner;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private PlaybookEntity playbook;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package net.geedge.asw.module.runner.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import net.geedge.asw.module.app.entity.ApplicationEntity;
|
||||||
|
import net.geedge.asw.module.app.entity.PackageEntity;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("pcap")
|
||||||
|
public class PcapEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String tags;
|
||||||
|
private String description;
|
||||||
|
private String path;
|
||||||
|
private Long size;
|
||||||
|
private Long connections;
|
||||||
|
private Long hosts;
|
||||||
|
private String md5;
|
||||||
|
private Long connectionTimeFirst;
|
||||||
|
private Long connectionTimeLast;
|
||||||
|
private String protocols;
|
||||||
|
private String status;
|
||||||
|
private Long createTimestamp;
|
||||||
|
private String createUserId;
|
||||||
|
private String workspaceId;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String jobId;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private ApplicationEntity application;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
@JsonProperty(value = "package")
|
||||||
|
private PackageEntity pkg;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private RunnerEntity runner;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private PlaybookEntity playbook;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package net.geedge.asw.module.runner.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("playbook")
|
||||||
|
public class PlaybookEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String appId;
|
||||||
|
private String tags;
|
||||||
|
private String script;
|
||||||
|
private Long opVersion;
|
||||||
|
|
||||||
|
private Long createTimestamp;
|
||||||
|
private Long updateTimestamp;
|
||||||
|
private String createUserId;
|
||||||
|
private String updateUserId;
|
||||||
|
|
||||||
|
private String workspaceId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package net.geedge.asw.module.runner.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("runner")
|
||||||
|
public class RunnerEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String token;
|
||||||
|
private String tags;
|
||||||
|
private String supportPlatforms;
|
||||||
|
private Integer shareFlag;
|
||||||
|
private String description;
|
||||||
|
private String status;
|
||||||
|
private Long lastHeartbeatTimestamp;
|
||||||
|
|
||||||
|
private Long createTimestamp;
|
||||||
|
private Long updateTimestamp;
|
||||||
|
private String createUserId;
|
||||||
|
private String updateUserId;
|
||||||
|
|
||||||
|
private String workspaceId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package net.geedge.asw.module.runner.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.runner.entity.DecodeRecordEntity;
|
||||||
|
|
||||||
|
public interface IDecodeRecordService extends IService<DecodeRecordEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package net.geedge.asw.module.runner.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.runner.entity.JobEntity;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface IJobService extends IService<JobEntity>{
|
||||||
|
|
||||||
|
JobEntity queryInfo(String id);
|
||||||
|
|
||||||
|
Page queryList(Map<String, Object> params);
|
||||||
|
|
||||||
|
JobEntity saveJob(JobEntity entity);
|
||||||
|
|
||||||
|
void removeJob(List<String> ids);
|
||||||
|
|
||||||
|
JobEntity assignPendingJob(String id, String platform);
|
||||||
|
|
||||||
|
void appendTraceLogStrToFile(String jobId, String content) throws RuntimeException;
|
||||||
|
|
||||||
|
void updateJobResult(String jobId, String state, MultipartFile pcapFile);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package net.geedge.asw.module.runner.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.runner.entity.PcapEntity;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface IPcapService extends IService<PcapEntity>{
|
||||||
|
|
||||||
|
PcapEntity queryInfo(String id);
|
||||||
|
|
||||||
|
Page queryList(Map<String, Object> params);
|
||||||
|
|
||||||
|
PcapEntity savePcap(String jobId, Resource fileResource);
|
||||||
|
|
||||||
|
PcapEntity savePcap(Resource fileResource,String... params);
|
||||||
|
|
||||||
|
void deletePcap(String id);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package net.geedge.asw.module.runner.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.runner.entity.PlaybookEntity;
|
||||||
|
|
||||||
|
public interface IPlaybookService extends IService<PlaybookEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package net.geedge.asw.module.runner.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.runner.entity.RunnerEntity;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface IRunnerService extends IService<RunnerEntity>{
|
||||||
|
|
||||||
|
Page queryList(Map<String, Object> params);
|
||||||
|
|
||||||
|
RunnerEntity saveRunner(RunnerEntity entity);
|
||||||
|
|
||||||
|
RunnerEntity updateRunner(RunnerEntity entity);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package net.geedge.asw.module.runner.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.module.runner.dao.DecodeRecordDao;
|
||||||
|
import net.geedge.asw.module.runner.entity.DecodeRecordEntity;
|
||||||
|
import net.geedge.asw.module.runner.service.IDecodeRecordService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class DecodeRecordServiceImpl extends ServiceImpl<DecodeRecordDao, DecodeRecordEntity> implements IDecodeRecordService {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
package net.geedge.asw.module.runner.service.impl;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import cn.hutool.core.io.IORuntimeException;
|
||||||
|
import cn.hutool.log.Log;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.common.util.RCode;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.app.entity.ApplicationEntity;
|
||||||
|
import net.geedge.asw.module.app.entity.PackageEntity;
|
||||||
|
import net.geedge.asw.module.app.service.IApplicationService;
|
||||||
|
import net.geedge.asw.module.app.service.IPackageService;
|
||||||
|
import net.geedge.asw.module.runner.dao.JobDao;
|
||||||
|
import net.geedge.asw.module.runner.entity.JobEntity;
|
||||||
|
import net.geedge.asw.module.runner.entity.PcapEntity;
|
||||||
|
import net.geedge.asw.module.runner.entity.PlaybookEntity;
|
||||||
|
import net.geedge.asw.module.runner.entity.RunnerEntity;
|
||||||
|
import net.geedge.asw.module.runner.service.IJobService;
|
||||||
|
import net.geedge.asw.module.runner.service.IPcapService;
|
||||||
|
import net.geedge.asw.module.runner.service.IPlaybookService;
|
||||||
|
import net.geedge.asw.module.runner.service.IRunnerService;
|
||||||
|
import net.geedge.asw.module.runner.util.RunnerConstant;
|
||||||
|
import net.geedge.asw.module.workbook.service.IWorkbookResourceService;
|
||||||
|
import net.geedge.asw.module.workbook.util.WorkbookConstant;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class JobServiceImpl extends ServiceImpl<JobDao, JobEntity> implements IJobService {
|
||||||
|
|
||||||
|
private static final Log log = Log.get();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IPcapService pcapService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IRunnerService runnerService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IPlaybookService playbookService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IPackageService packageService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IApplicationService applicationService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IWorkbookResourceService workbookResourceService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rootPath/result/{jobId}
|
||||||
|
*
|
||||||
|
* @param jobId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getJobResultPath(String jobId) {
|
||||||
|
return T.FileUtil.file(T.WebPathUtil.getRootPath(), "result", jobId).getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JobEntity queryInfo(String id) {
|
||||||
|
JobEntity job = this.getById(id);
|
||||||
|
T.VerifyUtil.is(job).notNull(RCode.SYS_RECORD_NOT_FOUND);
|
||||||
|
|
||||||
|
RunnerEntity runner = runnerService.getById(job.getRunnerId());
|
||||||
|
job.setRunner(runner);
|
||||||
|
|
||||||
|
PlaybookEntity playbook = playbookService.getById(job.getPlaybookId());
|
||||||
|
job.setPlaybook(playbook);
|
||||||
|
|
||||||
|
PackageEntity pkg = packageService.getById(job.getPackageId());
|
||||||
|
job.setPkg(pkg);
|
||||||
|
|
||||||
|
if (T.ObjectUtil.isNotNull(playbook)) {
|
||||||
|
ApplicationEntity application = applicationService.getById(playbook.getAppId());
|
||||||
|
job.setApplication(application);
|
||||||
|
}
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page queryList(Map<String, Object> params) {
|
||||||
|
Page page = T.PageUtil.getPage(params);
|
||||||
|
List<JobEntity> jobList = this.getBaseMapper().queryList(page, params);
|
||||||
|
page.setRecords(jobList);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public JobEntity saveJob(JobEntity entity) {
|
||||||
|
entity.setCreateTimestamp(System.currentTimeMillis());
|
||||||
|
entity.setUpdateTimestamp(System.currentTimeMillis());
|
||||||
|
entity.setCreateUserId(StpUtil.getLoginIdAsString());
|
||||||
|
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
|
||||||
|
|
||||||
|
// save
|
||||||
|
this.save(entity);
|
||||||
|
|
||||||
|
// workbook resource
|
||||||
|
workbookResourceService.saveResource(entity.getWorkbookId(), entity.getId(), WorkbookConstant.ResourceType.JOB.getValue());
|
||||||
|
|
||||||
|
// trace log file path
|
||||||
|
File traceLogFile = T.FileUtil.file(this.getJobResultPath(entity.getId()), "trace.log");
|
||||||
|
this.update(new LambdaUpdateWrapper<JobEntity>()
|
||||||
|
.set(JobEntity::getLogPath, traceLogFile.getPath())
|
||||||
|
.eq(JobEntity::getId, entity.getId()));
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void removeJob(List<String> ids) {
|
||||||
|
// remove
|
||||||
|
this.removeBatchByIds(ids);
|
||||||
|
// workbook resource
|
||||||
|
workbookResourceService.removeResource(ids, WorkbookConstant.ResourceType.JOB.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized JobEntity assignPendingJob(String runnerId, String platform) {
|
||||||
|
if (T.StrUtil.hasEmpty(runnerId, platform)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
JobEntity job = this.getBaseMapper().getPendingJobByPlatform(platform);
|
||||||
|
if (T.ObjectUtil.isNotNull(job)) {
|
||||||
|
// update
|
||||||
|
this.update(new LambdaUpdateWrapper<JobEntity>()
|
||||||
|
.set(JobEntity::getRunnerId, runnerId)
|
||||||
|
.set(JobEntity::getStatus, RunnerConstant.JobStatus.RUNNING.getValue())
|
||||||
|
.set(JobEntity::getStartTimestamp, System.currentTimeMillis())
|
||||||
|
.eq(JobEntity::getId, job.getId())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendTraceLogStrToFile(String jobId, String content) throws RuntimeException {
|
||||||
|
try {
|
||||||
|
JobEntity job = this.getById(jobId);
|
||||||
|
if (T.StrUtil.isEmpty(job.getLogPath())) {
|
||||||
|
File traceLogFile = T.FileUtil.file(this.getJobResultPath(jobId), "trace.log");
|
||||||
|
job.setLogPath(traceLogFile.getPath());
|
||||||
|
}
|
||||||
|
// append content
|
||||||
|
T.FileUtil.appendString(content, T.FileUtil.file(job.getLogPath()), T.CharsetUtil.CHARSET_UTF_8);
|
||||||
|
} catch (IORuntimeException e) {
|
||||||
|
log.error(e, "[appendTraceLogStrToFile] [error] [job: {}] [content: {}]", jobId, content);
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void updateJobResult(String jobId, String state, MultipartFile pcapFile) {
|
||||||
|
String pcapId = T.StrUtil.EMPTY;
|
||||||
|
// save pcap file
|
||||||
|
if (T.ObjectUtil.isNotNull(pcapFile)) {
|
||||||
|
PcapEntity pcapEntity = pcapService.savePcap(jobId, pcapFile.getResource());
|
||||||
|
pcapId = pcapEntity.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// update job status&pcap_id
|
||||||
|
state = T.StrUtil.equals("success", state) ? RunnerConstant.JobStatus.PASSED.getValue() : state;
|
||||||
|
this.update(new LambdaUpdateWrapper<JobEntity>()
|
||||||
|
.set(JobEntity::getStatus, state)
|
||||||
|
.set(T.StrUtil.isNotEmpty(pcapId), JobEntity::getPcapId, pcapId)
|
||||||
|
.set(JobEntity::getEndTimestamp, System.currentTimeMillis())
|
||||||
|
.eq(JobEntity::getId, jobId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
package net.geedge.asw.module.runner.service.impl;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import cn.hutool.log.Log;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.common.util.RCode;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.app.entity.ApplicationEntity;
|
||||||
|
import net.geedge.asw.module.app.entity.PackageEntity;
|
||||||
|
import net.geedge.asw.module.app.service.IApplicationService;
|
||||||
|
import net.geedge.asw.module.app.service.IPackageService;
|
||||||
|
import net.geedge.asw.module.runner.dao.PcapDao;
|
||||||
|
import net.geedge.asw.module.runner.entity.JobEntity;
|
||||||
|
import net.geedge.asw.module.runner.entity.PcapEntity;
|
||||||
|
import net.geedge.asw.module.runner.entity.PlaybookEntity;
|
||||||
|
import net.geedge.asw.module.runner.entity.RunnerEntity;
|
||||||
|
import net.geedge.asw.module.runner.service.IJobService;
|
||||||
|
import net.geedge.asw.module.runner.service.IPcapService;
|
||||||
|
import net.geedge.asw.module.runner.service.IPlaybookService;
|
||||||
|
import net.geedge.asw.module.runner.service.IRunnerService;
|
||||||
|
import net.geedge.asw.module.runner.util.PcapParserThread;
|
||||||
|
import net.geedge.asw.module.runner.util.RunnerConstant;
|
||||||
|
import net.geedge.asw.module.workbook.service.IWorkbookResourceService;
|
||||||
|
import net.geedge.asw.module.workbook.util.WorkbookConstant;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class PcapServiceImpl extends ServiceImpl<PcapDao, PcapEntity> implements IPcapService {
|
||||||
|
private static final Log log = Log.get();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IJobService jobService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IRunnerService runnerService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IPlaybookService playbookService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IPackageService packageService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IApplicationService applicationService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IWorkbookResourceService workbookResourceService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PcapEntity queryInfo(String id) {
|
||||||
|
PcapEntity pcap = this.getById(id);
|
||||||
|
T.VerifyUtil.is(pcap).notNull(RCode.SYS_RECORD_NOT_FOUND);
|
||||||
|
|
||||||
|
JobEntity job = jobService.getOne(new LambdaQueryWrapper<JobEntity>().eq(JobEntity::getPcapId, pcap.getId()));
|
||||||
|
if (T.ObjectUtil.isNotNull(job)) {
|
||||||
|
pcap.setJobId(job.getId());
|
||||||
|
|
||||||
|
RunnerEntity runner = runnerService.getById(job.getRunnerId());
|
||||||
|
pcap.setRunner(runner);
|
||||||
|
|
||||||
|
PackageEntity pkg = packageService.getById(job.getPackageId());
|
||||||
|
pcap.setPkg(pkg);
|
||||||
|
|
||||||
|
PlaybookEntity playbook = playbookService.getById(job.getPlaybookId());
|
||||||
|
pcap.setPlaybook(playbook);
|
||||||
|
|
||||||
|
if (T.ObjectUtil.isNotNull(playbook)) {
|
||||||
|
ApplicationEntity application = applicationService.getById(playbook.getAppId());
|
||||||
|
pcap.setApplication(application);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pcap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page queryList(Map<String, Object> params) {
|
||||||
|
Page page = T.PageUtil.getPage(params);
|
||||||
|
List<PcapEntity> pcapList = this.getBaseMapper().queryList(page, params);
|
||||||
|
page.setRecords(pcapList);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PcapEntity savePcap(String jobId, Resource fileResource) {
|
||||||
|
JobEntity job = jobService.getById(jobId);
|
||||||
|
return this.savePcap(fileResource, job.getTags(), job.getWorkbookId(), job.getWorkspaceId(), job.getCreateUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PcapEntity savePcap(Resource fileResource, String... params) {
|
||||||
|
String tags = T.ArrayUtil.get(params, 0);
|
||||||
|
String workbookId = T.ArrayUtil.get(params, 1);
|
||||||
|
String workspaceId = T.ArrayUtil.get(params, 2);
|
||||||
|
String createUserId = T.StrUtil.emptyToDefault(T.ArrayUtil.get(params, 3), StpUtil.getLoginIdAsString());
|
||||||
|
|
||||||
|
PcapEntity entity = new PcapEntity();
|
||||||
|
try {
|
||||||
|
entity.setName(fileResource.getFilename());
|
||||||
|
entity.setTags(T.StrUtil.emptyToDefault(tags, ""));
|
||||||
|
|
||||||
|
byte[] bytes = fileResource.getInputStream().readAllBytes();
|
||||||
|
entity.setSize((long) bytes.length);
|
||||||
|
|
||||||
|
entity.setStatus(RunnerConstant.PcapStatus.UPLOADED.getValue());
|
||||||
|
entity.setCreateTimestamp(System.currentTimeMillis());
|
||||||
|
entity.setCreateUserId(createUserId);
|
||||||
|
entity.setWorkspaceId(workspaceId);
|
||||||
|
|
||||||
|
// path
|
||||||
|
File destination = T.FileUtil.file(T.WebPathUtil.getRootPath(), workspaceId, fileResource.getFilename());
|
||||||
|
FileUtils.copyInputStreamToFile(fileResource.getInputStream(), destination);
|
||||||
|
entity.setPath(destination.getPath());
|
||||||
|
|
||||||
|
// md5
|
||||||
|
String md5Hex = T.DigestUtil.md5Hex(destination);
|
||||||
|
entity.setMd5(md5Hex);
|
||||||
|
|
||||||
|
// 根据文件 md5值 判断是否已上存在,存在则响应当前实体
|
||||||
|
PcapEntity findPcapByMd5 = this.getOne(new LambdaQueryWrapper<PcapEntity>().eq(PcapEntity::getMd5, md5Hex));
|
||||||
|
if (T.ObjectUtil.isNotNull(findPcapByMd5)) {
|
||||||
|
// 删除本次记录的文件
|
||||||
|
T.FileUtil.del(destination);
|
||||||
|
return findPcapByMd5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// save
|
||||||
|
this.save(entity);
|
||||||
|
|
||||||
|
// workbook resource
|
||||||
|
workbookResourceService.saveResource(workbookId, entity.getId(), WorkbookConstant.ResourceType.PCAP.getValue());
|
||||||
|
|
||||||
|
// parser
|
||||||
|
PcapParserThread pcapParserThread = new PcapParserThread();
|
||||||
|
pcapParserThread.setPcapEntity(entity);
|
||||||
|
T.ThreadUtil.execAsync(pcapParserThread);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e, "[savePcap] [error] [workspaceId: {}]", workspaceId);
|
||||||
|
}
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void deletePcap(String pcapId) {
|
||||||
|
PcapEntity pcap = this.getById(pcapId);
|
||||||
|
// remove file
|
||||||
|
T.FileUtil.del(pcap.getPath());
|
||||||
|
|
||||||
|
// remove
|
||||||
|
this.removeById(pcapId);
|
||||||
|
|
||||||
|
// update job pcap_id
|
||||||
|
jobService.update(new LambdaUpdateWrapper<JobEntity>()
|
||||||
|
.set(JobEntity::getPcapId, "")
|
||||||
|
.eq(JobEntity::getPcapId, pcapId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package net.geedge.asw.module.runner.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.module.runner.dao.PlaybookDao;
|
||||||
|
import net.geedge.asw.module.runner.entity.PlaybookEntity;
|
||||||
|
import net.geedge.asw.module.runner.service.IPlaybookService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class PlaybookServiceImpl extends ServiceImpl<PlaybookDao, PlaybookEntity> implements IPlaybookService {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package net.geedge.asw.module.runner.service.impl;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.runner.dao.RunnerDao;
|
||||||
|
import net.geedge.asw.module.runner.entity.RunnerEntity;
|
||||||
|
import net.geedge.asw.module.runner.service.IRunnerService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class RunnerServiceImpl extends ServiceImpl<RunnerDao, RunnerEntity> implements IRunnerService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page queryList(Map<String, Object> params) {
|
||||||
|
Page page = T.PageUtil.getPage(params);
|
||||||
|
List<RunnerEntity> jobList = this.getBaseMapper().queryList(page, params);
|
||||||
|
page.setRecords(jobList);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RunnerEntity saveRunner(RunnerEntity entity) {
|
||||||
|
entity.setCreateTimestamp(System.currentTimeMillis());
|
||||||
|
entity.setUpdateTimestamp(System.currentTimeMillis());
|
||||||
|
entity.setCreateUserId(StpUtil.getLoginIdAsString());
|
||||||
|
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
|
||||||
|
|
||||||
|
// token
|
||||||
|
entity.setToken(T.IdUtil.fastSimpleUUID());
|
||||||
|
|
||||||
|
// save
|
||||||
|
this.save(entity);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RunnerEntity updateRunner(RunnerEntity entity) {
|
||||||
|
entity.setUpdateTimestamp(System.currentTimeMillis());
|
||||||
|
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
|
||||||
|
|
||||||
|
// update
|
||||||
|
this.updateById(entity);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package net.geedge.asw.module.runner.util;
|
||||||
|
|
||||||
|
import cn.hutool.log.Log;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import lombok.Data;
|
||||||
|
import net.geedge.asw.common.config.SpringContextUtils;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.runner.entity.PcapEntity;
|
||||||
|
import net.geedge.asw.module.runner.service.IPcapService;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PcapParserThread implements Runnable {
|
||||||
|
|
||||||
|
private Log log = Log.get();
|
||||||
|
|
||||||
|
private PcapEntity pcapEntity;
|
||||||
|
private IPcapService pcapService;
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
pcapService = SpringContextUtils.getBean(IPcapService.class);
|
||||||
|
// analyzing
|
||||||
|
this.updatePcapStatus(RunnerConstant.PcapStatus.ANALYZING.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Thread.currentThread().setName("pcap-parser-thread-" + pcapEntity.getId());
|
||||||
|
log.info("job pcap parser start");
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("pcapInfo: {}", T.JSONUtil.toJsonStr(pcapEntity));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
log.info("job pcap parser run start");
|
||||||
|
// init
|
||||||
|
this.init();
|
||||||
|
// parser
|
||||||
|
this.parser();
|
||||||
|
log.info("job pcap parser run end");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e, "job pcap parser error, pcap: {}", pcapEntity.getId());
|
||||||
|
} finally {
|
||||||
|
// completed
|
||||||
|
this.updatePcapStatus(RunnerConstant.PcapStatus.COMPLETED.getValue());
|
||||||
|
log.info("job pcap parser end");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parser
|
||||||
|
*/
|
||||||
|
private void parser() {
|
||||||
|
String id = pcapEntity.getId();
|
||||||
|
String path = pcapEntity.getPath();
|
||||||
|
SignatureExtract signatureExtract = new SignatureExtract(id, path);
|
||||||
|
// signature
|
||||||
|
String signature = signatureExtract.signature();
|
||||||
|
// 保存结果,和 pcap 文件同目录,文件名:pcap_id_signature.json
|
||||||
|
String parentPath = T.FileUtil.getParent(path, 1);
|
||||||
|
File signatureFile = T.FileUtil.file(parentPath, id + "_signature.json");
|
||||||
|
T.FileUtil.del(signatureFile);
|
||||||
|
T.FileUtil.writeUtf8String(signature, signatureFile);
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update pcap status
|
||||||
|
*
|
||||||
|
* @param status
|
||||||
|
*/
|
||||||
|
private void updatePcapStatus(String status) {
|
||||||
|
pcapService.update(new LambdaUpdateWrapper<PcapEntity>()
|
||||||
|
.set(PcapEntity::getStatus, status)
|
||||||
|
.eq(PcapEntity::getId, pcapEntity.getId())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package net.geedge.asw.module.runner.util;
|
||||||
|
|
||||||
|
public class RunnerConstant {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* job status
|
||||||
|
*/
|
||||||
|
public enum JobStatus {
|
||||||
|
CREATED("created"),
|
||||||
|
|
||||||
|
PENDING("pending"),
|
||||||
|
|
||||||
|
RUNNING("running"),
|
||||||
|
|
||||||
|
PASSED("passed"),
|
||||||
|
|
||||||
|
FAILED("failed"),
|
||||||
|
|
||||||
|
CANCEL("cancel");
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
JobStatus(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pcap status
|
||||||
|
*/
|
||||||
|
public enum PcapStatus {
|
||||||
|
UPLOADED("Uploaded"),
|
||||||
|
|
||||||
|
ANALYZING("Analyzing"),
|
||||||
|
|
||||||
|
COMPLETED("Completed");
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
PcapStatus(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
package net.geedge.asw.module.runner.util;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONArray;
|
||||||
|
import cn.hutool.json.JSONConfig;
|
||||||
|
import cn.hutool.log.Log;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import net.geedge.asw.common.config.SpringContextUtils;
|
||||||
|
import net.geedge.asw.common.util.ASWException;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import org.apache.commons.lang3.time.StopWatch;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class SignatureExtract {
|
||||||
|
|
||||||
|
private static final Log log = Log.get();
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
private String tsharkPath = "/usr/bin/tshark";
|
||||||
|
|
||||||
|
public SignatureExtract(String id, String path) {
|
||||||
|
this.id = id;
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* signature
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String signature() {
|
||||||
|
log.info("[signature] [begin] [id: {}] [path: {}]", id, path);
|
||||||
|
StopWatch sw = new StopWatch();
|
||||||
|
sw.start();
|
||||||
|
try {
|
||||||
|
this.tsharkPath = SpringContextUtils.getProperty("tshark.path", "/usr/bin/tshark");
|
||||||
|
log.info("[signature] [tshark path: {}]", this.tsharkPath);
|
||||||
|
|
||||||
|
SignatureUtil signatureObject = new SignatureUtil(this.tsharkPath);
|
||||||
|
signatureObject.getStreamSignatureFromTshrak(path);
|
||||||
|
|
||||||
|
List<Map<String, String>> allFrameSignatureDictList = signatureObject.getOutputDictList();
|
||||||
|
|
||||||
|
// Get basic information of TCP data streams
|
||||||
|
List<Map<String, Object>> tcpStreamBasicInfoList = SignatureUtil.getTCPStreamBaseInfo(allFrameSignatureDictList);
|
||||||
|
List<Map<String, Object>> tcpStreamAllInfoList = T.ListUtil.list(false, tcpStreamBasicInfoList);
|
||||||
|
|
||||||
|
// Get other information of TCP data streams
|
||||||
|
// Processing data stream by stream
|
||||||
|
for (int i = 0; i < tcpStreamAllInfoList.size(); i++) {
|
||||||
|
String streamID = T.MapUtil.getStr(tcpStreamAllInfoList.get(i), "StreamID");
|
||||||
|
// Get all the Frame IDs of the data stream
|
||||||
|
List<Map<String, String>> tcpFrameSignatureList = signatureObject.getOneTcpFrameSignatureList(streamID);
|
||||||
|
|
||||||
|
// Merge signature information from all Frame IDs
|
||||||
|
// TCP data flow analysis
|
||||||
|
this.tcpDataFlowAnalysis(signatureObject, tcpStreamAllInfoList.get(i), tcpFrameSignatureList);
|
||||||
|
// General data flow analysis (common, ip, dns, http, ssl)
|
||||||
|
this.generalDataFlowAnalysis(signatureObject, tcpStreamAllInfoList.get(i), tcpFrameSignatureList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get basic information of UDP data streams
|
||||||
|
List<Map<String, Object>> udpStreamBaseInfo = SignatureUtil.getUDPStreamBaseInfo(allFrameSignatureDictList);
|
||||||
|
List<Map<String, Object>> udpStreamAllInfoList = T.ListUtil.list(false, udpStreamBaseInfo);
|
||||||
|
// Get other information of UDP data streams
|
||||||
|
// Processing data stream by stream
|
||||||
|
for (int i = 0; i < udpStreamAllInfoList.size(); i++) {
|
||||||
|
String streamID = T.MapUtil.getStr(udpStreamAllInfoList.get(i), "StreamID");
|
||||||
|
// Get all the Frame IDs of the data stream
|
||||||
|
List<Map<String, String>> udpFrameSignatureList = signatureObject.getOneUdpFrameSignatureList(streamID);
|
||||||
|
// Merge signature information from all Frame IDs
|
||||||
|
// UDP data flow analysis
|
||||||
|
this.udpDataFlowAnalysis(signatureObject, udpStreamAllInfoList.get(i), udpFrameSignatureList);
|
||||||
|
// General data flow analysis (common, ip, dns, http, ssl)
|
||||||
|
this.generalDataFlowAnalysis(signatureObject, udpStreamAllInfoList.get(i), udpFrameSignatureList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// result
|
||||||
|
List<Object> resultOutputDict = T.ListUtil.list(true);
|
||||||
|
resultOutputDict.addAll(tcpStreamAllInfoList);
|
||||||
|
resultOutputDict.addAll(udpStreamAllInfoList);
|
||||||
|
|
||||||
|
JSONConfig jsonConfig = new JSONConfig();
|
||||||
|
jsonConfig.setKeyComparator(Comparator.comparing(String::toString));
|
||||||
|
JSONArray jsonArray = new JSONArray(resultOutputDict, jsonConfig);
|
||||||
|
return jsonArray.toJSONString(0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e, "[signature] [error] [id: {}] [path: {}]", id, path);
|
||||||
|
throw new ASWException("pcap file parse error. pcap id: " + id);
|
||||||
|
} finally {
|
||||||
|
sw.stop();
|
||||||
|
log.info("[signature] [finshed] [id: {}] [Run Time: {}]", id, sw.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* data field
|
||||||
|
*
|
||||||
|
* @param signatureObject
|
||||||
|
* @param streamDict
|
||||||
|
* @param frameSignatureList
|
||||||
|
*/
|
||||||
|
private void generalDataFlowAnalysis(SignatureUtil signatureObject, Map<String, Object> streamDict, List<Map<String, String>> frameSignatureList) {
|
||||||
|
// common
|
||||||
|
streamDict.put("common.server_fqdn", signatureObject.ssl_extensions_server_name(frameSignatureList));
|
||||||
|
streamDict.put("common.app_id", new String[]{"unknow"});
|
||||||
|
if (T.MapUtil.getStr(frameSignatureList.get(0), "ip.proto").equals("6")) {
|
||||||
|
streamDict.put("srcport", signatureObject.tcp_srcport(frameSignatureList));
|
||||||
|
streamDict.put("dstport", signatureObject.tcp_dstport(frameSignatureList));
|
||||||
|
} else {
|
||||||
|
streamDict.put("srcport", signatureObject.udp_srcport(frameSignatureList));
|
||||||
|
streamDict.put("dstport", signatureObject.udp_dstport(frameSignatureList));
|
||||||
|
}
|
||||||
|
// ip
|
||||||
|
streamDict.put("ip.src", signatureObject.ip_src(frameSignatureList));
|
||||||
|
streamDict.put("ip.dst", signatureObject.ip_dst(frameSignatureList));
|
||||||
|
streamDict.put("ip.proto", signatureObject.ip_proto(frameSignatureList));
|
||||||
|
streamDict.put("heartbeat_flag", signatureObject.heartbeat_flag(frameSignatureList));
|
||||||
|
// dns
|
||||||
|
streamDict.put("dns.qry.name", signatureObject.dns_qry_name(frameSignatureList));
|
||||||
|
// http
|
||||||
|
streamDict.put("http.request.full_uri", signatureObject.http_request_full_uri(frameSignatureList));
|
||||||
|
streamDict.put("http.request.header", signatureObject.http_request_header(frameSignatureList));
|
||||||
|
streamDict.put("http.response.header", signatureObject.http_response_header(frameSignatureList));
|
||||||
|
// ssl
|
||||||
|
streamDict.put("ssl.handshake.certificate.algorithm_identifier", signatureObject.ssl_algorithm_identifier(frameSignatureList));
|
||||||
|
streamDict.put("ssl.handshake.certificate.serial_number", signatureObject.ssl_serial_number(frameSignatureList));
|
||||||
|
streamDict.put("ssl.handshake.certificate.issuer_common_name", signatureObject.ssl_issuer_common_name(frameSignatureList));
|
||||||
|
streamDict.put("ssl.handshake.certificate.issuer_organization_name", signatureObject.ssl_issuer_organization_name(frameSignatureList));
|
||||||
|
streamDict.put("ssl.handshake.certificate.issuer_country_name", signatureObject.ssl_issuer_country_name(frameSignatureList));
|
||||||
|
streamDict.put("ssl.handshake.certificate.subject_common_name", signatureObject.ssl_subject_common_name(frameSignatureList));
|
||||||
|
streamDict.put("ssl.handshake.certificate.subject_organization_name", signatureObject.ssl_subject_organization_name(frameSignatureList));
|
||||||
|
streamDict.put("ssl.handshake.certificate.subject_country_name", signatureObject.ssl_subject_country_name(frameSignatureList));
|
||||||
|
streamDict.put("ssl.handshake.certificate.not_valid_before", signatureObject.ssl_not_valid_before(frameSignatureList));
|
||||||
|
streamDict.put("ssl.handshake.certificate.not_valid_after", signatureObject.ssl_not_valid_after(frameSignatureList));
|
||||||
|
streamDict.put("ssl.handshake.certificate.algorithm_id", signatureObject.ssl_algorithm_id(frameSignatureList));
|
||||||
|
streamDict.put("ssl.analysis.ja3", signatureObject.ssl_ja3(frameSignatureList));
|
||||||
|
streamDict.put("ssl.analysis.sni_absent", signatureObject.ssl_sni_absent(frameSignatureList));
|
||||||
|
streamDict.put("ssl.analysis.ech_enabled", signatureObject.ssl_ech_enabled(frameSignatureList));
|
||||||
|
streamDict.put("ssl.analysis.esni_enabled", signatureObject.ssl_analysis_esni_enabled(frameSignatureList));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* udp
|
||||||
|
*
|
||||||
|
* @param signatureObject
|
||||||
|
* @param streamDict
|
||||||
|
* @param frameSignatureList
|
||||||
|
*/
|
||||||
|
private void udpDataFlowAnalysis(SignatureUtil signatureObject, Map<String, Object> streamDict, List<Map<String, String>> frameSignatureList) {
|
||||||
|
streamDict.put("udp.payload.c2s_first_data", signatureObject.udp_c2s_first_data(frameSignatureList));
|
||||||
|
streamDict.put("udp.payload.s2c_first_data", signatureObject.udp_s2c_first_data(frameSignatureList));
|
||||||
|
streamDict.put("udp.payload.c2s_first_data_len", signatureObject.udp_c2s_first_data_len(frameSignatureList));
|
||||||
|
streamDict.put("udp.payload.s2c_first_data_len", signatureObject.udp_s2c_first_data_len(frameSignatureList));
|
||||||
|
streamDict.put("udp.payload", signatureObject.udp_get_payload(frameSignatureList));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tcp
|
||||||
|
*
|
||||||
|
* @param signatureObject
|
||||||
|
* @param streamDict
|
||||||
|
* @param frameSignatureList
|
||||||
|
*/
|
||||||
|
private void tcpDataFlowAnalysis(SignatureUtil signatureObject, Map<String, Object> streamDict, List<Map<String, String>> frameSignatureList) {
|
||||||
|
streamDict.put("tcp.payload.c2s_first_data", signatureObject.tcp_c2s_first_data(frameSignatureList));
|
||||||
|
streamDict.put("tcp.payload.s2c_first_data", signatureObject.tcp_s2c_first_data(frameSignatureList));
|
||||||
|
streamDict.put("tcp.payload.c2s_first_data_len", signatureObject.tcp_c2s_first_data_len(frameSignatureList));
|
||||||
|
streamDict.put("tcp.payload.s2c_first_data_len", signatureObject.tcp_s2c_first_data_len(frameSignatureList));
|
||||||
|
streamDict.put("tcp.payload", signatureObject.tcp_get_payload(frameSignatureList));
|
||||||
|
}
|
||||||
|
}
|
||||||
1075
src/main/java/net/geedge/asw/module/runner/util/SignatureUtil.java
Normal file
1075
src/main/java/net/geedge/asw/module/runner/util/SignatureUtil.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,5 @@
|
|||||||
package net.geedge.asw.module.sys.controller;
|
package net.geedge.asw.module.sys.controller;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import cn.dev33.satoken.stp.SaTokenInfo;
|
import cn.dev33.satoken.stp.SaTokenInfo;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import net.geedge.asw.common.util.R;
|
import net.geedge.asw.common.util.R;
|
||||||
@@ -16,9 +7,13 @@ import net.geedge.asw.common.util.RCode;
|
|||||||
import net.geedge.asw.common.util.T;
|
import net.geedge.asw.common.util.T;
|
||||||
import net.geedge.asw.module.sys.entity.SysUserEntity;
|
import net.geedge.asw.module.sys.entity.SysUserEntity;
|
||||||
import net.geedge.asw.module.sys.service.ISysAuthService;
|
import net.geedge.asw.module.sys.service.ISysAuthService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/sys")
|
@RequestMapping("/api/v1")
|
||||||
public class SysAuthController {
|
public class SysAuthController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
package net.geedge.asw.module.sys.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import net.geedge.asw.common.util.ASWException;
|
||||||
|
import net.geedge.asw.common.util.R;
|
||||||
|
import net.geedge.asw.common.util.RCode;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.sys.entity.SysI18nEntity;
|
||||||
|
import net.geedge.asw.module.sys.entity.SysUserEntity;
|
||||||
|
import net.geedge.asw.module.sys.service.ISysI18nService;
|
||||||
|
import net.geedge.asw.module.sys.service.ISysUserService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/i18n")
|
||||||
|
public class SysI18nController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysUserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysI18nService sysI18nService;
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public R detail(@PathVariable("id") String id) {
|
||||||
|
SysI18nEntity entity = sysI18nService.getById(id);
|
||||||
|
if (T.ObjectUtil.isNotNull(entity)) {
|
||||||
|
SysUserEntity user = userService.getById(entity.getUpdateUserId());
|
||||||
|
user.setPwd(null);
|
||||||
|
entity.setUpdateUser(user);
|
||||||
|
}
|
||||||
|
return R.ok().putData("record", entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public R list(String ids, String q, String lang, String code, String value,
|
||||||
|
@RequestParam(defaultValue = "1") Integer current,
|
||||||
|
@RequestParam(defaultValue = "20") Integer size,
|
||||||
|
@RequestParam(defaultValue = "name") String orderBy) {
|
||||||
|
QueryWrapper<SysI18nEntity> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.in(T.StrUtil.isNotEmpty(ids), "id", T.StrUtil.split(ids, ','));
|
||||||
|
if (T.StrUtil.isNotBlank(q)) {
|
||||||
|
queryWrapper.and(wrapper -> wrapper.like("lang", q)
|
||||||
|
.or().like("code", q)
|
||||||
|
.or().like("value", q)
|
||||||
|
.or().like("remark", q)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
queryWrapper.eq(T.StrUtil.isNotEmpty(lang), "lang", lang);
|
||||||
|
queryWrapper.like(T.StrUtil.isNotEmpty(code), "code", code);
|
||||||
|
queryWrapper.like(T.StrUtil.isNotEmpty(value), "value", value);
|
||||||
|
Page<SysI18nEntity> page = Page.of(current, size);
|
||||||
|
page.addOrder(T.PageUtil.decodeOrderByStr(orderBy));
|
||||||
|
page = sysI18nService.page(page, queryWrapper);
|
||||||
|
return R.ok(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public R add(@RequestBody SysI18nEntity entity) {
|
||||||
|
T.VerifyUtil.is(entity).notNull()
|
||||||
|
.and(entity.getCode()).notEmpty()
|
||||||
|
.and(entity.getValue()).notEmpty()
|
||||||
|
.and(entity.getLang()).notEmpty();
|
||||||
|
SysI18nEntity one = sysI18nService.getOne(new LambdaQueryWrapper<SysI18nEntity>()
|
||||||
|
.eq(SysI18nEntity::getCode, entity.getCode())
|
||||||
|
.eq(SysI18nEntity::getLang, entity.getLang()));
|
||||||
|
if (T.ObjectUtil.isNotNull(one)) {
|
||||||
|
throw ASWException.builder().rcode(RCode.SYS_DUPLICATE_RECORD).build();
|
||||||
|
}
|
||||||
|
if (T.ObjectUtil.isEmpty(entity.getName())) {
|
||||||
|
entity.setName(entity.getCode());
|
||||||
|
}
|
||||||
|
entity.setUpdateTimestamp(System.currentTimeMillis());
|
||||||
|
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
|
||||||
|
sysI18nService.save(entity);
|
||||||
|
return R.ok().putData("id", entity.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
public R update(@RequestBody SysI18nEntity entity) {
|
||||||
|
T.VerifyUtil.is(entity).notNull()
|
||||||
|
.and(entity.getId()).notEmpty(RCode.ID_CANNOT_EMPTY)
|
||||||
|
.and(entity.getCode()).notEmpty()
|
||||||
|
.and(entity.getValue()).notEmpty()
|
||||||
|
.and(entity.getLang()).notEmpty();
|
||||||
|
SysI18nEntity one = sysI18nService.getOne(new LambdaQueryWrapper<SysI18nEntity>()
|
||||||
|
.eq(SysI18nEntity::getCode, entity.getCode())
|
||||||
|
.eq(SysI18nEntity::getLang, entity.getLang())
|
||||||
|
.ne(SysI18nEntity::getId, entity.getId()));
|
||||||
|
if (T.ObjectUtil.isNotNull(one)) {
|
||||||
|
throw ASWException.builder().rcode(RCode.SYS_DUPLICATE_RECORD).build();
|
||||||
|
}
|
||||||
|
if (T.ObjectUtil.isEmpty(entity.getName())) {
|
||||||
|
entity.setName(entity.getCode());
|
||||||
|
}
|
||||||
|
entity.setUpdateTimestamp(System.currentTimeMillis());
|
||||||
|
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
|
||||||
|
sysI18nService.updateById(entity);
|
||||||
|
return R.ok().putData("id", entity.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping
|
||||||
|
public R delete(String[] ids) {
|
||||||
|
T.VerifyUtil.is(ids).notEmpty();
|
||||||
|
sysI18nService.removeBatchByIds(T.ListUtil.of(ids));
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/lang")
|
||||||
|
public R lang(@RequestParam(required = false, defaultValue = "en,zh") String l) {
|
||||||
|
List<String> langList = T.StrUtil.split(l, ',');
|
||||||
|
Map result = T.MapUtil.builder().build();
|
||||||
|
for (String lang : langList) {
|
||||||
|
List<SysI18nEntity> dataList = sysI18nService.list(new LambdaQueryWrapper<SysI18nEntity>().eq(SysI18nEntity::getLang, lang));
|
||||||
|
Map<String, String> collect = dataList.stream().collect(Collectors.toMap(SysI18nEntity::getCode, SysI18nEntity::getValue));
|
||||||
|
result.put(lang, collect);
|
||||||
|
}
|
||||||
|
return R.ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/clearCache")
|
||||||
|
public R clearCache() {
|
||||||
|
sysI18nService.clearCache();
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,29 +1,19 @@
|
|||||||
package net.geedge.asw.module.sys.controller;
|
package net.geedge.asw.module.sys.controller;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import cn.hutool.log.Log;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
|
||||||
import cn.hutool.log.Log;
|
|
||||||
import net.geedge.asw.common.util.ASWException;
|
import net.geedge.asw.common.util.ASWException;
|
||||||
import net.geedge.asw.common.util.R;
|
import net.geedge.asw.common.util.R;
|
||||||
import net.geedge.asw.common.util.RCode;
|
import net.geedge.asw.common.util.RCode;
|
||||||
import net.geedge.asw.common.util.T;
|
import net.geedge.asw.common.util.T;
|
||||||
import net.geedge.asw.module.sys.entity.SysRoleEntity;
|
import net.geedge.asw.module.sys.entity.SysRoleEntity;
|
||||||
import net.geedge.asw.module.sys.service.ISysRoleService;
|
import net.geedge.asw.module.sys.service.ISysRoleService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/sys/role")
|
@RequestMapping("/api/v1/role")
|
||||||
public class SysRoleController {
|
public class SysRoleController {
|
||||||
|
|
||||||
private static final Log log = Log.get();
|
private static final Log log = Log.get();
|
||||||
@@ -37,8 +27,10 @@ public class SysRoleController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public R list(String ids, String name, @RequestParam(defaultValue = "1") Integer current,
|
public R list(String ids, String name,
|
||||||
@RequestParam(defaultValue = "20") Integer size, @RequestParam(defaultValue = "name") String orderBy) {
|
@RequestParam(defaultValue = "1") Integer current,
|
||||||
|
@RequestParam(defaultValue = "20") Integer size,
|
||||||
|
@RequestParam(defaultValue = "name") String orderBy) {
|
||||||
QueryWrapper<SysRoleEntity> queryWrapper = new QueryWrapper<SysRoleEntity>();
|
QueryWrapper<SysRoleEntity> queryWrapper = new QueryWrapper<SysRoleEntity>();
|
||||||
queryWrapper.like(T.StrUtil.isNotBlank(name), "name", name).in(T.StrUtil.isNotBlank(ids), "id", ids.split(","));
|
queryWrapper.like(T.StrUtil.isNotBlank(name), "name", name).in(T.StrUtil.isNotBlank(ids), "id", ids.split(","));
|
||||||
Page<SysRoleEntity> page = Page.of(current, size);
|
Page<SysRoleEntity> page = Page.of(current, size);
|
||||||
|
|||||||
@@ -1,34 +1,24 @@
|
|||||||
package net.geedge.asw.module.sys.controller;
|
package net.geedge.asw.module.sys.controller;
|
||||||
|
|
||||||
import java.util.List;
|
import cn.hutool.log.Log;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import net.geedge.asw.common.util.*;
|
||||||
import cn.hutool.log.Log;
|
|
||||||
import net.geedge.asw.common.util.ASWException;
|
|
||||||
import net.geedge.asw.common.util.Constants;
|
|
||||||
import net.geedge.asw.common.util.R;
|
|
||||||
import net.geedge.asw.common.util.RCode;
|
|
||||||
import net.geedge.asw.common.util.T;
|
|
||||||
import net.geedge.asw.module.sys.entity.SysRoleEntity;
|
import net.geedge.asw.module.sys.entity.SysRoleEntity;
|
||||||
import net.geedge.asw.module.sys.entity.SysUserEntity;
|
import net.geedge.asw.module.sys.entity.SysUserEntity;
|
||||||
|
import net.geedge.asw.module.sys.entity.SysUserRoleEntity;
|
||||||
import net.geedge.asw.module.sys.service.ISysRoleService;
|
import net.geedge.asw.module.sys.service.ISysRoleService;
|
||||||
|
import net.geedge.asw.module.sys.service.ISysUserRoleService;
|
||||||
import net.geedge.asw.module.sys.service.ISysUserService;
|
import net.geedge.asw.module.sys.service.ISysUserService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/sys/user")
|
@RequestMapping("/api/v1/user")
|
||||||
public class SysUserController {
|
public class SysUserController {
|
||||||
|
|
||||||
private static final Log log = Log.get();
|
private static final Log log = Log.get();
|
||||||
@@ -36,24 +26,35 @@ public class SysUserController {
|
|||||||
private ISysUserService userService;
|
private ISysUserService userService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysRoleService roleService;
|
private ISysRoleService roleService;
|
||||||
|
@Autowired
|
||||||
|
private ISysUserRoleService uerRoleService;
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public R detail(@PathVariable("id") String id) {
|
public R detail(@PathVariable("id") String id) {
|
||||||
SysUserEntity entity = userService.getById(id);
|
SysUserEntity entity = userService.getById(id);
|
||||||
entity.setPwd(null);
|
if (T.ObjectUtil.isNotNull(entity)) {
|
||||||
List<SysRoleEntity> roleList = roleService.listByIds(T.ListUtil.of(entity.getRoleIds()));
|
entity.setPwd(null);
|
||||||
entity.setRoles(roleList);
|
List<SysUserRoleEntity> userRoleList = uerRoleService.list(new LambdaQueryWrapper<SysUserRoleEntity>().eq(SysUserRoleEntity::getUserId, entity.getId()));
|
||||||
|
if (T.CollUtil.isNotEmpty(userRoleList)) {
|
||||||
|
List<String> roleIds = userRoleList.stream().map(SysUserRoleEntity::getRoleId).collect(Collectors.toList());
|
||||||
|
List<SysRoleEntity> roleList = roleService.listByIds(roleIds);
|
||||||
|
entity.setRoles(roleList);
|
||||||
|
}
|
||||||
|
}
|
||||||
return R.ok().putData("record", entity);
|
return R.ok().putData("record", entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public R list(String name, @RequestParam(defaultValue = "1") Integer current,
|
public R list(String ids, String q,
|
||||||
@RequestParam(defaultValue = "20") Integer size, @RequestParam(defaultValue = "name") String orderBy) {
|
@RequestParam(defaultValue = "1") Integer current,
|
||||||
QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<SysUserEntity>();
|
@RequestParam(defaultValue = "20") Integer size,
|
||||||
|
@RequestParam(defaultValue = "name") String orderBy) {
|
||||||
|
QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<>();
|
||||||
// 不查询 pwd 列
|
// 不查询 pwd 列
|
||||||
queryWrapper.select(SysUserEntity.class, entity -> !entity.getColumn().equals("pwd"));
|
queryWrapper.select(SysUserEntity.class, entity -> !entity.getColumn().equals("pwd"));
|
||||||
if (T.StrUtil.isNotBlank(name)) {
|
queryWrapper.in(T.StrUtil.isNotEmpty(ids), "id", T.StrUtil.split(ids, ','));
|
||||||
queryWrapper.and(wrapper -> wrapper.like("name", name).or().like("user_name", name));
|
if (T.StrUtil.isNotBlank(q)) {
|
||||||
|
queryWrapper.and(wrapper -> wrapper.like("name", q).or().like("user_name", q));
|
||||||
}
|
}
|
||||||
Page<SysUserEntity> page = Page.of(current, size);
|
Page<SysUserEntity> page = Page.of(current, size);
|
||||||
page.addOrder(T.PageUtil.decodeOrderByStr(orderBy));
|
page.addOrder(T.PageUtil.decodeOrderByStr(orderBy));
|
||||||
|
|||||||
10
src/main/java/net/geedge/asw/module/sys/dao/SysI18nDao.java
Normal file
10
src/main/java/net/geedge/asw/module/sys/dao/SysI18nDao.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package net.geedge.asw.module.sys.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import net.geedge.asw.module.sys.entity.SysI18nEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysI18nDao extends BaseMapper<SysI18nEntity> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package net.geedge.asw.module.sys.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("sys_i18n")
|
||||||
|
public class SysI18nEntity implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* i18n code
|
||||||
|
*/
|
||||||
|
private String code;
|
||||||
|
/**
|
||||||
|
* 语言
|
||||||
|
*/
|
||||||
|
private String lang;
|
||||||
|
/**
|
||||||
|
* 翻译值
|
||||||
|
*/
|
||||||
|
private String value;
|
||||||
|
/**
|
||||||
|
* 备注信息
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
/**
|
||||||
|
* 操作人
|
||||||
|
*/
|
||||||
|
private String updateUserId;
|
||||||
|
/**
|
||||||
|
* 操作时间
|
||||||
|
*/
|
||||||
|
private Long updateTimestamp;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private SysUserEntity updateUser;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ public class SysUserEntity {
|
|||||||
private String userName;
|
private String userName;
|
||||||
private String pwd;
|
private String pwd;
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private String[] roleIds;
|
private String roleIds;
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private List<SysRoleEntity> roles;
|
private List<SysRoleEntity> roles;
|
||||||
private Long createTimestamp;
|
private Long createTimestamp;
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package net.geedge.asw.module.sys.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.sys.entity.SysI18nEntity;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public interface ISysI18nService extends IService<SysI18nEntity> {
|
||||||
|
|
||||||
|
String queryValue(String code);
|
||||||
|
|
||||||
|
String queryValue(String code, Object... param);
|
||||||
|
|
||||||
|
String queryValue(String code, String lang);
|
||||||
|
|
||||||
|
String queryValue(String code, Locale locale, Object... param);
|
||||||
|
|
||||||
|
String queryValueByName(String name, Object... param);
|
||||||
|
|
||||||
|
void clearCache();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,16 +1,8 @@
|
|||||||
package net.geedge.asw.module.sys.service.impl;
|
package net.geedge.asw.module.sys.service.impl;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
|
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.log.Log;
|
import cn.hutool.log.Log;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import net.geedge.asw.common.util.ASWException;
|
import net.geedge.asw.common.util.ASWException;
|
||||||
import net.geedge.asw.common.util.Constants;
|
import net.geedge.asw.common.util.Constants;
|
||||||
import net.geedge.asw.common.util.RCode;
|
import net.geedge.asw.common.util.RCode;
|
||||||
@@ -21,6 +13,12 @@ import net.geedge.asw.module.sys.entity.SysMenuEntity;
|
|||||||
import net.geedge.asw.module.sys.entity.SysRoleEntity;
|
import net.geedge.asw.module.sys.entity.SysRoleEntity;
|
||||||
import net.geedge.asw.module.sys.entity.SysUserEntity;
|
import net.geedge.asw.module.sys.entity.SysUserEntity;
|
||||||
import net.geedge.asw.module.sys.service.ISysAuthService;
|
import net.geedge.asw.module.sys.service.ISysAuthService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class SysAuthServiceImpl implements ISysAuthService {
|
public class SysAuthServiceImpl implements ISysAuthService {
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package net.geedge.asw.module.sys.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.common.config.I18nConfig;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.sys.dao.SysI18nDao;
|
||||||
|
import net.geedge.asw.module.sys.entity.SysI18nEntity;
|
||||||
|
import net.geedge.asw.module.sys.service.ISysI18nService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SysI18nServiceImpl extends ServiceImpl<SysI18nDao, SysI18nEntity> implements ISysI18nService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private I18nConfig i18nConfig;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String queryValue(String code) {
|
||||||
|
return this.queryValue(code, this.getLocale());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String queryValue(String code, Object... param) {
|
||||||
|
return this.queryValue(code, this.getLocale(), param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String queryValue(String code, String lang) {
|
||||||
|
return this.queryValue(code, Locale.of(lang));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String queryValue(String code, Locale locale, Object... param) {
|
||||||
|
return i18nConfig.getSourceFromCache(code, locale, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String queryValueByName(String name, Object... param) {
|
||||||
|
String language = this.getLocale().getLanguage();
|
||||||
|
List<SysI18nEntity> list = this.list(new LambdaQueryWrapper<SysI18nEntity>().eq(SysI18nEntity::getName, name).eq(SysI18nEntity::getLang, language));
|
||||||
|
if (T.CollUtil.isEmpty(list)) {
|
||||||
|
return StrUtil.EMPTY;
|
||||||
|
}
|
||||||
|
SysI18nEntity sysI18nEntity = list.stream().findFirst().get();
|
||||||
|
return this.queryValue(sysI18nEntity.getCode(), this.getLocale(), param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearCache() {
|
||||||
|
i18nConfig.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getLocale
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Locale getLocale() {
|
||||||
|
return LocaleContextHolder.getLocale();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,20 +1,17 @@
|
|||||||
package net.geedge.asw.module.sys.service.impl;
|
package net.geedge.asw.module.sys.service.impl;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
|
||||||
import net.geedge.asw.common.util.T;
|
import net.geedge.asw.common.util.T;
|
||||||
import net.geedge.asw.module.sys.dao.SysUserDao;
|
import net.geedge.asw.module.sys.dao.SysUserDao;
|
||||||
import net.geedge.asw.module.sys.entity.SysUserEntity;
|
import net.geedge.asw.module.sys.entity.SysUserEntity;
|
||||||
import net.geedge.asw.module.sys.entity.SysUserRoleEntity;
|
import net.geedge.asw.module.sys.entity.SysUserRoleEntity;
|
||||||
import net.geedge.asw.module.sys.service.ISysUserService;
|
import net.geedge.asw.module.sys.service.ISysUserService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements ISysUserService {
|
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements ISysUserService {
|
||||||
@@ -32,9 +29,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> i
|
|||||||
this.saveOrUpdate(entity);
|
this.saveOrUpdate(entity);
|
||||||
// 保存 user role关系
|
// 保存 user role关系
|
||||||
List<SysUserRoleEntity> urList = T.ListUtil.list(false);
|
List<SysUserRoleEntity> urList = T.ListUtil.list(false);
|
||||||
Stream.of(entity.getRoleIds()).forEach(roleId -> {
|
for (String roleId : T.StrUtil.split(entity.getRoleIds(), ",")) {
|
||||||
urList.add(SysUserRoleEntity.builder().roleId(roleId).userId(entity.getId()).build());
|
urList.add(SysUserRoleEntity.builder().roleId(roleId).userId(entity.getId()).build());
|
||||||
});
|
}
|
||||||
userRoleService.saveBatch(urList);
|
userRoleService.saveBatch(urList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.geedge.asw.module.workbook.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import net.geedge.asw.module.workbook.entity.WorkbookEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface WorkbookDao extends BaseMapper<WorkbookEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.geedge.asw.module.workbook.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import net.geedge.asw.module.workbook.entity.WorkbookMemberEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface WorkbookMemberDao extends BaseMapper<WorkbookMemberEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.geedge.asw.module.workbook.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import net.geedge.asw.module.workbook.entity.WorkbookResourceEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface WorkbookResourceDao extends BaseMapper<WorkbookResourceEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package net.geedge.asw.module.workbook.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("workbook")
|
||||||
|
public class WorkbookEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String tags;
|
||||||
|
private String visibility;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private Long createTimestamp;
|
||||||
|
private Long updateTimestamp;
|
||||||
|
private String createUserId;
|
||||||
|
private String updateUserId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package net.geedge.asw.module.workbook.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("workbook_member")
|
||||||
|
public class WorkbookMemberEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
private String workbookId;
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
private Long createTimestamp;
|
||||||
|
private String createUserId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package net.geedge.asw.module.workbook.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("workbook_resource")
|
||||||
|
public class WorkbookResourceEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
private String id;
|
||||||
|
private String workbookId;
|
||||||
|
private String resourceType;
|
||||||
|
private String resourceId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package net.geedge.asw.module.workbook.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.workbook.entity.WorkbookMemberEntity;
|
||||||
|
|
||||||
|
public interface IWorkbookMemberService extends IService<WorkbookMemberEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package net.geedge.asw.module.workbook.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.workbook.entity.WorkbookResourceEntity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface IWorkbookResourceService extends IService<WorkbookResourceEntity>{
|
||||||
|
|
||||||
|
void saveResource(String workbookId, String resourceId, String type);
|
||||||
|
|
||||||
|
void removeResource(List<String> resourceIdList, String type);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package net.geedge.asw.module.workbook.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.workbook.entity.WorkbookEntity;
|
||||||
|
|
||||||
|
public interface IWorkbookService extends IService<WorkbookEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package net.geedge.asw.module.workbook.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.module.workbook.dao.WorkbookMemberDao;
|
||||||
|
import net.geedge.asw.module.workbook.entity.WorkbookMemberEntity;
|
||||||
|
import net.geedge.asw.module.workbook.service.IWorkbookMemberService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class WorkbookMemberServiceImpl extends ServiceImpl<WorkbookMemberDao, WorkbookMemberEntity> implements IWorkbookMemberService {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package net.geedge.asw.module.workbook.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.log.Log;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.common.util.T;
|
||||||
|
import net.geedge.asw.module.workbook.dao.WorkbookResourceDao;
|
||||||
|
import net.geedge.asw.module.workbook.entity.WorkbookResourceEntity;
|
||||||
|
import net.geedge.asw.module.workbook.service.IWorkbookResourceService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class WorkbookResourceServiceImpl extends ServiceImpl<WorkbookResourceDao, WorkbookResourceEntity> implements IWorkbookResourceService {
|
||||||
|
|
||||||
|
private static final Log log = Log.get();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveResource(String wbId, String resId, String type) {
|
||||||
|
if (T.StrUtil.hasEmpty(wbId, resId, type)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove
|
||||||
|
this.remove(new LambdaQueryWrapper<WorkbookResourceEntity>()
|
||||||
|
.eq(WorkbookResourceEntity::getResourceId, resId)
|
||||||
|
.eq(WorkbookResourceEntity::getResourceType, type));
|
||||||
|
|
||||||
|
// insert
|
||||||
|
WorkbookResourceEntity res = new WorkbookResourceEntity();
|
||||||
|
res.setWorkbookId(wbId);
|
||||||
|
res.setResourceId(resId);
|
||||||
|
res.setResourceType(type);
|
||||||
|
this.save(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeResource(List<String> resIdList, String type) {
|
||||||
|
if (T.CollUtil.isEmpty(resIdList) || T.StrUtil.isEmpty(type)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove
|
||||||
|
this.remove(new LambdaQueryWrapper<WorkbookResourceEntity>()
|
||||||
|
.eq(WorkbookResourceEntity::getResourceType, type)
|
||||||
|
.in(WorkbookResourceEntity::getResourceId, resIdList));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package net.geedge.asw.module.workbook.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.module.workbook.dao.WorkbookDao;
|
||||||
|
import net.geedge.asw.module.workbook.entity.WorkbookEntity;
|
||||||
|
import net.geedge.asw.module.workbook.service.IWorkbookService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class WorkbookServiceImpl extends ServiceImpl<WorkbookDao, WorkbookEntity> implements IWorkbookService {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package net.geedge.asw.module.workbook.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
|
public class WorkbookConstant {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resource type
|
||||||
|
*/
|
||||||
|
public enum ResourceType {
|
||||||
|
PACKAGE("package"),
|
||||||
|
SIGNATURE("signature"),
|
||||||
|
JOB("job"),
|
||||||
|
PCAP("pcap"),
|
||||||
|
DECODE_RECORD("decode_record");
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
ResourceType(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResourceType getInstanceByType(String type) {
|
||||||
|
for (ResourceType v : values()) {
|
||||||
|
if (StrUtil.equalsIgnoreCase(v.getValue(), type)) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Failed to find resource type with parameter.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.geedge.asw.module.workspace.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import net.geedge.asw.module.workspace.entity.WorkspaceEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface WorkspaceDao extends BaseMapper<WorkspaceEntity> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.geedge.asw.module.workspace.dao;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import net.geedge.asw.module.workspace.entity.WorkspaceMemberEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface WorkspaceMemberDao extends BaseMapper<WorkspaceMemberEntity> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package net.geedge.asw.module.workspace.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("workspace")
|
||||||
|
public class WorkspaceEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String tags;
|
||||||
|
private String visibility;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private Long createTimestamp;
|
||||||
|
private Long updateTimestamp;
|
||||||
|
private String createUserId;
|
||||||
|
private String updateUserId;
|
||||||
|
|
||||||
|
private String workspaceId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package net.geedge.asw.module.workspace.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("workspace_member")
|
||||||
|
public class WorkspaceMemberEntity {
|
||||||
|
|
||||||
|
private String workspaceId;
|
||||||
|
private String userId;
|
||||||
|
private String roleId;
|
||||||
|
|
||||||
|
private Long createTimestamp;
|
||||||
|
private String createUserId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package net.geedge.asw.module.workspace.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.workspace.entity.WorkspaceMemberEntity;
|
||||||
|
|
||||||
|
public interface IWorkspaceMemberService extends IService<WorkspaceMemberEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package net.geedge.asw.module.workspace.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import net.geedge.asw.module.workspace.entity.WorkspaceEntity;
|
||||||
|
|
||||||
|
public interface IWorkspaceService extends IService<WorkspaceEntity>{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package net.geedge.asw.module.workspace.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.module.workspace.dao.WorkspaceMemberDao;
|
||||||
|
import net.geedge.asw.module.workspace.entity.WorkspaceMemberEntity;
|
||||||
|
import net.geedge.asw.module.workspace.service.IWorkspaceMemberService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class WorkspaceMemberServiceImpl extends ServiceImpl<WorkspaceMemberDao, WorkspaceMemberEntity> implements IWorkspaceMemberService {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package net.geedge.asw.module.workspace.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import net.geedge.asw.module.workspace.dao.WorkspaceDao;
|
||||||
|
import net.geedge.asw.module.workspace.entity.WorkspaceEntity;
|
||||||
|
import net.geedge.asw.module.workspace.service.IWorkspaceService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class WorkspaceServiceImpl extends ServiceImpl<WorkspaceDao, WorkspaceEntity> implements IWorkspaceService {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -62,13 +62,13 @@ magic-api:
|
|||||||
swagger:
|
swagger:
|
||||||
version: 1.0
|
version: 1.0
|
||||||
description: Digital Horizon API 接口信息
|
description: Digital Horizon API 接口信息
|
||||||
title: DH API Swagger Docs
|
title: ASW Controller Swagger Docs
|
||||||
name: DH API 接口
|
name: ASW Controller 接口
|
||||||
location: /v2/api-docs/dh-api/swagger2.json
|
location: /v2/api-docs/asw-controller/swagger2.json
|
||||||
debug:
|
debug:
|
||||||
timeout: 60 # 断点超时时间,默认60s
|
timeout: 60 # 断点超时时间,默认60s
|
||||||
task:
|
task:
|
||||||
thread-name-prefix: dh-task- #线程池名字前缀
|
thread-name-prefix: asw-controller-task- #线程池名字前缀
|
||||||
log: true # 打印日志
|
log: true # 打印日志
|
||||||
pool:
|
pool:
|
||||||
size: 8 #线程池大小,默认值为CPU核心数
|
size: 8 #线程池大小,默认值为CPU核心数
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ server:
|
|||||||
mime-types: text/xml,text/plain,text/css,text/javascript,application/javascript,application/json,application/xml
|
mime-types: text/xml,text/plain,text/css,text/javascript,application/javascript,application/json,application/xml
|
||||||
|
|
||||||
mybatis-plus:
|
mybatis-plus:
|
||||||
mapper-locations: classpath:db/mapper/*Mapper.xml
|
mapper-locations: classpath:db/mapper/**/*Mapper.xml
|
||||||
configuration:
|
configuration:
|
||||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
global-config:
|
global-config:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<logger name="org.springframework" level="info" />
|
<logger name="org.springframework" level="info" />
|
||||||
<logger name="druid.sql" level="info" />
|
<logger name="druid.sql" level="info" />
|
||||||
|
|
||||||
<property name="log.path" value="/var/log/dh/" />
|
<property name="log.path" value="/var/log/asw-controller/" />
|
||||||
<!-- 输出格式 -->
|
<!-- 输出格式 -->
|
||||||
<property name="out.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" />
|
<property name="out.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" />
|
||||||
<!-- 活动文件的大小 -->
|
<!-- 活动文件的大小 -->
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
<!-- 2.2 level为 INFO 日志,时间滚动输出 -->
|
<!-- 2.2 level为 INFO 日志,时间滚动输出 -->
|
||||||
<appender name="LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
<appender name="LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<!-- 正在记录的日志文档的路径及文档名 -->
|
<!-- 正在记录的日志文档的路径及文档名 -->
|
||||||
<file>${log.path}/dh-web.log</file>
|
<file>${log.path}/asw-controller.log</file>
|
||||||
<!--日志文档输出格式 -->
|
<!--日志文档输出格式 -->
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>${out.pattern}</pattern>
|
<pattern>${out.pattern}</pattern>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
</encoder>
|
</encoder>
|
||||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||||
<fileNamePattern>${log.path}/dh-web-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
<fileNamePattern>${log.path}/asw-controller-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||||
<maxFileSize>${max.file.size}</maxFileSize>
|
<maxFileSize>${max.file.size}</maxFileSize>
|
||||||
<maxHistory>${max.history}</maxHistory>
|
<maxHistory>${max.history}</maxHistory>
|
||||||
<totalSizeCap>${total.size.cap}</totalSizeCap>
|
<totalSizeCap>${total.size.cap}</totalSizeCap>
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
<!-- 2.1 level为 ERROR 日志,时间滚动输出 -->
|
<!-- 2.1 level为 ERROR 日志,时间滚动输出 -->
|
||||||
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<!-- 正在记录的日志文档的路径及文档名 -->
|
<!-- 正在记录的日志文档的路径及文档名 -->
|
||||||
<file>${log.path}/dh-web-error.log</file>
|
<file>${log.path}/asw-controller-error.log</file>
|
||||||
<!--日志文档输出格式 -->
|
<!--日志文档输出格式 -->
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>${out.pattern}</pattern>
|
<pattern>${out.pattern}</pattern>
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
</encoder>
|
</encoder>
|
||||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||||
<fileNamePattern>${log.path}/dh-web-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
<fileNamePattern>${log.path}/asw-controller-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||||
<maxFileSize>${max.file.size}</maxFileSize>
|
<maxFileSize>${max.file.size}</maxFileSize>
|
||||||
<maxHistory>${max.history}</maxHistory>
|
<maxHistory>${max.history}</maxHistory>
|
||||||
<totalSizeCap>${total.size.cap}</totalSizeCap>
|
<totalSizeCap>${total.size.cap}</totalSizeCap>
|
||||||
|
|||||||
41
src/main/resources/db/mapper/app/PackageMapper.xml
Normal file
41
src/main/resources/db/mapper/app/PackageMapper.xml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="net.geedge.asw.module.app.dao.PackageDao">
|
||||||
|
|
||||||
|
|
||||||
|
<select id="queryList" resultType="net.geedge.asw.module.app.entity.PackageEntity">
|
||||||
|
SELECT
|
||||||
|
pkg.*
|
||||||
|
FROM
|
||||||
|
package pkg
|
||||||
|
LEFT JOIN workbook_resource wr ON pkg.id = wr.resource_id AND wr.resource_type = 'package'
|
||||||
|
<where>
|
||||||
|
<if test="params.ids != null and params.ids != ''">
|
||||||
|
pkg.id in
|
||||||
|
<foreach item="id" collection="params.ids.split(',')" separator="," open="(" close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.q != null and params.q != ''">
|
||||||
|
AND ( locate(#{params.q}, pkg.name) OR locate(#{params.q}, pkg.description) )
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.workbookId != null and params.workbookId != ''">
|
||||||
|
AND wr.workbook_id = #{params.workbookId}
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.workspaceId != null and params.workspaceId != ''">
|
||||||
|
AND pkg.workspace_id = #{params.workspaceId}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
|
||||||
|
GROUP BY
|
||||||
|
pkg.id
|
||||||
|
<if test="params.orderBy == null or params.orderBy == ''">
|
||||||
|
ORDER BY pkg.id
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
147
src/main/resources/db/mapper/runner/JobMapper.xml
Normal file
147
src/main/resources/db/mapper/runner/JobMapper.xml
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="net.geedge.asw.module.runner.dao.JobDao">
|
||||||
|
|
||||||
|
<resultMap type="net.geedge.asw.module.runner.entity.JobEntity" id="jobResultMap">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="playbookId" column="playbook_id"/>
|
||||||
|
<result property="packageId" column="package_id"/>
|
||||||
|
<result property="runnerId" column="runner_id"/>
|
||||||
|
<result property="scheduleId" column="schedule_id"/>
|
||||||
|
<result property="signatureIds" column="signature_ids"/>
|
||||||
|
<result property="tags" column="tags"/>
|
||||||
|
<result property="startTimestamp" column="start_timestamp"/>
|
||||||
|
<result property="endTimestamp" column="end_timestamp"/>
|
||||||
|
<result property="status" column="status"/>
|
||||||
|
<result property="pcapId" column="pcap_id"/>
|
||||||
|
<result property="logPath" column="log_path"/>
|
||||||
|
<result property="createTimestamp" column="create_timestamp"/>
|
||||||
|
<result property="updateTimestamp" column="update_timestamp"/>
|
||||||
|
<result property="createUserId" column="create_user_id"/>
|
||||||
|
<result property="updateUserId" column="update_user_id"/>
|
||||||
|
<result property="workspaceId" column="workspace_id"/>
|
||||||
|
|
||||||
|
<association property="pkg" columnPrefix="pkg_" javaType="net.geedge.asw.module.app.entity.PackageEntity">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="platform" column="platform"/>
|
||||||
|
<result property="identifier" column="identifier"/>
|
||||||
|
<result property="version" column="version"/>
|
||||||
|
<result property="logo" column="logo"/>
|
||||||
|
</association>
|
||||||
|
|
||||||
|
<association property="application" columnPrefix="app_"
|
||||||
|
javaType="net.geedge.asw.module.app.entity.ApplicationEntity">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="name" column="name"/>
|
||||||
|
</association>
|
||||||
|
|
||||||
|
<association property="runner" columnPrefix="run_" javaType="net.geedge.asw.module.runner.entity.RunnerEntity">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="name" column="name"/>
|
||||||
|
</association>
|
||||||
|
|
||||||
|
<association property="playbook" columnPrefix="pb_" javaType="net.geedge.asw.module.runner.entity.PlaybookEntity">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="name" column="name"/>
|
||||||
|
</association>
|
||||||
|
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
|
||||||
|
<select id="queryList" resultMap="jobResultMap">
|
||||||
|
SELECT
|
||||||
|
job.*,
|
||||||
|
pkg.id AS pkg_id,
|
||||||
|
pkg.platform AS pkg_platform,
|
||||||
|
pkg.version AS pkg_version,
|
||||||
|
pkg.logo AS pkg_logo,
|
||||||
|
pkg.identifier AS pkg_identifier,
|
||||||
|
|
||||||
|
app.id AS app_id,
|
||||||
|
app.name AS app_name,
|
||||||
|
|
||||||
|
run.id AS run_id,
|
||||||
|
run.name AS run_name,
|
||||||
|
|
||||||
|
pb.id AS pb_id,
|
||||||
|
pb.name AS pb_name
|
||||||
|
FROM
|
||||||
|
job job
|
||||||
|
LEFT JOIN runner run ON job.runner_id = run.id
|
||||||
|
LEFT JOIN package pkg ON job.package_id = pkg.id
|
||||||
|
LEFT JOIN playbook pb ON job.playbook_id = pb.id
|
||||||
|
LEFT JOIN application app ON pb.app_id = app.id
|
||||||
|
LEFT JOIN workbook_resource wr ON job.id = wr.resource_id AND wr.resource_type = 'job'
|
||||||
|
<where>
|
||||||
|
<if test="params.ids != null and params.ids != ''">
|
||||||
|
job.id in
|
||||||
|
<foreach item="id" collection="params.ids.split(',')" separator="," open="(" close=")">#{id}</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.appIds != null and params.appIds != ''">
|
||||||
|
AND app.id in
|
||||||
|
<foreach item="id" collection="params.appIds.split(',')" separator="," open="(" close=")">#{id}</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.packageIds != null and params.packageIds != ''">
|
||||||
|
AND pkg.id in
|
||||||
|
<foreach item="id" collection="params.packageIds.split(',')" separator="," open="(" close=")">#{id}</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.runnerIds != null and params.runnerIds != ''">
|
||||||
|
AND run.id in
|
||||||
|
<foreach item="id" collection="params.runnerIds.split(',')" separator="," open="(" close=")">#{id}</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.playbooks != null and params.playbooks != ''">
|
||||||
|
AND pb.id in
|
||||||
|
<foreach item="id" collection="params.playbooks.split(',')" separator="," open="(" close=")">#{id}</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.signatureIds != null and params.signatureIds != ''">
|
||||||
|
AND <foreach item="item" collection="params.signatureIds.split(',')" separator="OR" index="" open="(" close=")">
|
||||||
|
locate(#{item}, job.signature_ids)
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.workbookId != null and params.workbookId != ''">
|
||||||
|
AND wr.workbook_id = #{params.workbookId}
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.workspaceId != null and params.workspaceId != ''">
|
||||||
|
AND job.workspace_id = #{params.workspaceId}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
|
||||||
|
GROUP BY
|
||||||
|
job.id
|
||||||
|
|
||||||
|
<if test="params.orderBy == null or params.orderBy == ''">
|
||||||
|
ORDER BY job.id
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="getPendingJobByPlatform" resultMap="jobResultMap">
|
||||||
|
SELECT
|
||||||
|
job.*,
|
||||||
|
|
||||||
|
pkg.id AS pkg_id,
|
||||||
|
pkg.platform AS pkg_platform,
|
||||||
|
pkg.identifier AS pkg_identifier,
|
||||||
|
pkg.version AS pkg_version,
|
||||||
|
|
||||||
|
pb.id AS pb_id,
|
||||||
|
pb.name AS pb_name
|
||||||
|
FROM
|
||||||
|
job job
|
||||||
|
LEFT JOIN package pkg ON job.package_id = pkg.id
|
||||||
|
LEFT JOIN playbook pb ON job.playbook_id = pb.id
|
||||||
|
WHERE
|
||||||
|
job.status = 'pending' and pkg.platform = #{platform}
|
||||||
|
ORDER BY job.create_timestamp ASC
|
||||||
|
LIMIT 1
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
</mapper>
|
||||||
126
src/main/resources/db/mapper/runner/PcapMapper.xml
Normal file
126
src/main/resources/db/mapper/runner/PcapMapper.xml
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="net.geedge.asw.module.runner.dao.PcapDao">
|
||||||
|
|
||||||
|
<resultMap type="net.geedge.asw.module.runner.entity.PcapEntity" id="pcapResultMap">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="name" column="name"/>
|
||||||
|
<result property="tags" column="tags"/>
|
||||||
|
<result property="description" column="description"/>
|
||||||
|
<result property="path" column="path"/>
|
||||||
|
<result property="size" column="size"/>
|
||||||
|
<result property="connections" column="connections"/>
|
||||||
|
<result property="hosts" column="hosts"/>
|
||||||
|
<result property="md5" column="md5"/>
|
||||||
|
<result property="connectionTimeFirst" column="connection_time_first"/>
|
||||||
|
<result property="connectionTimeLast" column="connection_time_last"/>
|
||||||
|
<result property="protocols" column="protocols"/>
|
||||||
|
<result property="status" column="status"/>
|
||||||
|
<result property="createTimestamp" column="create_timestamp"/>
|
||||||
|
<result property="createUserId" column="create_user_id"/>
|
||||||
|
<result property="workspaceId" column="workspace_id"/>
|
||||||
|
|
||||||
|
<result property="jobId" column="jobId"/>
|
||||||
|
|
||||||
|
<association property="application" columnPrefix="app_" javaType="net.geedge.asw.module.app.entity.ApplicationEntity">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="name" column="name"/>
|
||||||
|
</association>
|
||||||
|
|
||||||
|
<association property="pkg" columnPrefix="pkg_" javaType="net.geedge.asw.module.app.entity.PackageEntity">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="platform" column="platform"/>
|
||||||
|
<result property="identifier" column="identifier"/>
|
||||||
|
<result property="version" column="version"/>
|
||||||
|
<result property="logo" column="logo"/>
|
||||||
|
</association>
|
||||||
|
|
||||||
|
<association property="runner" columnPrefix="run_" javaType="net.geedge.asw.module.runner.entity.RunnerEntity">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="name" column="name"/>
|
||||||
|
</association>
|
||||||
|
|
||||||
|
<association property="playbook" columnPrefix="pb_" javaType="net.geedge.asw.module.runner.entity.PlaybookEntity">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="name" column="name"/>
|
||||||
|
</association>
|
||||||
|
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<select id="queryList" resultMap="pcapResultMap">
|
||||||
|
SELECT
|
||||||
|
pcap.*,
|
||||||
|
job.id AS jobId,
|
||||||
|
|
||||||
|
app.id AS app_id,
|
||||||
|
app.name AS app_name,
|
||||||
|
|
||||||
|
pkg.id AS pkg_id,
|
||||||
|
pkg.platform AS pkg_platform,
|
||||||
|
pkg.version AS pkg_version,
|
||||||
|
pkg.logo AS pkg_logo,
|
||||||
|
pkg.identifier AS pkg_identifier,
|
||||||
|
|
||||||
|
run.id AS run_id,
|
||||||
|
run.name AS run_name,
|
||||||
|
|
||||||
|
pb.id AS pb_id,
|
||||||
|
pb.name AS pb_name
|
||||||
|
FROM
|
||||||
|
pcap pcap
|
||||||
|
left join job job on pcap.id = job.pcap_id
|
||||||
|
LEFT JOIN runner run ON job.runner_id = run.id
|
||||||
|
LEFT JOIN package pkg ON job.package_id = pkg.id
|
||||||
|
LEFT JOIN playbook pb ON job.playbook_id = pb.id
|
||||||
|
LEFT JOIN application app ON pb.app_id = app.id
|
||||||
|
LEFT JOIN workbook_resource wr ON pcap.id = wr.resource_id AND wr.resource_type = 'pcap'
|
||||||
|
<where>
|
||||||
|
<if test="params.ids != null and params.ids != ''">
|
||||||
|
pcap.id in
|
||||||
|
<foreach item="id" collection="params.ids.split(',')" separator="," open="(" close=")">#{id}</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.jobIds != null and params.jobIds != ''">
|
||||||
|
AND job.id in
|
||||||
|
<foreach item="id" collection="params.jobIds.split(',')" separator="," open="(" close=")">#{id}</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.appIds != null and params.appIds != ''">
|
||||||
|
AND app.id in
|
||||||
|
<foreach item="id" collection="params.appIds.split(',')" separator="," open="(" close=")">#{id}</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.packageIds != null and params.packageIds != ''">
|
||||||
|
AND pkg.id in
|
||||||
|
<foreach item="id" collection="params.packageIds.split(',')" separator="," open="(" close=")">#{id}</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.runnerIds != null and params.runnerIds != ''">
|
||||||
|
AND run.id in
|
||||||
|
<foreach item="id" collection="params.runnerIds.split(',')" separator="," open="(" close=")">#{id}</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.playbooks != null and params.playbooks != ''">
|
||||||
|
AND pb.id in
|
||||||
|
<foreach item="id" collection="params.playbooks.split(',')" separator="," open="(" close=")">#{id}</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.workbookId != null and params.workbookId != ''">
|
||||||
|
AND wr.workbook_id = #{params.workbookId}
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.workspaceId != null and params.workspaceId != ''">
|
||||||
|
AND pcap.workspace_id = #{params.workspaceId}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
|
||||||
|
GROUP BY
|
||||||
|
pcap.id
|
||||||
|
|
||||||
|
<if test="params.orderBy == null or params.orderBy == ''">
|
||||||
|
ORDER BY pcap.id
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
32
src/main/resources/db/mapper/runner/RunnerMapper.xml
Normal file
32
src/main/resources/db/mapper/runner/RunnerMapper.xml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="net.geedge.asw.module.runner.dao.RunnerDao">
|
||||||
|
|
||||||
|
<select id="queryList" resultType="net.geedge.asw.module.runner.entity.RunnerEntity">
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
runner
|
||||||
|
<where>
|
||||||
|
<if test="params.workspaceId != null and params.workspaceId != ''">
|
||||||
|
workspace_id = #{params.workspaceId}
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.q != null and params.q != ''">
|
||||||
|
AND locate(#{params.q}, description)
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="params.tags != null and params.tags != ''">
|
||||||
|
AND <foreach item="item" collection="params.tags.split(',')" separator="OR" index="" open="(" close=")">
|
||||||
|
locate(#{item}, tags)
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
|
||||||
|
<if test="params.orderBy == null or params.orderBy == ''">
|
||||||
|
ORDER BY id
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
56
src/main/resources/db/migration/R__AZ_sys_i18n.sql
Normal file
56
src/main/resources/db/migration/R__AZ_sys_i18n.sql
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
SET NAMES utf8mb4;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for sys_i18n
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `sys_i18n`;
|
||||||
|
CREATE TABLE `sys_i18n` (
|
||||||
|
`id` int(10) NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` varchar(128) NOT NULL COMMENT '名称',
|
||||||
|
`code` varchar(128) NOT NULL COMMENT 'code码',
|
||||||
|
`value` longtext NOT NULL COMMENT '翻译值',
|
||||||
|
`lang` varchar(64) NOT NULL COMMENT '语言',
|
||||||
|
`remark` varchar(512) NOT NULL DEFAULT '' COMMENT '备注',
|
||||||
|
`update_user_id` varchar(64) NOT NULL COMMENT '更新人',
|
||||||
|
`update_timestamp` bigint(20) NOT NULL COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
INDEX `idx_lang_code`(`lang`, `code`) USING BTREE
|
||||||
|
) ENGINE=InnoDB ROW_FORMAT=Dynamic DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (1, '999', 'ERROR', 'error', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (3, '999', 'ERROR', '错误', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (5, '100001', 'SYS_USER_PWD_ERROR', 'username or password error', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (7, '100001', 'SYS_USER_PWD_ERROR', '用户名或密码错误', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (9, '100002', 'SYS_DUPLICATE_RECORD', 'duplicate record', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (11, '100002', 'SYS_DUPLICATE_RECORD', '重复记录', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (13, '100003', 'SYS_NO_AUTH', 'Permission denied', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (15, '100003', 'SYS_NO_AUTH', '没有权限', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (17, '100004', 'ID_CANNOT_EMPTY', 'id cannot be empty', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (19, '100004', 'ID_CANNOT_EMPTY', 'id不能为空', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (21, '100005', 'NAME_CANNOT_EMPTY', 'name cannot be empty', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (23, '100005', 'NAME_CANNOT_EMPTY', '名称不能为空', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (25, '100006', 'PARAM_CANNOT_EMPTY', 'parameter cannot be empty', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (27, '100006', 'PARAM_CANNOT_EMPTY', '参数不能为空', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (29, '100007', 'USER_NO_LOGIN', 'user not login', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (31, '100007', 'USER_NO_LOGIN', '用户未登录', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (33, '100008', 'SYS_RECORD_NOT_FOUND', 'record not found', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (35, '100008', 'SYS_RECORD_NOT_FOUND', '找不到记录', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (37, '200', 'SUCCESS', 'success', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (39, '200', 'SUCCESS', '成功', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (41, '201001', 'APP_ID_CANNOT_EMPTY', 'application id cannot be empty', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (43, '201001', 'APP_ID_CANNOT_EMPTY', '应用ID不能为空', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (45, '202001', 'PACKAGE_ID_CANNOT_EMPTY', 'package id cannot be empty', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (47, '202001', 'PACKAGE_ID_CANNOT_EMPTY', '安装包ID不能为空', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (49, '301001', 'RUNNER_ID_CANNOT_EMPTY', 'runner id cannot be empty', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (51, '301001', 'RUNNER_ID_CANNOT_EMPTY', 'Runner ID不能为空', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (53, '302001', 'PLAYBOOK_ID_CANNOT_EMPTY', 'playbook id cannot be empty', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (55, '302001', 'PLAYBOOK_ID_CANNOT_EMPTY', '任务信息ID不能为空', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (57, '202002', 'PACKAGE_DESCRIPTION_CANNOT_EMPTY', 'package description cannot be empty', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (59, '202002', 'PACKAGE_DESCRIPTION_CANNOT_EMPTY', '安装包描述信息不能为空', 'zh', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (61, '401001', 'WORKSPACE_ID_CANNOT_EMPTY', 'workspace id cannot be empty', 'en', '', 'admin', 1719280800000);
|
||||||
|
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (63, '401001', 'WORKSPACE_ID_CANNOT_EMPTY', '工作空间ID不能为空', 'zh', '', 'admin', 1719280800000);
|
||||||
|
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
@@ -56,8 +56,7 @@ CREATE TABLE `sys_menu` (
|
|||||||
DROP TABLE IF EXISTS `sys_user_role`;
|
DROP TABLE IF EXISTS `sys_user_role`;
|
||||||
CREATE TABLE `sys_user_role` (
|
CREATE TABLE `sys_user_role` (
|
||||||
`user_id` varchar(64) NOT NULL,
|
`user_id` varchar(64) NOT NULL,
|
||||||
`role_id` varchar(64) NOT NULL,
|
`role_id` varchar(64) NOT NULL
|
||||||
PRIMARY KEY (`user_id`) USING BTREE
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `sys_role_menu`;
|
DROP TABLE IF EXISTS `sys_role_menu`;
|
||||||
@@ -133,4 +132,265 @@ CREATE TABLE `sys_file_content` (
|
|||||||
`id` varchar(64) NOT NULL,
|
`id` varchar(64) NOT NULL,
|
||||||
`content` longblob NOT NULL,
|
`content` longblob NOT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增 runner 表
|
||||||
|
*/
|
||||||
|
DROP TABLE IF EXISTS `runner`;
|
||||||
|
CREATE TABLE `runner` (
|
||||||
|
`id` varchar(64) NOT NULL COMMENT '主键',
|
||||||
|
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '名称',
|
||||||
|
`token` varchar(64) NOT NULL DEFAULT '' COMMENT 'token',
|
||||||
|
`tags` varchar(256) NOT NULL DEFAULT '' COMMENT '标签,多个逗号分隔',
|
||||||
|
`support_platforms` varchar(256) NOT NULL DEFAULT '' COMMENT '支持的平台; 可选值:android,ios,windows; 多个逗号分隔; 例:android,ios',
|
||||||
|
`share_flag` int(1) NOT NULL DEFAULT 1 COMMENT '共享标识; 1:共享 0:不共享,仅创建人可用',
|
||||||
|
`description` text NOT NULL DEFAULT '' COMMENT '描述信息',
|
||||||
|
`status` varchar(64) NOT NULL DEFAULT 'online' COMMENT '状态;可选值:online,offline',
|
||||||
|
`last_heartbeat_timestamp` bigint(20) NOT NULL DEFAULT (UNIX_TIMESTAMP(NOW()) * 1000) COMMENT '最后心跳时间戳',
|
||||||
|
`create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳',
|
||||||
|
`update_timestamp` bigint(20) NOT NULL COMMENT '更新时间戳',
|
||||||
|
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
|
||||||
|
`update_user_id` varchar(64) NOT NULL COMMENT '更新人',
|
||||||
|
`workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
KEY `idx_name` (`name`) USING BTREE,
|
||||||
|
KEY `idx_workspace_id` (`workspace_id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增 playbook 表
|
||||||
|
*/
|
||||||
|
DROP TABLE IF EXISTS `playbook`;
|
||||||
|
CREATE TABLE `playbook` (
|
||||||
|
`id` varchar(64) NOT NULL COMMENT '主键',
|
||||||
|
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '名称',
|
||||||
|
`app_id` varchar(64) NOT NULL DEFAULT '' COMMENT '应用程序 ID',
|
||||||
|
`tags` varchar(256) NOT NULL DEFAULT '' COMMENT '标签',
|
||||||
|
`script` text NOT NULL DEFAULT '' COMMENT '脚本内容',
|
||||||
|
`op_version` bigint(20) NOT NULL DEFAULT 1 COMMENT '更新版本号, 默认:1;每次更新递增',
|
||||||
|
`create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳',
|
||||||
|
`update_timestamp` bigint(20) NOT NULL COMMENT '更新时间戳',
|
||||||
|
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
|
||||||
|
`update_user_id` varchar(64) NOT NULL COMMENT '更新人',
|
||||||
|
`workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
KEY `idx_name` (`name`) USING BTREE,
|
||||||
|
KEY `idx_app_id` (`app_id`) USING BTREE,
|
||||||
|
KEY `idx_op_version` (`op_version`) USING BTREE,
|
||||||
|
KEY `idx_workspace_id` (`workspace_id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增 job 表
|
||||||
|
*/
|
||||||
|
DROP TABLE IF EXISTS `job`;
|
||||||
|
CREATE TABLE `job` (
|
||||||
|
`id` varchar(64) NOT NULL COMMENT '主键',
|
||||||
|
`playbook_id` varchar(64) NOT NULL DEFAULT '' COMMENT 'Playbook ID',
|
||||||
|
`package_id` varchar(64) NOT NULL DEFAULT '' COMMENT 'Package ID',
|
||||||
|
`runner_id` varchar(64) NOT NULL DEFAULT '' COMMENT 'Runner ID',
|
||||||
|
`schedule_id` varchar(64) NOT NULL DEFAULT '' COMMENT '定时器ID',
|
||||||
|
`signature_ids` text NOT NULL DEFAULT '' COMMENT '特征ID,多个逗号分隔',
|
||||||
|
`tags` varchar(256) NOT NULL DEFAULT '' COMMENT '标签; 默认:"";多个用逗号分隔;例:kz,vpn,android',
|
||||||
|
`start_timestamp` bigint(20) NOT NULL DEFAULT -1 COMMENT '开始时间戳',
|
||||||
|
`end_timestamp` bigint(20) NOT NULL DEFAULT -1 COMMENT '结束时间戳',
|
||||||
|
`status` varchar(64) NOT NULL DEFAULT '' COMMENT '状态; 可选值: created,pending,running,passed,failed,cancel',
|
||||||
|
`pcap_id` varchar(64) NOT NULL DEFAULT '' COMMENT 'PCAP ID',
|
||||||
|
`log_path` varchar(256) NOT NULL DEFAULT '' COMMENT '日志文件路径',
|
||||||
|
`create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳',
|
||||||
|
`update_timestamp` bigint(20) NOT NULL COMMENT '更新时间戳',
|
||||||
|
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
|
||||||
|
`update_user_id` varchar(64) NOT NULL COMMENT '更新人',
|
||||||
|
`workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
KEY `idx_playbook_id` (`playbook_id`) USING BTREE,
|
||||||
|
KEY `idx_package_id` (`package_id`) USING BTREE,
|
||||||
|
KEY `idx_runner_id` (`runner_id`) USING BTREE,
|
||||||
|
KEY `idx_workspace_id` (`workspace_id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增 pcap 表
|
||||||
|
*/
|
||||||
|
DROP TABLE IF EXISTS `pcap`;
|
||||||
|
CREATE TABLE `pcap` (
|
||||||
|
`id` varchar(64) NOT NULL COMMENT '主键',
|
||||||
|
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '文件名称',
|
||||||
|
`tags` varchar(256) NOT NULL DEFAULT '' COMMENT '标签',
|
||||||
|
`description` text NOT NULL DEFAULT '' COMMENT '描述信息',
|
||||||
|
`path` varchar(64) NOT NULL DEFAULT '' COMMENT 'PCAP文件路径',
|
||||||
|
`size` bigint(20) NOT NULL DEFAULT 0 COMMENT '文件大小',
|
||||||
|
`connections` bigint(20) NOT NULL DEFAULT 0 COMMENT '连接数量',
|
||||||
|
`hosts` bigint(20) NOT NULL DEFAULT 0 COMMENT 'IP数量',
|
||||||
|
`md5` varchar(64) NOT NULL DEFAULT '' COMMENT '摘要值,根据文件md5值判断是否已上存在,存在则响应当前id',
|
||||||
|
`connection_time_first` bigint(20) NOT NULL DEFAULT -1 COMMENT '连接开始时间',
|
||||||
|
`connection_time_last` bigint(20) NOT NULL DEFAULT -1 COMMENT '连接结束时间',
|
||||||
|
`protocols` varchar(64) NOT NULL DEFAULT '' COMMENT '包含的协议,多个逗号分隔',
|
||||||
|
`status` varchar(64) NOT NULL DEFAULT '' COMMENT '状态,可选值 Uploaded,Analyzing,Completed',
|
||||||
|
`create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳',
|
||||||
|
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
|
||||||
|
`workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
KEY `idx_name` (`name`) USING BTREE,
|
||||||
|
KEY `idx_md5` (`md5`) USING BTREE,
|
||||||
|
KEY `idx_tags` (`tags`) USING BTREE,
|
||||||
|
KEY `idx_workspace_id` (`workspace_id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增 decode_record 表
|
||||||
|
*/
|
||||||
|
DROP TABLE IF EXISTS `decode_record`;
|
||||||
|
CREATE TABLE `decode_record` (
|
||||||
|
`id` varchar(64) NOT NULL COMMENT '主键',
|
||||||
|
`pcap_id` varchar(64) NOT NULL DEFAULT '' COMMENT 'PCAP文件ID',
|
||||||
|
`stream_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '流ID',
|
||||||
|
`stream_attributes` text NOT NULL DEFAULT '' COMMENT '流属性',
|
||||||
|
`workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
KEY `idx_pcap_id` (`pcap_id`) USING BTREE,
|
||||||
|
KEY `idx_stream_id` (`stream_id`) USING BTREE,
|
||||||
|
KEY `idx_workspace_id` (`workspace_id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增 application 表
|
||||||
|
*/
|
||||||
|
DROP TABLE IF EXISTS `application`;
|
||||||
|
CREATE TABLE `application` (
|
||||||
|
`id` varchar(64) NOT NULL COMMENT '主键',
|
||||||
|
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '应用名称',
|
||||||
|
`long_name` varchar(256) NOT NULL DEFAULT '' COMMENT '应用全称',
|
||||||
|
`properties` text NOT NULL DEFAULT '' COMMENT '应用数据',
|
||||||
|
`description` text NOT NULL DEFAULT '' COMMENT '描述信息',
|
||||||
|
`surrogates` text NOT NULL DEFAULT '' COMMENT '',
|
||||||
|
`create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳',
|
||||||
|
`update_timestamp` bigint(20) NOT NULL COMMENT '更新时间戳',
|
||||||
|
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
|
||||||
|
`update_user_id` varchar(64) NOT NULL COMMENT '更新人',
|
||||||
|
`workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
KEY `idx_name` (`name`) USING BTREE,
|
||||||
|
KEY `idx_long_name` (`long_name`) USING BTREE,
|
||||||
|
KEY `idx_workspace_id` (`workspace_id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增 package 表
|
||||||
|
*/
|
||||||
|
DROP TABLE IF EXISTS `package`;
|
||||||
|
CREATE TABLE `package` (
|
||||||
|
`id` varchar(64) NOT NULL COMMENT '主键',
|
||||||
|
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '名称',
|
||||||
|
`logo` varchar(512) NOT NULL DEFAULT '' COMMENT '图标,图标文件 url 地址',
|
||||||
|
`description` text NOT NULL DEFAULT '' COMMENT '描述信息',
|
||||||
|
`platform` varchar(256) NOT NULL DEFAULT '' COMMENT '操作系统; 可选值:android,ios,windows,linux',
|
||||||
|
`version` varchar(256) NOT NULL DEFAULT '' COMMENT '安装包版本',
|
||||||
|
`identifier` varchar(256) NOT NULL DEFAULT '' COMMENT '唯一标识;android:package name,ios:bundle id',
|
||||||
|
`create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳',
|
||||||
|
`update_timestamp` bigint(20) NOT NULL COMMENT '更新时间戳',
|
||||||
|
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
|
||||||
|
`update_user_id` varchar(64) NOT NULL COMMENT '更新人',
|
||||||
|
`workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
KEY `idx_name` (`name`) USING BTREE,
|
||||||
|
KEY `idx_version` (`version`) USING BTREE,
|
||||||
|
KEY `idx_workspace_id` (`workspace_id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增 signature 表
|
||||||
|
*/
|
||||||
|
DROP TABLE IF EXISTS `signature`;
|
||||||
|
CREATE TABLE `signature` (
|
||||||
|
`id` varchar(64) NOT NULL COMMENT '主键',
|
||||||
|
`app_id` varchar(64) NOT NULL DEFAULT '' COMMENT '应用ID',
|
||||||
|
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '名称',
|
||||||
|
`tags` varchar(256) NOT NULL DEFAULT '' COMMENT '标签,多个逗号分隔',
|
||||||
|
`description` text NOT NULL DEFAULT '' COMMENT '描述信息',
|
||||||
|
`display_flag` int(1) NOT NULL DEFAULT 1 COMMENT '是否显示; 1:显示 0:不显示',
|
||||||
|
`conditions` text NOT NULL DEFAULT '' COMMENT '条件',
|
||||||
|
`op_version` bigint(20) NOT NULL DEFAULT 1 COMMENT '更新版本号, 默认:1;每次更新递增',
|
||||||
|
`create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳',
|
||||||
|
`update_timestamp` bigint(20) NOT NULL COMMENT '更新时间戳',
|
||||||
|
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
|
||||||
|
`update_user_id` varchar(64) NOT NULL COMMENT '更新人',
|
||||||
|
`workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
KEY `idx_app_id` (`app_id`) USING BTREE,
|
||||||
|
KEY `idx_name` (`name`) USING BTREE,
|
||||||
|
KEY `idx_op_version` (`op_version`) USING BTREE,
|
||||||
|
KEY `idx_workspace_id` (`workspace_id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增 workbook,workbook_member,workbook_resource 表
|
||||||
|
*/
|
||||||
|
DROP TABLE IF EXISTS `workbook`;
|
||||||
|
CREATE TABLE `workbook` (
|
||||||
|
`id` varchar(64) NOT NULL COMMENT '主键',
|
||||||
|
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '名称',
|
||||||
|
`tags` varchar(256) NOT NULL DEFAULT '' COMMENT '标签,多个逗号分隔',
|
||||||
|
`visibility` varchar(16) NOT NULL DEFAULT 'private' COMMENT '可见程度,可选值:private,public 默认:private',
|
||||||
|
`description` text NOT NULL DEFAULT '' COMMENT '描述信息',
|
||||||
|
`create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳',
|
||||||
|
`update_timestamp` bigint(20) NOT NULL COMMENT '更新时间戳',
|
||||||
|
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
|
||||||
|
`update_user_id` varchar(64) NOT NULL COMMENT '更新人',
|
||||||
|
`workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
KEY `idx_name` (`name`) USING BTREE,
|
||||||
|
KEY `idx_workspace_id` (`workspace_id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `workbook_member`;
|
||||||
|
CREATE TABLE `workbook_member` (
|
||||||
|
`workbook_id` varchar(64) NOT NULL COMMENT '主键',
|
||||||
|
`user_id` varchar(64) NOT NULL COMMENT 'user ID',
|
||||||
|
`create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳',
|
||||||
|
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
|
||||||
|
PRIMARY KEY (`workbook_id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `workbook_resource`;
|
||||||
|
CREATE TABLE `workbook_resource` (
|
||||||
|
`id` varchar(64) NOT NULL COMMENT '主键',
|
||||||
|
`workbook_id` varchar(64) NOT NULL COMMENT 'workbook ID',
|
||||||
|
`resource_type` varchar(64) NOT NULL COMMENT '资源类型 可选值:package,signature,job,pcap,decode_record',
|
||||||
|
`resource_id` varchar(64) NOT NULL COMMENT '资源id',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增 workspace, workspace_member 表
|
||||||
|
*/
|
||||||
|
DROP TABLE IF EXISTS `workspace`;
|
||||||
|
CREATE TABLE `workspace` (
|
||||||
|
`id` varchar(64) NOT NULL COMMENT '主键',
|
||||||
|
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '名称',
|
||||||
|
`tags` varchar(256) NOT NULL DEFAULT '' COMMENT '标签,多个逗号分隔',
|
||||||
|
`visibility` varchar(16) NOT NULL DEFAULT 'private' COMMENT '可见程度,可选值:private,public 默认:private',
|
||||||
|
`description` text NOT NULL DEFAULT '' COMMENT '描述信息',
|
||||||
|
`create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳',
|
||||||
|
`update_timestamp` bigint(20) NOT NULL COMMENT '更新时间戳',
|
||||||
|
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
|
||||||
|
`update_user_id` varchar(64) NOT NULL COMMENT '更新人',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
KEY `idx_name` (`name`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `workspace_member`;
|
||||||
|
CREATE TABLE `workspace_member` (
|
||||||
|
`workspace_id` varchar(64) NOT NULL,
|
||||||
|
`user_id` varchar(64) NOT NULL,
|
||||||
|
`role_id` varchar(64) NOT NULL,
|
||||||
|
`create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳',
|
||||||
|
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
|
||||||
|
KEY `idx_workspace_id` (`workspace_id`) USING BTREE,
|
||||||
|
KEY `idx_user_id` (`user_id`) USING BTREE,
|
||||||
|
KEY `idx_role_id` (`role_id`) USING BTREE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
Reference in New Issue
Block a user