Compare commits

...

156 Commits
dev ... master

Author SHA1 Message Date
weishao 00c214a473 rm \ 2023-03-09 19:13:18 +08:00
youys 45a2f5be9b 添加注释 2023-03-09 18:10:53 +08:00
youys c657b31416 缺陷>代码详情接口v2版本 2023-03-09 17:35:00 +08:00
youys 7e387eb37a 缺陷>代码详情接口v2版本 2023-03-09 17:34:12 +08:00
weishao 69d126b2f6 扫描文件路径 2023-03-09 16:43:08 +08:00
weishao bd0c90a496 静态扫描扫描逻辑 2023-03-09 16:14:29 +08:00
weishao 0421776f81 静态扫描扫描逻辑 2023-03-09 15:32:02 +08:00
jshixiong 5099a0a90a 组件漏洞 2023-03-09 15:04:34 +08:00
jshixiong 38d1a432a7 fix 2023-03-08 15:08:41 +08:00
jshixiong dd5f1f7fc3 概览 漏洞指标 2023-03-08 15:08:40 +08:00
jshixiong 2f368a2a44 fix:漏洞和组件 2023-03-07 16:01:48 +08:00
jshixiong a40dfb387a 漏洞和组件 2023-03-07 15:45:42 +08:00
weishao d72dba7f01 组件漏洞 2023-03-02 18:09:59 +08:00
weishao 88b3b4cd91 漏洞分页 2023-03-02 15:47:22 +08:00
weishao a0b77d21d6 漏洞详情 2023-03-02 15:09:32 +08:00
weishao 172def1186 漏洞 2023-03-02 14:44:08 +08:00
weishao 53428dc4ac 漏洞 2023-03-02 14:13:13 +08:00
weishao f968d9c668 漏洞 2023-03-02 10:39:18 +08:00
youys dd684dd6ef fix 2023-03-01 09:57:51 +08:00
youys 88ec9b0197 组件分险等级统计 2023-02-28 18:08:17 +08:00
youys 50c14fb136 随机分险等级 2023-02-28 18:00:23 +08:00
youys 611948c914 随机分险等级 2023-02-28 17:58:33 +08:00
youys 4041e767e8 组件名称取值问题 2023-02-28 17:45:32 +08:00
youys a70ac2cb64 fix 异步线程池mdc值传递 2023-02-27 15:54:42 +08:00
youys 3c98a12b58 失败了也去查询结果 2023-02-22 19:20:01 +08:00
youys ee7523dd5e fix 2023-02-22 19:15:02 +08:00
youys 09161eff8f .net 扫描分支 2023-02-22 19:03:27 +08:00
youys bfc61bfc79 异步解析组件 2023-02-15 14:45:18 +08:00
jshixiong 917632e8a8 fix 2023-02-14 14:12:00 +08:00
jshixiong 51a2a47748 注释 2023-02-14 10:38:57 +08:00
jshixiong 00e797b7a6 导出pdf报告 2023-02-13 18:25:17 +08:00
youys 24c7240c2b 项目在检测中不能再次检测 2023-02-07 09:41:30 +08:00
youys c002010512 获取文件目录大小命令更新 2023-02-06 18:05:54 +08:00
youys 9100963f74 分页问题 2023-02-06 17:02:25 +08:00
youys 20079ce5cd Merge branch 'component' into merge 2023-02-06 16:50:27 +08:00
youys c4eaae0ae3 code_license 删除了full_name字段 2023-02-06 16:50:12 +08:00
youys f432c69247 Merge branch 'component' into merge 2023-02-06 11:52:27 +08:00
youys a8fb88fcce 依赖路径关系箭头 2023-02-06 11:52:14 +08:00
youys 1889819871 空转换数值问题 2023-02-03 18:11:04 +08:00
youys f4e915fad9 添加字段 2023-02-03 14:09:06 +08:00
youys 4161413a2c Merge branch 'component' into merge 2023-02-03 13:49:29 +08:00
youys b0a9bb6498 组件找不到给默认数据 2023-02-03 13:49:14 +08:00
youys 62878d96b7 更新模板 2023-02-03 11:16:58 +08:00
youys 1a1dd97dc3 add log 2023-02-03 10:49:32 +08:00
youys 4e53d32e08 Merge branch 'component' into merge 2023-02-03 10:39:34 +08:00
youys a52babb07c 移除写死数据 2023-02-03 10:39:22 +08:00
youys 6922d0f08a Merge branch 'component' into merge 2023-02-03 10:38:02 +08:00
youys 68f5eeb2bb 移除写死数据 2023-02-03 10:37:53 +08:00
youys 1586cb84e5 合并代码 2023-02-03 10:29:41 +08:00
youys 3ed1d3237f 移除todo 2023-02-03 10:27:57 +08:00
jshixiong dcbf3265f3 fill delete 2023-02-02 18:20:28 +08:00
weishao 409a655207 检测冗余参数 2023-02-02 18:14:42 +08:00
weishao eff035728c Merge branch 'merge' of https://gitlink.org.cn/youys/quality_analysis into merge 2023-02-02 17:51:11 +08:00
weishao 8b5afadb78 无组件情况 2023-02-02 17:50:55 +08:00
jshixiong 86777e7a7b 模板列表不关联项目 2023-02-02 17:43:07 +08:00
weishao 931552ecab Merge branch 'merge' of https://gitlink.org.cn/youys/quality_analysis into merge 2023-02-02 17:18:22 +08:00
weishao 31b7863dd8 组件分析 2023-02-02 17:17:56 +08:00
jshixiong 7cfce85563 缺陷列表导出 2023-02-02 10:22:31 +08:00
weishao fe829ca081 展示非本人创建的分析任务 2023-02-01 10:24:31 +08:00
weishao 68730a7f50 算法修正 2023-01-29 20:59:06 +08:00
weishao 32032ceb45 算法修正 2023-01-29 20:48:31 +08:00
weishao 18c43a7a0b 算法修正 2023-01-29 20:32:15 +08:00
weishao 84ecd6bd01 nil默认语言 2023-01-29 19:21:53 +08:00
weishao d97d33011b nil jar 配置 2023-01-29 19:13:01 +08:00
weishao bcf3ebf44b nil配置 2023-01-29 19:01:02 +08:00
weishao 3d4ad762f0 Merge branch 'clone_detection' into merge 2023-01-29 18:51:36 +08:00
weishao 315062ff48 nil 2023-01-29 18:03:34 +08:00
weishao a799a70f9a 增加语言 2023-01-29 18:01:14 +08:00
weishao d410460795 克隆检测调整 2023-01-29 16:50:33 +08:00
jshixiong 0dabd940fa Merge branch 'merge_report' into merge
# Conflicts:
#	web/src/main/java/net/educoder/quality/entity/mysql/ComponentParseRecordDetail.java
#	web/src/main/resources/template/report-center-template.docx
2023-01-20 13:09:27 +08:00
jshixiong 6e670317b4 报告批量下载 2023-01-20 12:55:24 +08:00
jshixiong 924b333c0f fix 2023-01-20 12:03:56 +08:00
youys 41655f8156 导出模板格式更新 2023-01-20 10:54:23 +08:00
jshixiong 25564a9e75 质量分析报告 2023-01-20 10:18:40 +08:00
jshixiong c5ed615565 质量分析报告 2023-01-20 10:16:25 +08:00
youys 1d7f22a18e Merge branch 'component' into merge 2023-01-19 12:06:14 +08:00
youys ff8799130b 只取一条许可证 2023-01-19 12:05:53 +08:00
youys 0eee13f0d1 只取一条许可证 2023-01-19 12:05:30 +08:00
youys ec7da92229 Merge branch 'component' into merge 2023-01-19 11:44:25 +08:00
youys 454833c4fe 增加home_url字段 2023-01-19 11:44:14 +08:00
youys 95443d066b Merge branch 'component' into merge 2023-01-19 10:45:31 +08:00
youys 974b623867 增加数据库配置 2023-01-19 10:43:22 +08:00
youys 1a78551d49 Merge branch 'component' into merge 2023-01-18 14:57:44 +08:00
youys b16a83e44c 增加漏洞字段,增加mock数据 2023-01-18 14:57:21 +08:00
weishao ad4462228d Merge branch 'clone_detection' into merge 2023-01-17 17:56:21 +08:00
weishao 3cd1113b17 开源质量分析模板 2023-01-17 17:55:32 +08:00
youys 2af9e0c033 merge clone_detection 2023-01-17 12:34:42 +08:00
youys 5295ea916f Merge branch 'component' into merge 2023-01-17 12:32:54 +08:00
youys 63d9cc1247 组件许可证数据 2023-01-17 12:31:33 +08:00
weishao e4617f7249 jsoup test 2023-01-12 20:16:44 +08:00
weishao d21ed60307 jsoup test 2023-01-12 20:16:23 +08:00
weishao 63816225b0 本地写死地址测试 2023-01-06 17:17:59 +08:00
weishao bfbdc6099b 本地写死地址测试 2023-01-06 17:13:26 +08:00
weishao dba47fee69 本地写死地址测试 2023-01-06 16:21:13 +08:00
weishao 8ae64d86db 本地写死地址测试 2023-01-06 15:46:53 +08:00
weishao fd389367ca 本地写死地址测试 2023-01-06 15:43:09 +08:00
weishao ab589a1ba8 nil 2023-01-06 15:20:47 +08:00
weishao c3bd36abd9 ceshi 2023-01-06 14:25:14 +08:00
weishao 27ec41ae72 克隆检测记录 2023-01-06 14:15:45 +08:00
weishao 3971d7dea2 克隆检测记录 2023-01-06 14:02:04 +08:00
weishao 21731f2983 克隆检测记录 2023-01-06 13:50:00 +08:00
weishao c270bc1650 可运行 2023-01-06 12:31:12 +08:00
weishao 5cbb3ac29b 克隆检测逻辑实现 2023-01-05 23:28:05 +08:00
youys e050cfec84 组件mock数据,以及新增缺失接口 2022-12-27 11:31:16 +08:00
weishao a569851c2d 克隆检测接口 2022-12-18 22:28:10 +08:00
youys db56dfc451 组件 2022-11-11 22:17:57 +08:00
youys c2b3722839 git地址截取 2022-11-11 10:28:09 +08:00
youys 4975ca72e9 git地址截取 2022-11-11 10:23:13 +08:00
youys b5cadf3d2a 修复截取项目名bug 2022-11-11 09:56:05 +08:00
youys 2b4a586c55 Merge branch 'dev2.0' into merge 2022-10-25 11:15:24 +08:00
youys 4f7cd54856 报告中心批量下载接口 2022-10-25 11:15:06 +08:00
youys 60cc1cdebf merge component branch 2022-10-20 10:39:29 +08:00
youys ea521a2e4a 修改定时任务执行时间 2022-10-19 11:11:08 +08:00
youys 647bb9cab0 组件优化 2022-10-19 10:42:51 +08:00
youys b1d6438185 对比详情接口返回修改 2022-10-18 17:32:39 +08:00
youys 9445272a6b 日志增加traceId 2022-10-18 10:55:13 +08:00
youys d9a6bc9bc8 修改样式 2022-10-17 17:34:14 +08:00
youys 27098bcd60 缺陷代码详情接口增加字段 2022-10-17 17:25:35 +08:00
youys 8d180e763f 缺陷代码详情接口增加字段 2022-10-17 17:10:42 +08:00
youys 0c61b6a2f2 组件相关接口 2022-10-14 21:20:46 +08:00
youys 58a71b2da2 组件接口定义 2022-10-13 17:13:24 +08:00
youys 829621a053 模拟数据 2022-10-10 11:46:22 +08:00
youys 5210612bd5 模拟数据 2022-10-10 11:40:50 +08:00
youys 7982974c09 模拟数据 2022-10-10 11:29:09 +08:00
youys 6e51410e3f 多数据源连接失败,则快速失败 2022-10-10 11:21:07 +08:00
youys 640223040d 漏洞信息统计接口新增字段 2022-10-10 11:10:53 +08:00
youys 14d7115680 漏洞导出接口 2022-09-29 11:23:14 +08:00
youys aa1626df4c 解决冲突 2022-09-28 16:24:20 +08:00
youys 5e4718abb3 项目缺陷相关接口 2022-09-28 16:21:07 +08:00
jshixiong b8ff010a98 项目许可证接口(模拟) 2022-09-27 16:54:02 +08:00
youys fdbf824aaf 解决冲突 2022-09-27 16:32:29 +08:00
youys 5520eab2c1 增加protobuf依赖,缺陷相关接口 2022-09-27 16:29:30 +08:00
jshixiong 2a2941fbbb 项目许可证接口(模拟) 2022-09-27 14:25:59 +08:00
jshixiong 6cf2dc26b3 检测配置启动初始化 2022-09-27 14:24:29 +08:00
youys 8d3fa5ba38 执行命令增加source 2022-09-26 16:48:41 +08:00
youys dbc18290a3 Merge branch 'dev2.0' of https://gitlink.org.cn/youys/quality_analysis into dev2.0 2022-09-26 11:22:01 +08:00
youys 71c0315692 fix 2022-09-26 11:21:56 +08:00
jshixiong db52c08cfd 检测配置优化 2022-09-26 10:01:34 +08:00
youys 3aaa24c5c3 报告模板更新,下载接口更新,导出接口返回id 2022-09-23 17:57:14 +08:00
youys a633602a3d 增加配置id 2022-09-23 16:22:36 +08:00
youys 27cabd0230 检测配置接口更新 2022-09-23 16:20:25 +08:00
youys c69e77b39c 检测配置接口更新 2022-09-23 16:19:45 +08:00
youys f43808b999 报告中心相关接口 2022-09-23 15:53:24 +08:00
youys 820947169f 日志接口更新 2022-09-23 11:24:22 +08:00
youys 3015aef071 get请求传参问题 2022-09-22 14:54:05 +08:00
youys 912996711b Merge branch 'dev2.0' of https://gitlink.org.cn/youys/quality_analysis into dev2.0 2022-09-21 16:42:28 +08:00
youys a56aadba39 创建模板更新创建人字段 2022-09-21 16:42:20 +08:00
jshixiong f574aed4f8 项目检测配置初始化方法 2022-09-21 14:55:23 +08:00
youys 088819cbd8 更改get请求接收参数 2022-09-21 14:31:13 +08:00
youys fb59e454a1 Merge branch 'dev2.0' of https://gitlink.org.cn/youys/quality_analysis into dev2.0 2022-09-21 14:08:24 +08:00
youys 354af95c22 所有请求参数使用json方式传输,增加request流缓存 2022-09-21 14:08:21 +08:00
jshixiong bbe2d5726b 项目检测配置接口 2022-09-21 12:10:23 +08:00
jshixiong 0647389a86 项目检测配置接口 2022-09-21 11:32:42 +08:00
youys 613116ef54 允许跨域 2022-09-21 10:36:09 +08:00
youys c48aa58dce 项目概述unfinish 2022-09-20 15:44:54 +08:00
youys 3665c9f3f8 更新接口 2022-09-20 11:53:32 +08:00
182 changed files with 19211 additions and 497 deletions

View File

@ -26,13 +26,13 @@ public class DefaultControllerAdvisor {
@ExceptionHandler(Exception.class)
public R processException(Exception e) {
logger.error(e.getMessage(), e);
logger.error("DefaultControllerAdvisor#Exception", e);
return R.failed(ErrorCodeEnum.EXCEPTION.getValue(),ErrorCodeEnum.EXCEPTION.getDescription());
}
@ExceptionHandler(BusinessException.class)
public R processException(BusinessException e) {
logger.error(e.getMessage(), e);
logger.error("DefaultControllerAdvisor#BusinessException", e);
return R.failed(e.getErrCode(),e.getMessage());
}
@ -40,7 +40,7 @@ public class DefaultControllerAdvisor {
@ExceptionHandler(MissingServletRequestParameterException.class)
public R processMissingServletRequestParameterException(MissingServletRequestParameterException e){
logger.error(e.getMessage(), e);
logger.error("DefaultControllerAdvisor#MissingServletRequestParameterException", e);
return R.failed(ErrorCodeEnum.MVC_BIND_EXCEPTION.getValue(),ErrorCodeEnum.MVC_BIND_EXCEPTION.getDescription());
}
@ -48,7 +48,7 @@ public class DefaultControllerAdvisor {
@ExceptionHandler(ConstraintViolationException.class)
public R processConstraintViolationException(ConstraintViolationException e) {
logger.error(e.getMessage(), e);
logger.error("DefaultControllerAdvisor#ConstraintViolationException", e);
return R.failed(ErrorCodeEnum.INVALID_ARG_EXCEPTION.getValue(),ErrorCodeEnum.INVALID_ARG_EXCEPTION.getDescription());
}
@ -56,15 +56,15 @@ public class DefaultControllerAdvisor {
@ExceptionHandler(BindException.class)
public R processBindException(BindException e) {
logger.error(e.getMessage(), e);
return R.failed(ErrorCodeEnum.BIND_EXCEPTION.getValue(),ErrorCodeEnum.BIND_EXCEPTION.getDescription());
logger.error("DefaultControllerAdvisor#BindException", e);
return R.failed(ErrorCodeEnum.BIND_EXCEPTION.getValue(), e.getMessage());
}
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
public R processHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
logger.error(e.getMessage(), e);
logger.error("DefaultControllerAdvisor#HttpRequestMethodNotSupportedException", e);
return R.failed(ErrorCodeEnum.METHOD_NOT_ALLOWED_EXCEPTION.getValue(),ErrorCodeEnum.METHOD_NOT_ALLOWED_EXCEPTION.getDescription());
}

View File

@ -0,0 +1,28 @@
package net.educoder.quality.common.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @Author: youys
* @Date: 2022/9/21
* @Description: 支持跨域
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
//项目中的所有接口都支持跨域
registry.addMapping("/**")
//所有地址都可以访问也可以配置具体地址
.allowedOriginPatterns("*")
.allowCredentials(true)
//"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"
.allowedMethods("*")
// 跨域允许时间
.maxAge(3600);
}
}

View File

@ -25,6 +25,8 @@ public class DynamicDataSourceConfig {
public static final String MASTER = "master";
public static final String READONLY = "readonly";
public static final String GITEA = "gitea";
public static final String SAST = "sast";
private static final List INIT_SQLS = Arrays.asList("SET NAMES utf8mb4");
@ -96,6 +98,77 @@ public class DynamicDataSourceConfig {
@Value("${spring.datasource.readonly.druid.test-while-idle}")
private boolean readonlyTestWhileIdle;
// --------------------------gitea----------------------------------
@Value("${spring.datasource.gitea.driver-class-name}")
private String giteaDriverClass;
@Value("${spring.datasource.gitea.url}")
private String giteaUrl;
@Value("${spring.datasource.gitea.username}")
private String giteaUsername;
@Value("${spring.datasource.gitea.password}")
private String giteaPassword;
@Value("${spring.datasource.gitea.druid.initial-size}")
private Integer giteaInitialSize;
@Value("${spring.datasource.gitea.druid.max-active}")
private Integer giteaMaxActive;
@Value("${spring.datasource.gitea.druid.min-idle}")
private Integer giteaMinIdle;
@Value("${spring.datasource.gitea.druid.validation-query}")
private String giteaValidationQuery;
@Value("${spring.datasource.gitea.druid.test-on-borrow}")
private boolean giteaTestOnBorrow;
@Value("${spring.datasource.gitea.druid.test-on-return}")
private boolean giteaTestOnReturn;
@Value("${spring.datasource.gitea.druid.test-while-idle}")
private boolean giteaTestWhileIdle;
// --------------------------sast----------------------------------
@Value("${spring.datasource.sast.driver-class-name}")
private String sastDriverClass;
@Value("${spring.datasource.sast.url}")
private String sastUrl;
@Value("${spring.datasource.sast.username}")
private String sastUsername;
@Value("${spring.datasource.sast.password}")
private String sastPassword;
@Value("${spring.datasource.sast.druid.initial-size}")
private Integer sastInitialSize;
@Value("${spring.datasource.sast.druid.max-active}")
private Integer sastMaxActive;
@Value("${spring.datasource.sast.druid.min-idle}")
private Integer sastMinIdle;
@Value("${spring.datasource.sast.druid.validation-query}")
private String sastValidationQuery;
@Value("${spring.datasource.sast.druid.test-on-borrow}")
private boolean sastTestOnBorrow;
@Value("${spring.datasource.sast.druid.test-on-return}")
private boolean sastTestOnReturn;
@Value("${spring.datasource.sast.druid.test-while-idle}")
private boolean sastTestWhileIdle;
@Bean("master")
public DataSource masterDataSource() {
DruidDataSource masterDataSource = new DruidDataSource();
@ -110,6 +183,12 @@ public class DynamicDataSourceConfig {
masterDataSource.setTestOnReturn(masterTestOnReturn);
masterDataSource.setTestWhileIdle(masterTestWhileIdle);
masterDataSource.setValidationQuery(masterValidationQuery);
// 连接失败后中断---重试10次
masterDataSource.setBreakAfterAcquireFailure(true);
masterDataSource.setConnectionErrorRetryAttempts(10);
// 快速失败
masterDataSource.setFailFast(true);
return masterDataSource;
}
@ -127,16 +206,68 @@ public class DynamicDataSourceConfig {
readonlyDataSource.setTestOnReturn(readonlyTestOnReturn);
readonlyDataSource.setTestWhileIdle(readonlyTestWhileIdle);
readonlyDataSource.setValidationQuery(readonlyValidationQuery);
// 连接失败后中断---重试10次
readonlyDataSource.setBreakAfterAcquireFailure(true);
readonlyDataSource.setConnectionErrorRetryAttempts(10);
// 快速失败
readonlyDataSource.setFailFast(true);
return readonlyDataSource;
}
@Bean("gitea")
public DataSource giteaDataSource() {
DruidDataSource giteaDataSource = new DruidDataSource();
giteaDataSource.setDriverClassName(giteaDriverClass);
giteaDataSource.setUrl(giteaUrl);
giteaDataSource.setUsername(giteaUsername);
giteaDataSource.setPassword(giteaPassword);
giteaDataSource.setMinIdle(giteaMinIdle);
giteaDataSource.setMaxActive(giteaMaxActive);
giteaDataSource.setMinIdle(giteaMinIdle);
giteaDataSource.setTestOnBorrow(giteaTestOnBorrow);
giteaDataSource.setTestOnReturn(giteaTestOnReturn);
giteaDataSource.setTestWhileIdle(giteaTestWhileIdle);
giteaDataSource.setValidationQuery(giteaValidationQuery);
// 连接失败后中断---重试10次
giteaDataSource.setBreakAfterAcquireFailure(true);
giteaDataSource.setConnectionErrorRetryAttempts(10);
// 快速失败
giteaDataSource.setFailFast(true);
return giteaDataSource;
}
@Bean("sast")
public DataSource sastDataSource() {
DruidDataSource sastDataSource = new DruidDataSource();
sastDataSource.setDriverClassName(sastDriverClass);
sastDataSource.setUrl(sastUrl);
sastDataSource.setUsername(sastUsername);
sastDataSource.setPassword(sastPassword);
sastDataSource.setMinIdle(sastMinIdle);
sastDataSource.setMaxActive(sastMaxActive);
sastDataSource.setMinIdle(sastMinIdle);
sastDataSource.setTestOnBorrow(sastTestOnBorrow);
sastDataSource.setTestOnReturn(sastTestOnReturn);
sastDataSource.setTestWhileIdle(sastTestWhileIdle);
sastDataSource.setValidationQuery(sastValidationQuery);
// 连接失败后中断---重试10次
sastDataSource.setBreakAfterAcquireFailure(true);
sastDataSource.setConnectionErrorRetryAttempts(10);
// 快速失败
sastDataSource.setFailFast(true);
return sastDataSource;
}
@Bean
@Primary
public DataSource dynamicDataSource() {
Map<Object, Object> dataSourceMap = new HashMap<>(2);
dataSourceMap.put(MASTER, masterDataSource());
dataSourceMap.put(READONLY, slaveDataSource());
dataSourceMap.put(GITEA, giteaDataSource());
dataSourceMap.put(SAST, sastDataSource());
//设置动态数据源
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(dataSourceMap);

View File

@ -0,0 +1,46 @@
package net.educoder.quality.common.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import tk.mybatis.spring.annotation.MapperScan;
import javax.sql.DataSource;
/**
* @Author: youys
* @Date: 2022/9/15
* @Description:
*/
@Configuration
@MapperScan(basePackages = "net.educoder.quality.mapper.gitea", sqlSessionFactoryRef = "sqlSessionFactoryGiteaDataSource")
public class GiteaDatasourceConfig {
@Bean(name = "sqlSessionFactoryGiteaDataSource")
public SqlSessionFactory sqlSessionFactoryDdsDataSource(@Qualifier("gitea") DataSource masterDataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(masterDataSource);
//下边两句仅仅用于*.xml文件如果整个持久层操作不需要使用到xml文件的话只用注解就可以搞定则不加
//指定entity和mapperxml的路径
factoryBean.setTypeAliasesPackage("net.educoder.quality.entity.gitea");
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:gitea.mapper/*Mapper.xml"));
return factoryBean.getObject();
}
@Bean(name = "giteaPlatformTransactionManager")
public PlatformTransactionManager platformTransactionManager(@Qualifier("gitea") DataSource giteaDataSource){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(giteaDataSource);
return dataSourceTransactionManager;
}
}

View File

@ -0,0 +1,42 @@
package net.educoder.quality.common.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* @Author: youys
* @Date: 2022/10/14
* @Description:
*/
@Data
@Configuration
public class PropertiesConfig {
@Value("${sonar.workspace}")
private String workspace;
@Value("${openi.gitUsername}")
private String gitUsername;
@Value("${openi.gitPassword}")
private String gitPassword;
@Value("${nil.mil}")
private String mil;
@Value("${nil.mit}")
private String mit;
@Value("${nil.filtrationThreshold}")
private String filtrationThreshold;
@Value("${nil.verificationThreshold}")
private String verificationThreshold;
@Value("${nil.jarPath}")
private String nilJarPath;
@Value("${sast.driver}")
private String sastDriver;
}

View File

@ -0,0 +1,35 @@
package net.educoder.quality.common.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import tk.mybatis.spring.annotation.MapperScan;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "net.educoder.quality.mapper.sast", sqlSessionFactoryRef = "sqlSessionFactorySastDataSource")
public class SastDatasourceConfig {
@Bean(name = "sqlSessionFactorySastDataSource")
public SqlSessionFactory sqlSessionFactoryDdsDataSource(@Qualifier("sast") DataSource sastDataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(sastDataSource);
factoryBean.setTypeAliasesPackage("net.educoder.quality.entity.sast");
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:sast.mapper/*Mapper.xml"));
return factoryBean.getObject();
}
@Bean(name = "sastPlatformTransactionManager")
public PlatformTransactionManager platformTransactionManager(@Qualifier("sast") DataSource sastDataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(sastDataSource);
return dataSourceTransactionManager;
}
}

View File

@ -1,8 +1,11 @@
package net.educoder.quality.common.config;
import net.educoder.quality.common.filter.MdcTaskDecorator;
import net.educoder.quality.common.util.mdc.MdcThreadPoolTaskScheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
/**
@ -15,7 +18,7 @@ public class ThreadPoolConfig {
@Bean("sonarScannerThreadPool")
public ThreadPoolTaskExecutor sonarScannerThreadPool(){
public ThreadPoolTaskExecutor sonarScannerThreadPool() {
ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
threadPoolExecutor.setCorePoolSize(100);
threadPoolExecutor.setMaxPoolSize(100);
@ -23,12 +26,26 @@ public class ThreadPoolConfig {
threadPoolExecutor.setThreadNamePrefix("sonar-thread-");
threadPoolExecutor.setWaitForTasksToCompleteOnShutdown(true);
threadPoolExecutor.setAwaitTerminationMillis(5);
threadPoolExecutor.setTaskDecorator(new MdcTaskDecorator());
return threadPoolExecutor;
}
@Bean("cloneDetectionThreadPool")
public ThreadPoolTaskExecutor cloneDetectionThreadPool() {
ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
threadPoolExecutor.setCorePoolSize(100);
threadPoolExecutor.setMaxPoolSize(100);
threadPoolExecutor.setQueueCapacity(5000);
threadPoolExecutor.setThreadNamePrefix("clone-detection-thread-");
threadPoolExecutor.setWaitForTasksToCompleteOnShutdown(true);
threadPoolExecutor.setAwaitTerminationMillis(5);
threadPoolExecutor.setTaskDecorator(new MdcTaskDecorator());
return threadPoolExecutor;
}
@Bean("sonarQueryResultThreadPool")
public ThreadPoolTaskExecutor sonarQueryResultThreadPool(){
public ThreadPoolTaskExecutor sonarQueryResultThreadPool() {
ThreadPoolTaskExecutor sonarQueryResultThreadPool = new ThreadPoolTaskExecutor();
sonarQueryResultThreadPool.setCorePoolSize(100);
sonarQueryResultThreadPool.setMaxPoolSize(100);
@ -36,7 +53,38 @@ public class ThreadPoolConfig {
sonarQueryResultThreadPool.setThreadNamePrefix("sonar-result-thread-");
sonarQueryResultThreadPool.setWaitForTasksToCompleteOnShutdown(true);
sonarQueryResultThreadPool.setAwaitTerminationMillis(5);
sonarQueryResultThreadPool.setTaskDecorator(new MdcTaskDecorator());
return sonarQueryResultThreadPool;
}
@Bean("parseComponentThreadPool")
public ThreadPoolTaskExecutor parseComponentThreadPool() {
ThreadPoolTaskExecutor parseComponentThreadPool = new ThreadPoolTaskExecutor();
parseComponentThreadPool.setCorePoolSize(10);
parseComponentThreadPool.setMaxPoolSize(20);
parseComponentThreadPool.setQueueCapacity(5000);
parseComponentThreadPool.setThreadNamePrefix("parse-component-");
parseComponentThreadPool.setWaitForTasksToCompleteOnShutdown(true);
parseComponentThreadPool.setAwaitTerminationMillis(5);
parseComponentThreadPool.setTaskDecorator(new MdcTaskDecorator());
return parseComponentThreadPool;
}
/**
* 配置schedule 定时任务多线程处理
* beanName必须命名threadPoolTaskScheduler
*
* @return
*/
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
MdcThreadPoolTaskScheduler taskScheduler = new MdcThreadPoolTaskScheduler();
//核心线程池数量方法: 返回可用处理器的Java虚拟机的数量
taskScheduler.setPoolSize(20);
taskScheduler.setThreadNamePrefix("schedule-");
return taskScheduler;
}
}

View File

@ -11,6 +11,7 @@ public interface QualityConstants {
String C = "c";
String CXX = "cpp";
String CPP = "c++";
String NET = "c#";
String OTHER = "other";

View File

@ -0,0 +1,57 @@
package net.educoder.quality.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Author: youys
* @Date: 2022/9/26
* @Description:
*/
@Getter
@AllArgsConstructor
public enum BugTypeEnum {
ALL("all", "ALL", "全部"),
CRITICAL("critical", "CRITICAL", "严重"),
HIGH("high", "BLOCKER", "高危"),
MIDDLE("middle", "MAJOR", "中危"),
LOW("low", "MINOR", "低危"),
;
String bugType;
String dbValue;
String description;
public static BugTypeEnum getBugTypeEnum(String bugType){
for (BugTypeEnum bugTypeEnum : BugTypeEnum.values()) {
if(bugTypeEnum.bugType.equals(bugType)){
return bugTypeEnum;
}
}
return null;
}
public static BugTypeEnum getBugTypeEnumByDbValue(String dbValue){
for (BugTypeEnum bugTypeEnum : BugTypeEnum.values()) {
if(bugTypeEnum.dbValue.equals(dbValue)){
return bugTypeEnum;
}
}
return null;
}
public static String getDescriptionByDbValue(String dbValue){
if (dbValue==null || "".equals(dbValue)){
return null;
}
for (BugTypeEnum bugTypeEnum : BugTypeEnum.values()) {
if(bugTypeEnum.dbValue.equals(dbValue)){
return bugTypeEnum.description;
}
}
return null;
}
}

View File

@ -1,53 +0,0 @@
package net.educoder.quality.common.enums;
/**
* 通用状态枚举 0为否定含义1为肯定含义
* @author 威少
*/
public enum CommonStateEnum {
/**
* 否定含义
*/
FALSE(0, false),
/**
* 肯定含义
*/
TRUE(1, true);
int value;
boolean booleanValue;
CommonStateEnum(int value, boolean booleanValue) {
this.value = value;
this.booleanValue = booleanValue;
}
public int getValue() {
return value;
}
public boolean getBooleanValue() {
return booleanValue;
}
/**
* 从bool值转换
* @param value bool值
* @return 肯定为1否定为0
*/
public static CommonStateEnum fromBoolean(Boolean value) {
return value == null ? FALSE : value ? TRUE : FALSE;
}
/**
* 从整型值转换
* @param value 整型值
* @return 肯定为1否定为0
*/
public static CommonStateEnum fromInteger(Integer value) {
return value == null || value == FALSE.getValue() ? FALSE : TRUE;
}
}

View File

@ -21,4 +21,15 @@ public enum DetectResultCompareEnum {
Integer type;
String desc;
public static DetectResultCompareEnum getDetectResultCompareEnum(int type) {
for (DetectResultCompareEnum detectResultCompareEnum : DetectResultCompareEnum.values()) {
if (detectResultCompareEnum.getType() == type) {
return detectResultCompareEnum;
}
}
return null;
}
}

View File

@ -13,7 +13,10 @@ public enum ErrorCodeEnum {
PARAM_ERROR("000002","传参错误"),
FILE_SAVE_ERROR("000003","文件保存失败,请重试"),
TEMPLATE_NAME_ALREADY_EXISTS("000004","模板名称已存在"),
PROJECT_NOT_SUCCESS("000005","该项目未检测或者未有成功的检测"),
PROJECT_NOT_EXISTS("000006","该项目不存在"),
BIND_EXCEPTION("000007","参数绑定异常"),
NOT_FUND_VULNERABILITY("000008","未找到漏洞信息"),
MVC_BIND_EXCEPTION("000014","请求参数绑定异常"),
METHOD_NOT_ALLOWED_EXCEPTION("000008","请求方式异常"),
EXCEPTION("999999","系统异常"),
@ -25,6 +28,11 @@ public enum ErrorCodeEnum {
AFTERMATH_EXP("000013","评测线程出错,善后处理发生异常"),
GIT_FAIL("000014","获取git凭证失败: "),
GIT_CREDENTIAL_FAIL("000015","设置git凭证失败:"),
GIT_CREDENTIAL_INVALID("000016","git账号密码不匹配"),
GIT_URL_INVALID("000017","非法的git地址"),
COMPONENT_NOT_FOUND("000018","组件未找到"),
LICENSE_NOT_FOUND("000019","许可证未找到"),
UNDER_DETECTION_ERROR("000020","项目正在检测中,请稍后再试"),
;
String value;

View File

@ -13,8 +13,8 @@ import lombok.Getter;
public enum IssueTypeEnum {
VULNERABILITY(3, "漏洞"),
BUG(2, "缺陷")
BUG(2, "缺陷"),
VULNERABILITY(3, "漏洞")
;
/**

View File

@ -10,13 +10,11 @@ import lombok.Getter;
*/
@Getter
@AllArgsConstructor
public enum SourceEnum {
public enum TaskInfoStatusEnum {
LOCAL("local", "本地文件"),
GIT("git", "git地址"),
SVN("svn", "svn地址");
SUCCESS(1, "成功"),
FAILED(-1, "失败");
private String source;
private Integer status;
private String desc;
}

View File

@ -0,0 +1,49 @@
package net.educoder.quality.common.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.util.ContentCachingRequestWrapper;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @Author: youys
* @Date: 2022/9/21
* @Description: 缓存request请求流
*/
@Slf4j
@WebFilter(urlPatterns = "/*")
public class CachingContentFilter implements Filter {
private static final String FORM_CONTENT_TYPE = "multipart/form-data";
private static final String METHOD_GET = "GET";
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
String contentType = request.getContentType();
if (request instanceof HttpServletRequest) {
HttpServletRequest requestWrapper = new ContentCachingRequestWrapper((HttpServletRequest) request);
if (contentType != null && contentType.contains(FORM_CONTENT_TYPE)) {
chain.doFilter(request, response);
}else if(METHOD_GET.equalsIgnoreCase(((HttpServletRequest) request).getMethod())){
chain.doFilter(request, response);
}
else {
chain.doFilter(requestWrapper, response);
}
return;
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}

View File

@ -0,0 +1,39 @@
package net.educoder.quality.common.filter;
import org.slf4j.MDC;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.util.UUID;
/**
* @Author: youys
* @Date: 2022/10/18
* @Description:
*/
@WebFilter(urlPatterns = "/*", filterName = "logbackFilter")
public class LogbackFilter implements Filter {
private static final String UNIQUE_ID = "traceId";
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
boolean bInsertMDC = insertMDC();
try {
chain.doFilter(request, response);
} finally {
if(bInsertMDC) {
MDC.remove(UNIQUE_ID);
}
}
}
private boolean insertMDC() {
UUID uuid = UUID.randomUUID();
String uniqueId = uuid.toString().replace("-", "");
MDC.put(UNIQUE_ID, uniqueId);
return true;
}
}

View File

@ -0,0 +1,28 @@
package net.educoder.quality.common.filter;
import org.slf4j.MDC;
import org.springframework.core.task.TaskDecorator;
import java.util.Map;
/**
* @Description
* @Author youys
* @Since 1.0
* @Date 2021/7/7
*/
public class MdcTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
Map<String,String> map = MDC.getCopyOfContextMap();
return () -> {
try{
MDC.setContextMap(map);
runnable.run();
} finally {
MDC.clear();
}
};
}
}

View File

@ -0,0 +1,184 @@
package net.educoder.quality.common.util;
import cn.hutool.core.date.DateUtil;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;
/**
* Cron表达式工具类quartz类
* 符号表示的值
* * 表示所有值
* ? 表示未说明的值即不关心它为何值
* - 表示一个指定的范围
* , 表示附加一个可能值
* / 符号前表示开始时间符号后表示每次递增的值
* L("last") ("last") "L" 用在day-of-month字段意思是 "这个月最后一天"
* W("weekday") 只能用在day-of-month字段用来描叙最接近指定天的工作日周一到周五
* @author jshixiong
*/
public class CronUtil {
private static final SimpleDateFormat sdf = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
/**
* 可选 留空
* 允许的特殊字符留空, 1970-2099 , - * /
*/
private String year;
/**
* 星期 可以用数字1-7表示1 星期日或用字符口串SUN, MON, TUE, WED, THU, FRI and SAT表示
* 允许的特殊字符1-7 或者 SUN-SAT , - * ? / L C #
*/
private String week;
/**
* 可以用0-11 或用字符串 JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC 表示
* 允许的特殊字符1-12 或者 JAN-DEC , - * /
*/
private String month;
/**
* 可以用数字1-31 中的任一一个值但要注意一些特别的月份
* 允许的特殊字符1-31 , - * ? / L W C
*/
private String day;
/**
* 可以用数字0-23表示
* 允许的特殊字符0-23, - * /
*/
private String hour;
/**
* 可以用数字059 表示
* 允许的特殊字符0-59,- * /
*/
private String minutes;
/**
* 可以用数字059 表示
* 允许的特殊字符0-59,- * /
*/
private String seconds ;
/***
* 日期转换cron表达式 例如 "0 07 10 15 1 ? 2016"
* @param date 时间点
* @return
*/
public static String getCron(Date date) {
String formatTimeStr = null;
if (Objects.nonNull(date)) {
formatTimeStr = sdf.format(date);
}
return formatTimeStr;
}
/***
* 日期转换cron表达式 例如 "0 07 10 15 1 ? 2016"
* @param date 时间点
* @return
*/
public static String getCron(LocalDateTime date) {
String formatTimeStr = null;
if (Objects.nonNull(date)) {
formatTimeStr = DateUtil.format(date,"ss mm HH dd MM ? yyyy");
}
return formatTimeStr;
}
/***
* 忽略年份
* 日期转换cron表达式 例如 "0 07 10 15 1 ?"
* @param date 时间点
* @return
*/
public static String getCronIgnoreYear(LocalDateTime date) {
String formatTimeStr = null;
if (Objects.nonNull(date)) {
formatTimeStr = DateUtil.format(date,"ss mm HH dd MM ?");
}
return formatTimeStr;
}
/**
* 获取指定日期的cron表达式
* @param year
* @param week 星期 可以用数字1-7表示1 星期日或用字符口串SUN, MON, TUE, WED, THU, FRI and SAT表示
* @param month 可以用0-11 或用字符串 JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC 表示
* @param day 可以用数字1-31 中的任一一个值但要注意一些特别的月份
* @param hour 可以用数字0-23表示
* @param minutes 可以用数字059 表示
* @param seconds 可以用数字059 表示
* @return
*/
public static String getCron(String year,String week,String month,String day,String hour,String minutes,String seconds) {
return seconds+" "+minutes+" "+hour+" "+day+" "+month+" "+week+" "+year;
}
/**
* 获取指定日期的cron表达式
* @param week 星期 可以用数字1-7表示1 星期日或用字符口串SUN, MON, TUE, WED, THU, FRI and SAT表示
* @param month 可以用0-11 或用字符串 JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC 表示
* @param day 可以用数字1-31 中的任一一个值但要注意一些特别的月份
* @param hour 可以用数字0-23表示
* @param minutes 可以用数字059 表示
* @param seconds 可以用数字059 表示
* @return
*/
public static String getCron(String week,String month,String day,String hour,String minutes,String seconds) {
return getCron("*",week,month,day,hour,minutes,seconds);
}
/**
* 获取指定日期的cron表达式
* @param month 可以用0-11 或用字符串 JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC 表示
* @param day 可以用数字1-31 中的任一一个值但要注意一些特别的月份
* @param hour 可以用数字0-23表示
* @param minutes 可以用数字059 表示
* @param seconds 可以用数字059 表示
* @return
*/
static String getCron(String month,String day,String hour,String minutes,String seconds) {
return getCron("?",month,day,hour,minutes,seconds);
}
/**
* 获取指定范围的Cron表达式 例如 13-14 30-31 11-12 20-21 04-05 1-2 2021-2022
* @param year 使用year1-year2 year1<=year2
* @param week 星期 使用week1-week2 可以用数字1-7表示1 星期日或用字符口串SUN, MON, TUE, WED, THU, FRI and SAT表示
* @param month 使用month1-month2 可以用0-11 或用字符串 JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC 表示
* @param day 使用day1-day2 可以用数字1-31 中的任一一个值但要注意一些特别的月份
* @param hour 使用hour1-hour2 可以用数字0-23表示
* @param minutes 使用minutes1-minutes2 可以用数字059 表示
* @param seconds 使用seconds1-seconds2 可以用数字059 表示
* @return
*/
public static String getCronByRange(String year,String week,String month,String day,String hour,String minutes,String seconds) {
return seconds+" "+minutes+" "+hour+" "+day+" "+month+" "+week+" "+year;
}
/**
* 获取指定范围的Cron表达式 例如 13-14 30-31 11-12 20-21 04-05 1-2
* @param week 星期 使用week1-week2 可以用数字1-7表示1 星期日或用字符口串SUN, MON, TUE, WED, THU, FRI and SAT表示
* @param month 使用month1-month2 可以用0-11 或用字符串 JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC 表示
* @param day 使用day1-day2 可以用数字1-31 中的任一一个值但要注意一些特别的月份
* @param hour 使用hour1-hour2 可以用数字0-23表示
* @param minutes 使用minutes1-minutes2 可以用数字059 表示
* @param seconds 使用seconds1-seconds2 可以用数字059 表示
* @return
*/
public static String getCronByRange(String week,String month,String day,String hour,String minutes,String seconds) {
return getCron("*",week,month,day,hour,minutes,seconds);
}
/**
* 获取指定范围的Cron表达式 例如 13-14 30-31 11-12 20-21 04-05
* @param month 使用month1-month2 可以用0-11 或用字符串 JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC 表示
* @param day 使用day1-day2 可以用数字1-31 中的任一一个值但要注意一些特别的月份
* @param hour 使用hour1-hour2 可以用数字0-23表示
* @param minutes 使用minutes1-minutes2 可以用数字059 表示
* @param seconds 使用seconds1-seconds2 可以用数字059 表示
* @return
*/
static String getCronByRange(String month,String day,String hour,String minutes,String seconds) {
return getCron("?",month,day,hour,minutes,seconds);
}
}

View File

@ -0,0 +1,38 @@
package net.educoder.quality.common.util;
import lombok.extern.slf4j.Slf4j;
import net.educoder.quality.common.bean.ShellResult;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
/**
* @Author: youys
* @Date: 2022/10/14
* @Description:
*/
@Slf4j
public class GitUtil {
/**
* 克隆代码到指定目录
*/
public static ShellResult gitClone(String gitUrl, String branch, String username, String password, String fullWorkspace) {
File file = new File(fullWorkspace);
if (!file.exists()) {
file.mkdirs();
}
int index = gitUrl.lastIndexOf("//");
String command;
if (StringUtils.isNotBlank(username)) {
command = StringUtils.join("cd ", fullWorkspace, " && git clone -b ", branch, " ", gitUrl.substring(0, index + 2), username, ":",
password, "@", gitUrl.substring(index + 2));
} else {
command = StringUtils.join("cd ", fullWorkspace, " && git clone -b ", branch, " ", gitUrl.substring(0, index + 2), gitUrl.substring(index + 2));
}
return ShellUtil.executeAndGetExitStatus(command);
}
}

View File

@ -94,7 +94,6 @@ public final class ShellUtil {
continue;
}
logger.debug("executeAndGetExitStatus line: {}", line); // TODO 此处稳定后去除
out.append(line);
out.append(System.getProperty("line.separator"));
}

View File

@ -0,0 +1,220 @@
package net.educoder.quality.common.util;
import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @Author: youys
* @Date: 2022/9/23
* @Description:
*/
public class WordUtil {
public static void changeText(XWPFDocument document, Map<String, String> textMap) {
//获取段落集合
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
//判断此段落时候需要进行替换
String text = paragraph.getText();
if (StringUtils.isNotBlank(text) && text.contains("${")) {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
//替换模板原来位置
String textValue = changeValue(run.toString(), textMap);
run.setText(textValue, 0);
}
}
}
}
/**
* 匹配传入信息集合与模板
*
* @param value 模板需要替换的区域
* @param textMap 传入信息集合
* @return 模板需要替换区域信息集合对应值
*/
public static String changeValue(String value, Map<String, String> textMap) {
Set<Map.Entry<String, String>> textSets = textMap.entrySet();
for (Map.Entry<String, String> textSet : textSets) {
//匹配模板与替换值 格式${key}
String key = "${" + textSet.getKey() + "}";
if (value.indexOf(key) != -1) {
value = value.replace(key, textSet.getValue());
}
}
return value;
}
/**
* 取得某个表格多行的段落
* @param table XWPFTable
*/
public static List<XWPFParagraph> getTableRowsParagraphs(XWPFTable table,int begain,int end) {
List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
// 列表内段落
for (int i = begain;i<=end;i++){
XWPFTableRow row = table.getRow(i);
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
paragraphs.addAll(cell.getParagraphs());
}
}
return paragraphs;
}
/**
* 取得一行的段落
* @param row 一行
*/
public static List<XWPFParagraph> getRowParagraphs(XWPFTableRow row) {
List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
paragraphs.addAll(cell.getParagraphs());
}
return paragraphs;
}
/**
* insertRow 在word表格中指定位置插入一行并将某一行的样式及内容复制到新增行
* */
public static XWPFTableRow insertRow(XWPFTable table, XWPFTableRow copyRow, int newrowIndex) {
// 在表格中指定的位置新增一行
XWPFTableRow targetRow = table.insertNewTableRow(newrowIndex);
//复制行对象
targetRow.getCtRow().setTrPr(copyRow.getCtRow().getTrPr());
//或许需要复制的行的列
List<XWPFTableCell> copyCells = copyRow.getTableCells();
//复制列对象
XWPFTableCell targetCell = null;
for (int i = 0; i < copyCells.size(); i++) {
XWPFTableCell copyCell = copyCells.get(i);
targetCell = targetRow.addNewTableCell();
targetCell.getCTTc().setTcPr(copyCell.getCTTc().getTcPr());
if (copyCell.getParagraphs() != null && copyCell.getParagraphs().size() > 0) {
targetCell.getParagraphs().get(0).getCTP().setPPr(copyCell.getParagraphs().get(0).getCTP().getPPr());
if (copyCell.getParagraphs().get(0).getRuns() != null
&& copyCell.getParagraphs().get(0).getRuns().size() > 0) {
XWPFRun cellRun = targetCell.getParagraphs().get(0).createRun();
XWPFRun copyRun = copyCell.getParagraphs().get(0).getRuns().get(0);
//字体名称
cellRun.setFontFamily(copyRun.getFontFamily());
//字体颜色
cellRun.setColor(copyRun.getColor());
//字体加粗
cellRun.setBold(copyRun.isBold());
//字体倾斜
cellRun.setItalic(copyRun.isItalic());
cellRun.setText(copyCell.getText());
}
}
}
return targetRow;
}
/**
* 替换全部文本
* @param textMap 替换信息
* @param paragraphs 段落
*/
public static void replaceAllTexts(Map<String, String> textMap, List<XWPFParagraph> paragraphs) {
Set<Map.Entry<String, String>> textEntrySet = textMap.entrySet();
for (Map.Entry<String, String> entry : textEntrySet) {
String key = entry.getKey();
String value = entry.getValue();
// 替换全部文本
replaceAllTexts(key, value, paragraphs);
}
}
/**
* 替换全部文本
* @param key 替换键
* @param value 替换值
* @param paragraphs 段落
*/
public static void replaceAllTexts(String key, String value, List<XWPFParagraph> paragraphs) {
for (XWPFParagraph paragraph : paragraphs) {
// 待替换文本
String text = paragraph.getText();
if (StringUtils.isNotEmpty(text) && text.indexOf(key) != -1) {
List<XWPFRun> runs = paragraph.getRuns();
// 只保留第一个Run
for (int i = (runs.size() - 1); i > 0; i--) {
paragraph.removeRun(i);
}
runs.get(0).setText(text.replace(key, value), 0);
}
}
}
/**
* 保存Word
* @param document Word文档
* @param filePath 保存路径
*/
public static void save(XWPFDocument document, String filePath) throws Exception {
FileOutputStream fos = null;
try {
System.out.println("POI生成Word文件" + filePath);
File file = new File(filePath);
// FileUtil.makeDir(file.getParentFile());
fos = new FileOutputStream(file);
document.write(fos);
} finally {
if (fos != null) {
fos.close();
}
}
}
/**
* 打开Word
* @param filePath 文件全路径
*/
public static XWPFDocument open(String filePath) throws Exception {
InputStream is = null;
try {
System.out.println("POI打开Word文件" + filePath);
is = new FileInputStream(filePath);
return new XWPFDocument(is);
} finally {
if (is != null) {
is.close();
}
}
}
/**
* word转pdf
* 功能依赖于poi 3.17
* linux或win环境下需要相应的中文字体支持宋体微软雅黑...否则中文不显示
* @param document
*/
public static void docToPdf(XWPFDocument document,OutputStream outPDF ){
PdfOptions options = PdfOptions.create();
try {
PdfConverter.getInstance().convert(document, outPDF, options);
}catch (IOException e){
e.printStackTrace();
}finally {
try {
if (outPDF!=null){
outPDF.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

View File

@ -0,0 +1,73 @@
/*
* SonarQube
* Copyright (C) 2009-2019 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package net.educoder.quality.common.util.html;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
class CharactersReader {
static final int END_OF_STREAM = -1;
private final BufferedReader stringBuffer;
private final Deque<String> openTags;
private int currentValue;
private int previousValue;
private int currentIndex = -1;
public CharactersReader(BufferedReader stringBuffer) {
this.stringBuffer = stringBuffer;
this.openTags = new ArrayDeque<>();
}
boolean readNextChar() throws IOException {
previousValue = currentValue;
currentValue = stringBuffer.read();
currentIndex++;
return currentValue != END_OF_STREAM;
}
int getCurrentValue() {
return currentValue;
}
int getPreviousValue() {
return previousValue;
}
int getCurrentIndex() {
return currentIndex;
}
void registerOpenTag(String textType) {
openTags.push(textType);
}
void removeLastOpenTag() {
openTags.remove();
}
Deque<String> getOpenTags() {
return openTags;
}
}

View File

@ -0,0 +1,133 @@
/*
* SonarQube
* Copyright (C) 2009-2019 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package net.educoder.quality.common.util.html;
import com.google.common.collect.Lists;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
class DecorationDataHolder {
private static final String ENTITY_SEPARATOR = ";";
private static final String FIELD_SEPARATOR = ",";
private static final String SYMBOL_PREFIX = "sym-";
private static final String HIGHLIGHTABLE = "sym";
private List<OpeningHtmlTag> openingTagsEntries;
private int openingTagsIndex;
private List<Integer> closingTagsOffsets;
private int closingTagsIndex;
DecorationDataHolder() {
openingTagsEntries = Lists.newArrayList();
closingTagsOffsets = Lists.newArrayList();
}
void loadSymbolReferences(String symbolsReferences) {
String[] symbols = symbolsReferences.split(ENTITY_SEPARATOR);
for (String symbol : symbols) {
String[] symbolFields = symbol.split(FIELD_SEPARATOR);
int declarationStartOffset = Integer.parseInt(symbolFields[0]);
int declarationEndOffset = Integer.parseInt(symbolFields[1]);
int symbolLength = declarationEndOffset - declarationStartOffset;
String[] symbolOccurrences = Arrays.copyOfRange(symbolFields, 2, symbolFields.length);
loadSymbolOccurrences(declarationStartOffset, symbolLength, symbolOccurrences);
}
}
void loadLineSymbolReferences(String symbolsReferences) {
String[] symbols = symbolsReferences.split(ENTITY_SEPARATOR);
for (String symbol : symbols) {
String[] symbolFields = symbol.split(FIELD_SEPARATOR);
int startOffset = Integer.parseInt(symbolFields[0]);
int endOffset = Integer.parseInt(symbolFields[1]);
int symbolLength = endOffset - startOffset;
int symbolId = Integer.parseInt(symbolFields[2]);
loadSymbolOccurrences(symbolId, symbolLength, new String[] { Integer.toString(startOffset) });
}
}
void loadSyntaxHighlightingData(String syntaxHighlightingRules) {
String[] rules = syntaxHighlightingRules.split(ENTITY_SEPARATOR);
for (String rule : rules) {
String[] ruleFields = rule.split(FIELD_SEPARATOR);
int startOffset = Integer.parseInt(ruleFields[0]);
int endOffset = Integer.parseInt(ruleFields[1]);
if (startOffset < endOffset) {
insertAndPreserveOrder(new OpeningHtmlTag(startOffset, ruleFields[2]), openingTagsEntries);
insertAndPreserveOrder(endOffset, closingTagsOffsets);
}
}
}
List<OpeningHtmlTag> getOpeningTagsEntries() {
return openingTagsEntries;
}
OpeningHtmlTag getCurrentOpeningTagEntry() {
return openingTagsIndex < openingTagsEntries.size() ? openingTagsEntries.get(openingTagsIndex) : null;
}
void nextOpeningTagEntry() {
openingTagsIndex++;
}
List<Integer> getClosingTagsOffsets() {
return closingTagsOffsets;
}
int getCurrentClosingTagOffset() {
return closingTagsIndex < closingTagsOffsets.size() ? closingTagsOffsets.get(closingTagsIndex) : -1;
}
void nextClosingTagOffset() {
closingTagsIndex++;
}
private void loadSymbolOccurrences(int declarationStartOffset, int symbolLength, String[] symbolOccurrences) {
for (String symbolOccurrence : symbolOccurrences) {
int occurrenceStartOffset = Integer.parseInt(symbolOccurrence);
int occurrenceEndOffset = occurrenceStartOffset + symbolLength;
insertAndPreserveOrder(new OpeningHtmlTag(occurrenceStartOffset, SYMBOL_PREFIX + declarationStartOffset + " " + HIGHLIGHTABLE), openingTagsEntries);
insertAndPreserveOrder(occurrenceEndOffset, closingTagsOffsets);
}
}
private void insertAndPreserveOrder(OpeningHtmlTag newEntry, List<OpeningHtmlTag> openingHtmlTags) {
int insertionIndex = 0;
Iterator<OpeningHtmlTag> tagIterator = openingHtmlTags.iterator();
while (tagIterator.hasNext() && tagIterator.next().getStartOffset() <= newEntry.getStartOffset()) {
insertionIndex++;
}
openingHtmlTags.add(insertionIndex, newEntry);
}
private void insertAndPreserveOrder(int newOffset, List<Integer> orderedOffsets) {
int insertionIndex = 0;
Iterator<Integer> entriesIterator = orderedOffsets.iterator();
while (entriesIterator.hasNext() && entriesIterator.next() <= newOffset) {
insertionIndex++;
}
orderedOffsets.add(insertionIndex, newOffset);
}
}

View File

@ -0,0 +1,74 @@
/*
* SonarQube
* Copyright (C) 2009-2019 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package net.educoder.quality.common.util.html;
import org.apache.commons.lang3.StringUtils;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 给代码增加样式
*/
public final class HtmlSourceDecorator {
private static volatile HtmlSourceDecorator htmlSourceDecorator = null;
private HtmlSourceDecorator() {
}
public static HtmlSourceDecorator getInstance() {
if (htmlSourceDecorator == null) {
synchronized (HtmlSourceDecorator.class) {
if (htmlSourceDecorator == null) {
htmlSourceDecorator = new HtmlSourceDecorator();
}
}
}
return htmlSourceDecorator;
}
public String getDecoratedSourceAsHtml(@NotNull String sourceLine, @NotNull String highlighting, @NotNull String symbols) {
if (sourceLine == null) {
return null;
}
DecorationDataHolder decorationDataHolder = new DecorationDataHolder();
if (StringUtils.isNotBlank(highlighting)) {
decorationDataHolder.loadSyntaxHighlightingData(highlighting);
}
if (StringUtils.isNotBlank(symbols)) {
decorationDataHolder.loadLineSymbolReferences(symbols);
}
HtmlTextDecorator textDecorator = new HtmlTextDecorator();
List<String> decoratedSource = textDecorator.decorateTextWithHtml(sourceLine, decorationDataHolder, 1, 1);
if (decoratedSource == null) {
return null;
} else {
if (decoratedSource.isEmpty()) {
return "";
} else {
return decoratedSource.get(0);
}
}
}
}

View File

@ -0,0 +1,223 @@
/*
* SonarQube
* Copyright (C) 2009-2019 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package net.educoder.quality.common.util.html;
import com.google.common.io.Closeables;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.Nullable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Collection;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
@Slf4j
public class HtmlTextDecorator {
static final char CR_END_OF_LINE = '\r';
static final char LF_END_OF_LINE = '\n';
static final char HTML_OPENING = '<';
static final char HTML_CLOSING = '>';
static final char AMPERSAND = '&';
static final String ENCODED_HTML_OPENING = "&lt;";
static final String ENCODED_HTML_CLOSING = "&gt;";
static final String ENCODED_AMPERSAND = "&amp;";
List<String> decorateTextWithHtml(String text, DecorationDataHolder decorationDataHolder) {
return decorateTextWithHtml(text, decorationDataHolder, null, null);
}
List<String> decorateTextWithHtml(String text, DecorationDataHolder decorationDataHolder, @Nullable Integer from, @Nullable Integer to) {
StringBuilder currentHtmlLine = new StringBuilder();
List<String> decoratedHtmlLines = newArrayList();
int currentLine = 1;
BufferedReader stringBuffer = null;
try {
stringBuffer = new BufferedReader(new StringReader(text));
CharactersReader charsReader = new CharactersReader(stringBuffer);
while (charsReader.readNextChar()) {
if (shouldStop(currentLine, to)) {
break;
}
if (shouldStartNewLine(charsReader)) {
if (canAddLine(currentLine, from)) {
decoratedHtmlLines.add(currentHtmlLine.toString());
}
currentLine++;
currentHtmlLine = new StringBuilder();
}
addCharToCurrentLine(charsReader, currentHtmlLine, decorationDataHolder);
}
closeCurrentSyntaxTags(charsReader, currentHtmlLine);
if (shouldStartNewLine(charsReader)) {
addLine(decoratedHtmlLines, currentHtmlLine.toString(), currentLine, from, to);
currentLine++;
addLine(decoratedHtmlLines, "", currentLine, from, to);
} else if (currentHtmlLine.length() > 0) {
addLine(decoratedHtmlLines, currentHtmlLine.toString(), currentLine, from, to);
}
} catch (IOException exception) {
String errorMsg = "An exception occurred while highlighting the syntax of one of the project's files";
log.error(errorMsg);
throw new IllegalStateException(errorMsg, exception);
} finally {
Closeables.closeQuietly(stringBuffer);
}
return decoratedHtmlLines;
}
private void addCharToCurrentLine(CharactersReader charsReader, StringBuilder currentHtmlLine, DecorationDataHolder decorationDataHolder) {
if (shouldStartNewLine(charsReader)) {
if (shouldReopenPendingTags(charsReader)) {
reopenCurrentSyntaxTags(charsReader, currentHtmlLine);
}
}
int numberOfTagsToClose = getNumberOfTagsToClose(charsReader.getCurrentIndex(), decorationDataHolder);
closeCompletedTags(charsReader, numberOfTagsToClose, currentHtmlLine);
if (shouldClosePendingTags(charsReader)) {
closeCurrentSyntaxTags(charsReader, currentHtmlLine);
}
Collection<String> tagsToOpen = getTagsToOpen(charsReader.getCurrentIndex(), decorationDataHolder);
openNewTags(charsReader, tagsToOpen, currentHtmlLine);
if (shouldAppendCharToHtmlOutput(charsReader)) {
char currentChar = (char) charsReader.getCurrentValue();
currentHtmlLine.append(normalize(currentChar));
}
}
private static void addLine(List<String> decoratedHtmlLines, String line, int currentLine, @Nullable Integer from, @Nullable Integer to) {
if (canAddLine(currentLine, from) && !shouldStop(currentLine, to)) {
decoratedHtmlLines.add(line);
}
}
private static boolean canAddLine(int currentLine, @Nullable Integer from) {
return from == null || currentLine >= from;
}
private static boolean shouldStop(int currentLine, @Nullable Integer to) {
return to != null && to < currentLine;
}
private char[] normalize(char currentChar) {
char[] normalizedChars;
if (currentChar == HTML_OPENING) {
normalizedChars = ENCODED_HTML_OPENING.toCharArray();
} else if (currentChar == HTML_CLOSING) {
normalizedChars = ENCODED_HTML_CLOSING.toCharArray();
} else if (currentChar == AMPERSAND) {
normalizedChars = ENCODED_AMPERSAND.toCharArray();
} else {
normalizedChars = new char[] {currentChar};
}
return normalizedChars;
}
private boolean shouldAppendCharToHtmlOutput(CharactersReader charsReader) {
return charsReader.getCurrentValue() != CR_END_OF_LINE && charsReader.getCurrentValue() != LF_END_OF_LINE;
}
private int getNumberOfTagsToClose(int currentIndex, DecorationDataHolder dataHolder) {
int numberOfTagsToClose = 0;
while (currentIndex == dataHolder.getCurrentClosingTagOffset()) {
numberOfTagsToClose++;
dataHolder.nextClosingTagOffset();
}
return numberOfTagsToClose;
}
private Collection<String> getTagsToOpen(int currentIndex, DecorationDataHolder dataHolder) {
Collection<String> tagsToOpen = newArrayList();
while (dataHolder.getCurrentOpeningTagEntry() != null && currentIndex == dataHolder.getCurrentOpeningTagEntry().getStartOffset()) {
tagsToOpen.add(dataHolder.getCurrentOpeningTagEntry().getCssClass());
dataHolder.nextOpeningTagEntry();
}
return tagsToOpen;
}
private boolean shouldClosePendingTags(CharactersReader charactersReader) {
return charactersReader.getCurrentValue() == CR_END_OF_LINE
|| (charactersReader.getCurrentValue() == LF_END_OF_LINE && charactersReader.getPreviousValue() != CR_END_OF_LINE)
|| (charactersReader.getCurrentValue() == CharactersReader.END_OF_STREAM && charactersReader.getPreviousValue() != LF_END_OF_LINE);
}
private boolean shouldReopenPendingTags(CharactersReader charactersReader) {
return (charactersReader.getPreviousValue() == LF_END_OF_LINE && charactersReader.getCurrentValue() != LF_END_OF_LINE)
|| (charactersReader.getPreviousValue() == CR_END_OF_LINE && charactersReader.getCurrentValue() != CR_END_OF_LINE
&& charactersReader.getCurrentValue() != LF_END_OF_LINE);
}
private boolean shouldStartNewLine(CharactersReader charactersReader) {
return charactersReader.getPreviousValue() == LF_END_OF_LINE
|| (charactersReader.getPreviousValue() == CR_END_OF_LINE && charactersReader.getCurrentValue() != LF_END_OF_LINE);
}
private void closeCompletedTags(CharactersReader charactersReader, int numberOfTagsToClose,
StringBuilder decoratedText) {
for (int i = 0; i < numberOfTagsToClose; i++) {
injectClosingHtml(decoratedText);
charactersReader.removeLastOpenTag();
}
}
private void openNewTags(CharactersReader charactersReader, Collection<String> tagsToOpen,
StringBuilder decoratedText) {
for (String tagToOpen : tagsToOpen) {
injectOpeningHtmlForRule(tagToOpen, decoratedText);
charactersReader.registerOpenTag(tagToOpen);
}
}
private void closeCurrentSyntaxTags(CharactersReader charactersReader, StringBuilder decoratedText) {
for (int i = 0; i < charactersReader.getOpenTags().size(); i++) {
injectClosingHtml(decoratedText);
}
}
private void reopenCurrentSyntaxTags(CharactersReader charactersReader, StringBuilder decoratedText) {
for (String tags : charactersReader.getOpenTags()) {
injectOpeningHtmlForRule(tags, decoratedText);
}
}
private void injectOpeningHtmlForRule(String textType, StringBuilder decoratedText) {
decoratedText.append("<span class=\"").append(textType).append("\">");
}
private void injectClosingHtml(StringBuilder decoratedText) {
decoratedText.append("</span>");
}
}

View File

@ -0,0 +1,64 @@
/*
* SonarQube
* Copyright (C) 2009-2019 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package net.educoder.quality.common.util.html;
class OpeningHtmlTag {
private final int startOffset;
private final String cssClass;
OpeningHtmlTag(int startOffset, String cssClass) {
this.startOffset = startOffset;
this.cssClass = cssClass;
}
int getStartOffset() {
return startOffset;
}
String getCssClass() {
return cssClass;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
return compareTo((OpeningHtmlTag) o);
}
@Override
public int hashCode() {
int result = startOffset;
result = 31 * result + (cssClass != null ? cssClass.hashCode() : 0);
return result;
}
private boolean compareTo(OpeningHtmlTag otherTag) {
if (startOffset != otherTag.startOffset) {
return false;
}
return (cssClass != null) ? cssClass.equals(otherTag.cssClass) : (otherTag.cssClass == null);
}
}

View File

@ -0,0 +1,31 @@
package net.educoder.quality.common.util.mdc;
import cn.hutool.core.util.IdUtil;
import org.slf4j.MDC;
import java.util.Map;
/**
* @Author: youys
* @Date: 2023/2/27
* @Description:
*/
public class MdcTaskDecorator {
public static Runnable decorate(Runnable runnable) {
Map<String, String> contextMap = MDC.getCopyOfContextMap();
return () -> {
try {
if (contextMap != null) {
MDC.setContextMap(contextMap);
}
MDC.put("traceId", IdUtil.fastSimpleUUID());
runnable.run();
} finally {
MDC.clear();
}
};
}
}

View File

@ -0,0 +1,25 @@
package net.educoder.quality.common.util.mdc;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.Date;
import java.util.concurrent.ScheduledFuture;
/**
* @Author: youys
* @Date: 2023/2/27
* @Description:
*/
public class MdcThreadPoolTaskScheduler extends ThreadPoolTaskScheduler {
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
return super.scheduleWithFixedDelay(MdcTaskDecorator.decorate(task), startTime, delay);
}
@Override
public ScheduledFuture<?> schedule(Runnable task, Date startTime) {
return super.schedule(MdcTaskDecorator.decorate(task), startTime);
}
}

View File

@ -163,7 +163,12 @@
<version>${pagehelper.version}</version>
</dependency>
<!-- word to pdf -->
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.poi.xwpf.converter.pdf-gae</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
@ -196,6 +201,18 @@
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.21.6</version>
</dependency>
<dependency>
<groupId>net.jpountz.lz4</groupId>
<artifactId>lz4</artifactId>
<version>1.3.0</version>
</dependency>
</dependencies>
@ -257,7 +274,7 @@
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.py</include>
<include>**/*.docx</include>
<include>**/*.sh</include>
<include>**/*.xml</include>
<include>**/*.yml</include>

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parent</artifactId>
<artifactId>parent</artifactId>
<groupId>net.educoder.quality</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
@ -16,6 +16,14 @@
<description>web</description>
<packaging>jar</packaging>
<properties>
<targetJavaProject>${basedir}/src/main/java</targetJavaProject>
<targetMapperPackage>net.educoder.quality.mapper</targetMapperPackage>
<targetModelPackage>net.educoder.quality.entity.mysql</targetModelPackage>
<!-- XML生成路径 -->
<targetResourcesProject>${basedir}/src/main/resources</targetResourcesProject>
<targetXMLPackage>mysql.mapper</targetXMLPackage>
</properties>
<dependencies>
<dependency>
@ -23,8 +31,55 @@
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.15.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-launcher -->
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.9.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.1.5</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>

View File

@ -2,10 +2,13 @@ package net.educoder.quality;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@SpringBootApplication
@ServletComponentScan
@EnableAspectJAutoProxy(exposeProxy = true)
public class WebApplication {

View File

@ -1,9 +1,11 @@
package net.educoder.quality.aspect;
import com.alibaba.fastjson.JSONObject;
import net.educoder.quality.common.annotations.OperateLogAnnotation;
import net.educoder.quality.common.util.IpUtil;
import net.educoder.quality.entity.mysql.OperateLog;
import net.educoder.quality.service.OperateLogService;
import net.educoder.quality.vo.CommonVO;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@ -13,6 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.ContentCachingRequestWrapper;
import javax.servlet.http.HttpServletRequest;
@ -39,6 +42,25 @@ public class OperateLogAop {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 获取请求参数
CommonVO commonVO;
if(request instanceof ContentCachingRequestWrapper){
ContentCachingRequestWrapper requestWrapper = (ContentCachingRequestWrapper)request;
commonVO = JSONObject.parseObject(new String(requestWrapper.getContentAsByteArray()), CommonVO.class);
}else{
commonVO = new CommonVO();
commonVO.setCurrentUser(request.getParameter("currentUser"));
commonVO.setRepoOwner(request.getParameter("repoOwner"));
commonVO.setRepository(request.getParameter("repository"));
}
if (commonVO == null){
commonVO = new CommonVO();
commonVO.setCurrentUser(request.getParameter("currentUser"));
commonVO.setRepoOwner(request.getParameter("repoOwner"));
commonVO.setRepository(request.getParameter("repository"));
}
// 获取IP地址
String ipAddress = IpUtil.getIpAddress(request);
@ -46,17 +68,13 @@ public class OperateLogAop {
MethodSignature signature = (MethodSignature) pjp.getSignature();
OperateLogAnnotation annotation = signature.getMethod().getAnnotation(OperateLogAnnotation.class);
// 获取请求参数
String currentUser = request.getHeader("currentUser");
String repoOwner = request.getHeader("repoOwner");
String repository = request.getHeader("repository");
OperateLog operateLog = new OperateLog();
operateLog.setDescription(annotation.description());
operateLog.setClientIp(ipAddress);
operateLog.setOperator(currentUser);
operateLog.setRepoOwner(repoOwner);
operateLog.setRepository(repository);
operateLog.setOperator(commonVO.getCurrentUser());
operateLog.setRepoOwner(commonVO.getRepoOwner());
operateLog.setRepository(commonVO.getRepository());
try {
Object result = pjp.proceed();
operateLog.setResult("成功");

View File

@ -0,0 +1,52 @@
package net.educoder.quality.controller;
import net.educoder.quality.common.util.R;
import net.educoder.quality.dto.CloneDetectionStatisticsDTO;
import net.educoder.quality.service.CloneDetectionService;
import net.educoder.quality.vo.AddCloneDetectionVO;
import net.educoder.quality.vo.PageVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* 克隆检测控制器
*/
@RestController
public class CloneDetectionController {
@Autowired
private CloneDetectionService cloneDetectionService;
/**
* 添加一个项目的对比
*/
@PostMapping("/clone/detection/{projectId}/add")
public R add(@PathVariable Long projectId, @RequestBody @Valid AddCloneDetectionVO addCloneDetectionVO) {
cloneDetectionService.add(projectId, addCloneDetectionVO);
return R.success();
}
/**
* 克隆检测统计
*/
@GetMapping("/clone/detection/{projectId}/statistics")
public R<CloneDetectionStatisticsDTO> statistics(@PathVariable Long projectId) {
CloneDetectionStatisticsDTO cloneDetectionStatisticsDTO = cloneDetectionService.cloneDetectionStatistics(projectId);
return R.success(cloneDetectionStatisticsDTO);
}
/**
* 克隆检测列表
*/
@GetMapping("/clone/detection/{projectId}/list/{type}")
public R list(@PathVariable Long projectId, @PathVariable String type, @Valid PageVO pageVO) {
if ("file".equals(type) || "code".equals(type)) {
return R.success(cloneDetectionService.cloneDetectionResultFileCodeLevelList(projectId, pageVO));
} else {
return R.success(cloneDetectionService.cloneDetectionResultProjectLevelList(projectId, pageVO));
}
}
}

View File

@ -0,0 +1,89 @@
package net.educoder.quality.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageInfo;
import net.educoder.quality.common.util.R;
import net.educoder.quality.dto.*;
import net.educoder.quality.entity.mysql.ComponentParseRecordDetail;
import net.educoder.quality.service.ComponentService;
import net.educoder.quality.vo.PageVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: youys
* @Date: 2022/10/13
* @Description: 组件控制器
*/
@RestController
public class ComponentController {
@Autowired
private ComponentService componentService;
/**
* 组件解析
*
* @return
*/
@PostMapping("/component/{projectId}/parse")
public R parse(@PathVariable Long projectId) {
componentService.parseComponent(projectId);
return R.success();
}
/**
* 组件统计
*
* @return
*/
@GetMapping("/component/{projectId}/statistics")
public R<ComponentStatisticsDTO> statistics(@PathVariable Long projectId) {
ComponentStatisticsDTO componentStatisticsDTO = componentService.componentStatistics(projectId);
return R.success(componentStatisticsDTO);
}
@GetMapping("/component/{projectId}/list")
public R list(@PathVariable Long projectId, @Valid PageVO pageVO) {
PageInfo<ComponentParseRecordDetailDTO> componentListDTOPageInfo = componentService.componentList(projectId, pageVO);
List<ComponentListDTO> resultList = new ArrayList<>(componentListDTOPageInfo.getList().size());
for (ComponentParseRecordDetail componentParseRecordDetail : componentListDTOPageInfo.getList()) {
ComponentListDTO componentListDTO = new ComponentListDTO();
BeanUtils.copyProperties(componentParseRecordDetail, componentListDTO);
componentListDTO.setVulnerabilities(StringUtils.isNotEmpty(componentParseRecordDetail.getVulnerabilities()) ? JSON.parseArray(componentParseRecordDetail.getVulnerabilities()) : new JSONArray());
resultList.add(componentListDTO);
}
PageInfo<ComponentListDTO> pageInfo = new PageInfo<>();
BeanUtils.copyProperties(componentListDTOPageInfo, pageInfo);
pageInfo.setList(resultList);
return R.success(pageInfo);
}
@GetMapping("/component/detail/{id}")
public R<ComponentDetailDTO> getComponentDetail(@PathVariable Long id) {
ComponentDetailDTO detailDTO = componentService.getComponentDetail(id);
return R.success(detailDTO);
}
@GetMapping("/component/depend/{id}")
public R<DependComponentDTO> getDependComponent(@PathVariable Long id) {
List<DependComponentDTO> dependComponentList = componentService.getDependComponent(id);
return R.success(dependComponentList);
}
}

View File

@ -0,0 +1,44 @@
package net.educoder.quality.controller;
import net.educoder.quality.common.annotations.OperateLogAnnotation;
import net.educoder.quality.common.util.R;
import net.educoder.quality.entity.mysql.DetectionConfig;
import net.educoder.quality.service.DetectionConfigService;
import net.educoder.quality.vo.DetectionConfigVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* <p>
* 项目检测配置 前端控制器
* </p>
*
* @author jshixiong
* @since 2022-09-20
*/
@RestController
@RequestMapping("/detectionConfig")
public class DetectionConfigController {
@Autowired
private DetectionConfigService detectionConfigService;
@OperateLogAnnotation(description = "修改或新增检测配置")
@PostMapping("/editOrAdd")
public R editOrAdd(@Valid @RequestBody DetectionConfigVO config){
int i = detectionConfigService.editOrAdd(config);
if (i<0){
return R.failed("400","失败");
}
return R.success("成功");
}
@GetMapping("/getById/{id}")
public R getById(@PathVariable("id") Long id){
return R.success(detectionConfigService.getById(id));
}
}

View File

@ -54,13 +54,12 @@ public class OperateLogController {
@OperateLogAnnotation(description = "操作日志导出Excel")
public void exportExcel(@Valid OperateListVO operateListVO, HttpServletResponse response) throws IOException {
PageInfo<OperateLog> operateList = operateLogService.getOperateList(operateListVO);
List<OperateLog> operateList = operateLogService.exportExcel(operateListVO);
List<OperateLog> list = operateList.getList();
List<OperateLogExcelDTO> writeDataList = new ArrayList<>(list.size());
List<OperateLogExcelDTO> writeDataList = new ArrayList<>(operateList.size());
for (OperateLog operateLog : list) {
for (OperateLog operateLog : operateList) {
OperateLogExcelDTO excelDTO = new OperateLogExcelDTO();
BeanUtils.copyProperties(operateLog, excelDTO);
writeDataList.add(excelDTO);

View File

@ -1,18 +1,23 @@
package net.educoder.quality.controller;
import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageInfo;
import net.educoder.quality.common.annotations.OperateLogAnnotation;
import net.educoder.quality.common.util.R;
import net.educoder.quality.dto.CompareResultDTO;
import net.educoder.quality.dto.ProjectsDTO;
import net.educoder.quality.dto.*;
import net.educoder.quality.entity.mysql.ComponentParseRecordDetail;
import net.educoder.quality.entity.mysql.Projects;
import net.educoder.quality.service.ProjectService;
import net.educoder.quality.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -33,21 +38,11 @@ public class ProjectController {
/**
* 项目列表
*
* @param pageNum
* @param pageSize
* @param projectsVO
* @return
*/
@GetMapping("/projects")
public R<List<Projects>> getProjectList(@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam String repoOwner,
@RequestParam String repository) {
ProjectsVO projectsVO = new ProjectsVO();
projectsVO.setPageNum(pageNum);
projectsVO.setPageSize(pageSize);
projectsVO.setUsername(repoOwner);
projectsVO.setRepository(repository);
public R<List<Projects>> getProjectList(@Valid ProjectsVO projectsVO) {
PageInfo<ProjectsDTO> page = projectService.getProjectList(projectsVO);
return R.success(page);
}
@ -60,8 +55,8 @@ public class ProjectController {
*/
@PostMapping("/projects")
@OperateLogAnnotation(description = "添加项目")
public R addProject(AddProjectVO addProjectVO, @RequestParam("file") MultipartFile multipartFile) {
projectService.addProject(addProjectVO, multipartFile);
public R addProject(@RequestBody @Valid AddProjectVO addProjectVO) {
projectService.addProject(addProjectVO);
return R.success();
}
@ -79,18 +74,6 @@ public class ProjectController {
return R.success();
}
/**
* 项目详情
*
* @param projectId
* @return
*/
@GetMapping("/projects/{projectId}")
public R<Projects> getProjectDetail(@PathVariable Long projectId) {
Projects projects = projectService.getProjectDetail(projectId);
return R.success(projects);
}
/**
* 项目检测
@ -115,7 +98,7 @@ public class ProjectController {
@OperateLogAnnotation(description = "重新检测")
public R<String> reDetect(@RequestBody @Valid ReDetectVO reDetectVO) {
String taskId = projectService.reDetect(reDetectVO);
Map<String,Object> result = new HashMap<>(2);
Map<String, Object> result = new HashMap<>(2);
result.put("taskId", taskId);
return R.success(result);
}
@ -129,13 +112,12 @@ public class ProjectController {
*/
@PostMapping("/projects/detectResultCompare")
@OperateLogAnnotation(description = "检测结果对比")
public R detectResultCompare(@Valid DetectResultCompareVO detectResultCompareVO) {
public R detectResultCompare(@RequestBody @Valid DetectResultCompareVO detectResultCompareVO) {
CompareResultDTO<?> compareResultDTO = projectService.detectResultCompare(detectResultCompareVO);
return R.success(compareResultDTO);
}
/**
* 检测结果对比详情
*
@ -143,11 +125,106 @@ public class ProjectController {
* @return
*/
@PostMapping("/projects/detectResultCompareDetail")
public R detectResultCompareDetail(@Valid DetectResultCompareDetailVO detectResultCompareDetailVO) {
CompareResultDTO<?> compareResultDTO = projectService.detectResultCompareDetail(detectResultCompareDetailVO);
return R.success(compareResultDTO);
public R detectResultCompareDetail(@RequestBody @Valid DetectResultCompareDetailVO detectResultCompareDetailVO) {
List<DetectResultCompareDetailDTO> detectResultCompareDetailDTOS = projectService.detectResultCompareDetail(detectResultCompareDetailVO);
return R.success(detectResultCompareDetailDTOS);
}
/**
* 项目概览
*
* @param projectId
* @return
*/
@GetMapping("/projects/{projectId}/overview")
public R<ProjectOverviewDTO> projectOverview(@PathVariable Long projectId) {
ProjectOverviewDTO projectOverview = projectService.getProjectOverview(projectId);
return R.success(projectOverview);
}
/**
* 缺陷
*
* @param projectId
* @return
*/
@GetMapping("/projects/{projectId}/bug")
public R<ProjectBugDTO> projectBug(@PathVariable Long projectId) {
ProjectBugDTO projectBugDTO = projectService.projectBug(projectId);
return R.success(projectBugDTO);
}
/**
* 缺陷详情
*
* @param projectId
* @return
*/
@GetMapping("/projects/{projectId}/bug/detail")
public R<ProjectBugDetailDTO> projectBugDetail(@PathVariable Long projectId) {
ProjectBugDetailDTO projectBugDetailDTO = projectService.projectBugDetail(projectId);
return R.success(projectBugDetailDTO);
}
/**
* 缺陷中心
*
* @param projectId
* @return
*/
@GetMapping("/projects/{projectId}/bug/center")
public R<PageInfo> projectBugCenter(@PathVariable Long projectId, @Valid ProjectBugCenterVO projectBugCenterVO) {
PageInfo<ProjectBugCenterDTO> projectBugCenterDTOPageInfo = projectService.projectBugCenter(projectId, projectBugCenterVO);
return R.success(projectBugCenterDTOPageInfo);
}
/**
* 缺陷列表导出
*
* @param projectId
*/
@GetMapping("/projects/{projectId}/bug/export")
public void projectBugExport(@PathVariable Long projectId, @Valid ProjectBugCenterVO projectBugCenterVO, HttpServletResponse response) throws Exception {
List<ProjectBugCenterDTO> projectBugCenterDTOList = projectService.projectBugList(projectId, projectBugCenterVO);
Projects projects = projectService.getProjectById(projectId);
response.setCharacterEncoding("utf-8");
String fileName = new String(projects.getProjectName().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
response.setHeader("Content-disposition", "attachment;filename=" + fileName + "_bug.xlsx");
response.setContentType("application/vnd.ms-excel");
EasyExcel.write(response.getOutputStream(), ProjectBugCenterDTO.class).sheet().doWrite(projectBugCenterDTOList);
}
/**
* 缺陷中心> 代码详情
*
* @param projectId
* @return
*/
@GetMapping("/projects/{projectId}/bug/center/codeDetail")
public R<ProjectBugCenterCodeDetailDTO> projectBugCenterCodeDetail(@PathVariable Long projectId, @Valid ProjectBugCenterCodeDetailVO centerCodeDetailVO) {
ProjectBugCenterCodeDetailDTO projectBugCenterCodeDetailDTO = projectService.projectBugCenterCodeDetail(projectId, centerCodeDetailVO);
return R.success(projectBugCenterCodeDetailDTO);
}
/**
* 缺陷中心> 代码详情
* V2版本
*
* @param projectId
* @return
*/
@GetMapping("/projects/v2/{projectId}/bug/center/codeDetail")
public R<ProjectBugCenterCodeDetailV2DTO> projectBugCenterCodeDetailV2(@PathVariable Long projectId, @RequestParam("ruleId") Integer id) {
ProjectBugCenterCodeDetailV2DTO codeDetailV2DTO = projectService.projectBugCenterCodeDetailV2(projectId, id);
return R.success(codeDetailV2DTO);
}
}

View File

@ -0,0 +1,205 @@
package net.educoder.quality.controller;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ZipUtil;
import com.github.pagehelper.PageInfo;
import net.educoder.quality.common.util.R;
import net.educoder.quality.common.util.WordUtil;
import net.educoder.quality.dto.ReportDetailDTO;
import net.educoder.quality.entity.mysql.Projects;
import net.educoder.quality.entity.mysql.ReportCenter;
import net.educoder.quality.service.ProjectService;
import net.educoder.quality.service.ReportCenterService;
import net.educoder.quality.service.postgres.PgProjectsService;
import net.educoder.quality.vo.ExportReportVO;
import net.educoder.quality.vo.ReportListVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.util.*;
/**
* @Author: youys
* @Date: 2022/9/23
* @Description: 报告中心控制器
*/
@RestController
public class ReportCenterController {
@Autowired
private ReportCenterService reportCenterService;
@Autowired
private ProjectService projectService;
@Autowired
private PgProjectsService pgProjectsService;
@Value("${download.tempDir}")
private String downloadTempDir;
/**
* 导出报告
*
* @param exportReportVO
* @return
*/
@PostMapping("/report/export")
public R exportReport(@RequestBody @Valid ExportReportVO exportReportVO) {
Long id = reportCenterService.exportReport(exportReportVO);
Map<String, Object> result = new HashMap<>(2);
result.put("id", id);
return R.success(result);
}
/**
* 报告中心列表
*
* @param reportListVO
* @return
*/
@GetMapping("/report/list")
public R<PageInfo<ReportCenter>> reportList(@Valid ReportListVO reportListVO) {
PageInfo<ReportCenter> reportCenterPageInfo = reportCenterService.reportList(reportListVO);
return R.success(reportCenterPageInfo);
}
/**
* 报告下载
*
* @param reportId
* @return
*/
@GetMapping("/report/download/{reportId}")
public void downloadReport(@PathVariable Long reportId, HttpServletResponse response) throws IOException {
ReportCenter reportCenter = reportCenterService.reportCenterDetail(reportId);
Projects projects = projectService.getProjectById(reportCenter.getProjectId());
// 设置文件下载参数
response.setCharacterEncoding("utf-8");
String fileName = new String(reportCenter.getReportName().getBytes("utf-8"), "ISO8859-1");
// 获取模板填充数据
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("template/report-center-template.docx");
ServletOutputStream outputStream = response.getOutputStream();
ReportDetailDTO reportDetail = pgProjectsService.getReportDetail(projects.getProjectName());
Map<String, String> param = new HashMap<>(13);
param.put("projectName", projects.getProjectName());
param.put("createTime", DateUtil.formatDateTime(new Date()));
param.put("issueCount",String.valueOf(reportDetail.getBugCount().getTotal()));
param.put("seriousIssueCount",String.valueOf(reportDetail.getBugCount().getCritical()));
param.put("highRiskIssueCount",String.valueOf(reportDetail.getBugCount().getHigh()));
param.put("midRiskIssueCount",String.valueOf(reportDetail.getBugCount().getMiddle()));
param.put("lowRiskIssueCount",String.valueOf(reportDetail.getBugCount().getLow()));
param.put("componentCount",String.valueOf(reportDetail.getComponents()));
param.put("componentBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getTotal()));
param.put("seriousBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getCritical()));
param.put("highRiskBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getHigh()));
param.put("midRiskBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getMiddle()));
param.put("lowRiskBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getLow()));
XWPFDocument doc = new XWPFDocument(resourceAsStream);
WordUtil.changeText(doc, param);
pgProjectsService.fillReportTable(doc,reportDetail);
String format = reportCenter.getFormat();
if ("pdf".equals(format)){
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".pdf");
response.setContentType("application/pdf");
WordUtil.docToPdf(doc,outputStream);
}else {
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".docx");
response.setContentType("application/octet-stream");
doc.write(outputStream);
}
}
/**
* 报告下载
*
* @param reportIds
* @return
*/
@GetMapping("/report/batchDownload")
public void batchDownloadReport(@RequestParam("reportIds") List<Long> reportIds, HttpServletResponse response) throws IOException {
// 设置文件下载参数
response.setCharacterEncoding("utf-8");
String fileName = new String("报告中心".getBytes("utf-8"), "ISO8859-1");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".zip");
response.setContentType("application/octet-stream");
ServletOutputStream outputStream = response.getOutputStream();
String[] filePaths = new String[reportIds.size()];
InputStream[] ins = new InputStream[reportIds.size()];
int i = 0;
for (Long reportId : reportIds) {
ReportCenter reportCenter = reportCenterService.reportCenterDetail(reportId);
Projects projects = projectService.getProjectById(reportCenter.getProjectId());
// 获取模板填充数据
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("template/report-center-template.docx");
ReportDetailDTO reportDetail = pgProjectsService.getReportDetail(projects.getProjectName());
Map<String, String> param = new HashMap<>(13);
param.put("projectName", projects.getProjectName());
param.put("createTime", DateUtil.formatDateTime(new Date()));
param.put("issueCount",String.valueOf(reportDetail.getBugCount().getTotal()));
param.put("seriousIssueCount",String.valueOf(reportDetail.getBugCount().getCritical()));
param.put("highRiskIssueCount",String.valueOf(reportDetail.getBugCount().getHigh()));
param.put("midRiskIssueCount",String.valueOf(reportDetail.getBugCount().getMiddle()));
param.put("lowRiskIssueCount",String.valueOf(reportDetail.getBugCount().getLow()));
param.put("componentCount",String.valueOf(reportDetail.getComponents()));
param.put("componentBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getTotal()));
param.put("seriousBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getCritical()));
param.put("highRiskBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getHigh()));
param.put("midRiskBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getMiddle()));
param.put("lowRiskBugCount",String.valueOf(reportDetail.getVulnerabilityCount().getLow()));
XWPFDocument doc = new XWPFDocument(resourceAsStream);
WordUtil.changeText(doc, param);
pgProjectsService.fillReportTable(doc,reportDetail);
String filePath = filePath(reportCenter.getReportName());
doc.write(new FileOutputStream(new File(filePath)));
doc.close();
ins[i] = new FileInputStream(new File(filePath));
filePaths[i] = filePath;
i++;
}
ZipUtil.zip(outputStream, filePaths, ins);
}
private String filePath(String reportName){
String path = StringUtils.join(downloadTempDir, "/", IdUtil.fastSimpleUUID(), "/");
String name = reportName + ".docx";
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
return path + name;
}
}

View File

@ -0,0 +1,63 @@
package net.educoder.quality.controller;
import com.github.pagehelper.PageInfo;
import net.educoder.quality.common.util.R;
import net.educoder.quality.dto.ProjectVulnerabilityDTO;
import net.educoder.quality.dto.ProjectVulnerabilityDetailDTO;
import net.educoder.quality.service.VulnerabilityService;
import net.educoder.quality.vo.PageVO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
/**
* 克隆检测控制器
*/
@RestController
public class VulnerabilityController {
@Resource
private VulnerabilityService vulnerabilityService;
/**
* 漏洞统计信息
*
* @param projectId
* @return
*/
@GetMapping("/projects/{projectId}/vulnerability")
public R<ProjectVulnerabilityDTO> projectVulnerability(@PathVariable Long projectId) {
ProjectVulnerabilityDTO projectVulnerabilityDTO = vulnerabilityService.vulnerabilityStatistics(projectId);
return R.success(projectVulnerabilityDTO);
}
/**
* 漏洞列表
*
* @param projectId
* @return
*/
@GetMapping("/projects/{projectId}/vulnerability/list")
public R<PageInfo> projectVulnerabilityList(@PathVariable Long projectId, @Valid PageVO pageVO) {
PageInfo<ProjectVulnerabilityDetailDTO> vulnerabilityList = vulnerabilityService.vulnerabilityList(projectId, pageVO);
return R.success(vulnerabilityList);
}
/**
* 漏洞详情
*
* @param projectId
* @return
*/
@GetMapping("/projects/{projectId}/vulnerability/detail")
public R<ProjectVulnerabilityDetailDTO> projectVulnerabilityDetail(@PathVariable Long projectId, @RequestParam("uuid") String uuid) {
ProjectVulnerabilityDetailDTO detailDTO = vulnerabilityService.vulnerabilityDetail(projectId, uuid);
return R.success(detailDTO);
}
}

View File

@ -5,29 +5,9 @@ import lombok.Data;
/**
* @Author: youys
* @Date: 2022/9/19
* @Description:
* @Description: bug比较结果
*/
@Data
public class BugResultDTO {
private Long total;
/**
* 严重的 对应 critical
*/
private Long critical;
/**
* 高危 对应 blocker
*/
private Long high;
/**
* 对应 major
*/
private Long middle;
/**
* 对应 minor
*/
private Long low;
public class BugResultDTO extends CompareBaseResultDTO {
}

View File

@ -0,0 +1,63 @@
package net.educoder.quality.dto;
import lombok.Data;
@Data
public class CloneDetectionResultFileCodeLevelDTO {
private Long projectId;
/**
* 源文件路径
*/
private String sourceFilePath;
/**
* 源文件开始行
*/
private Integer sourceFileStartLine;
/**
* 源文件结束行
*/
private Integer sourceFileEndLine;
/**
* 源文件代码
*/
private String sourceFileCode;
/**
* 对比文件路径
*/
private String targetFilePath;
/**
* 对比文件开始行
*/
private Integer targetFileStartLine;
/**
* 对比文件结束行
*/
private Integer targetFileEndLine;
/**
* 对比文件代码
*/
private String targetFileCode;
/**
* 对比工程名称
*/
private String targetProjectName;
/**
* 对比工程路径
*/
private String targetProjectUrl;
/**
* 相似比
*/
private double commonSourcePercent;
/**
* 相似行数
*/
private double commonSourceLine;
/**
* 原创比
*/
private double originalSourcePercent;
}

View File

@ -0,0 +1,37 @@
package net.educoder.quality.dto;
import lombok.Data;
@Data
public class CloneDetectionResultProjectLevelDTO {
/**
* 克隆检测ID
*/
private Long cloneDetectionId;
/**
* 相似文件比
*/
private Integer similarityFilePercent;
/**
* 相似文件数
*/
private Integer similarityFile;
/**
* 源项目名
*/
private String sourceProjectName;
/**
* 对比项目名
*/
private String targetProjectName;
/**
* 对比项目地址
*/
private String targetProjectUrl;
}

View File

@ -0,0 +1,41 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CloneDetectionStatisticsDTO {
/**
* 溯源相似比-文件
*/
private double fileCodeSimilarityPercent;
/**
* 自主代码比-文件
*/
private double fileOriginalPercent;
/**
* 溯源相似比-代码行
*/
private double codeLineSimilarityPercent;
/**
* 自主代码比-代码行
*/
private double codeLineOriginalPercent;
/**
* 溯源相似比-容量
*/
private double capacitySimilarityPercent;
/**
* 自主代码比-容量
*/
private double capacityOriginalPercent;
}

View File

@ -0,0 +1,28 @@
package net.educoder.quality.dto;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class ClonePairDTO {
private String sourceFile;
private int sourceFileStartLine;
private int sourceFileEndLine;
private String targetFile;
private int targetFileStartLine;
private int targetFileEndLine;
private double similarity;
private int similarLines;
public ClonePairDTO(String sourceFile, int sourceFileStartLine, int sourceFileEndLine, String targetFile, int targetFileStartLine, int targetFileEndLine, double similarity) {
this.sourceFile = sourceFile;
this.sourceFileStartLine = sourceFileStartLine;
this.sourceFileEndLine = sourceFileEndLine;
this.targetFile = targetFile;
this.targetFileStartLine = targetFileStartLine;
this.targetFileEndLine = targetFileEndLine;
this.similarity = similarity;
this.similarLines = Math.max(Math.min(sourceFileEndLine - sourceFileStartLine, targetFileEndLine - targetFileStartLine), 0);
}
}

View File

@ -0,0 +1,33 @@
package net.educoder.quality.dto;
import lombok.Data;
/**
* @Author: youys
* @Date: 2022/9/26
* @Description:
*/
@Data
public class CompareBaseResultDTO {
private Long total = 0L;
/**
* 严重的 对应 critical
*/
private Long critical = 0L;
/**
* 高危 对应 blocker
*/
private Long high = 0L;
/**
* 对应 major
*/
private Long middle = 0L;
/**
* 对应 minor
*/
private Long low = 0L;
}

View File

@ -0,0 +1,53 @@
package net.educoder.quality.dto;
import lombok.Data;
import java.util.List;
/**
* @Author: youys
* @Date: 2022/12/27
* @Description: 组件-查看详情
*/
@Data
public class ComponentDetailDTO {
/**
* 组件名称
*/
private String componentName;
/**
* 许可证
*/
private String permit;
/**
* 主业
*/
private String homeUrl;
/**
* 发布日期
*/
private String publishDate;
/**
* 更新日期
*/
private String updateDate;
/**
* 描述
*/
private String description;
/**
* 关键词
*/
private String keysWord;
/**
* 使用版本
*/
private List<String> useVersion;
}

View File

@ -0,0 +1,50 @@
package net.educoder.quality.dto;
import com.alibaba.fastjson.JSONArray;
import lombok.Data;
/**
* @Author: youys
* @Date: 2022/10/13
* @Description: 组件列表
*/
@Data
public class ComponentListDTO {
private Long id;
/**
* 组件名称
*/
private String componentName;
/**
* 语言
*/
private String language;
/**
* 风险等级
*/
private String riskLevel;
/**
* 漏洞
*/
private String vulnerability;
/**
* 漏洞详情
*/
private JSONArray vulnerabilities;
/**
* 依赖方式
*/
private String dependWay;
/**
* 依赖路径
*/
private String dependPath;
/**
* 依赖数量
*/
private Integer dependNum;
}

View File

@ -0,0 +1,20 @@
package net.educoder.quality.dto;
import lombok.Data;
import net.educoder.quality.entity.mysql.ComponentParseRecordDetail;
/**
* @Author: youys
* @Date: 2022/12/27
* @Description:
*/
@Data
public class ComponentParseRecordDetailDTO extends ComponentParseRecordDetail {
/**
* 依赖数量
*/
private Integer dependNum;
}

View File

@ -0,0 +1,14 @@
package net.educoder.quality.dto;
import lombok.Data;
/**
* @Author: youys
* @Date: 2022/9/26
* @Description: 对比组件结果
*/
@Data
public class ComponentResultDTO extends CompareBaseResultDTO {
}

View File

@ -0,0 +1,55 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: youys
* @Date: 2022/10/13
* @Description:
*/
@Data
public class ComponentStatisticsDTO {
private ComponentStatistics componentStatistics;
private ComponentRisk componentRisk;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class ComponentStatistics {
/**
* 组件总数
*/
private Long componentTotal = 0L;
/**
* 间接依赖
*/
private Long indirectDependencies = 0L;
/**
* 直接依赖
*/
private Long directlyDependencies = 0L;
}
@Data
public static class ComponentRisk extends CompareBaseResultDTO {
/**
* 风险总计
*/
private Long riskTotal = 0L;
/**
* 未知
*/
private Long unKnow = 0L;
}
}

View File

@ -0,0 +1,16 @@
package net.educoder.quality.dto;
import lombok.Data;
/**
* @Author: youys
* @Date: 2022/12/27
* @Description:
*/
@Data
public class DependComponentDTO {
private String componentName;
private String version;
private String dependPath;
}

View File

@ -0,0 +1,20 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @Author: youys
* @Date: 2022/9/23
* @Description:
*/
@Data
@AllArgsConstructor
public class DetectConfigDTO {
private LocalDateTime jobTime;
private Long templateId;
private Long id;
}

View File

@ -0,0 +1,15 @@
package net.educoder.quality.dto;
import lombok.Data;
/**
* @Author: youys
* @Date: 2022/10/18
* @Description: 比对详情
*/
@Data
public class DetectResultCompareDetailDTO extends CompareResultDTO<Boolean> {
private String name;
}

View File

@ -0,0 +1,20 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: youys
* @Date: 2022/9/27
* @Description:
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FileSourceDTO {
private Integer rowNumber;
private String code;
}

View File

@ -0,0 +1,17 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* @Author: youys
* @Date: 2022/9/21
* @Description: 键值对
*/
@Data
@AllArgsConstructor
public class KeyValuePair {
private String name;
private String value;
}

View File

@ -0,0 +1,45 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 许可证兼容分析
* @author jshixiong
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LicenceCompatibleDTO {
/**
* 许可证1 ID
*/
private Long licenceId1;
/**
* 许可证1 名称
*/
private String licenceName1;
/**
* 许可证2 ID
*/
private Long licenceId2;
/**
* 许可证2 名称
*/
private String licenceName2;
/**
* 兼容结果描述
*/
private String result;
/**
* 兼容分析
*/
private String analysis;
}

View File

@ -0,0 +1,21 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 许可证版权信息
* @author jshixiong
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LicenceCopyrightDTO {
private String info;
private Long fileCount;
private String distortInfo;
}

View File

@ -0,0 +1,29 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 许可证篡改分析
* @author jshixiong
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LicenceDistortDTO {
private Long licenceId;
private String licenceName;
private String referencePath;
private String sourcePath;
private String riskLevel;
private String beforeDistort;
private String afterDistort;
}

View File

@ -0,0 +1,25 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
* @author jshixiong
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LicenceFileDTO {
private Long id;
private String name;
private String type;
private String version;
private String url;
}

View File

@ -0,0 +1,39 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 许可证分页列表DTO
* @author jshixiong
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LicenceListDTO {
/**
* 许可证ID
*/
private Long licenceId;
/**
* 许可证名称
*/
private String licenceName;
/**
* 风险等级
*/
private String riskLevel;
/**
* 文件数
*/
private Long fileCount;
/**
* 组件数
*/
private Long moduleCount;
}

View File

@ -0,0 +1,25 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 许可证总计
* @author jshixiong
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LicenceOverviewDTO {
/**
* 许可证数
*/
private Long licenceCount;
/**
* 版权数
*/
private Long copyrightCount;
}

View File

@ -0,0 +1,29 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 许可证兼容风险总计
* @author jshixiong
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LicenceRiskDTO {
/**
* 兼容风险数
*/
private Long riskCount;
/**
* 条件兼容数
*/
private Long compatible;
/**
* 条件不兼容数
*/
private Long notCompatible;
}

View File

@ -0,0 +1,12 @@
package net.educoder.quality.dto;
import lombok.Data;
/**
* @Author: youys
* @Date: 2022/9/26
* @Description:
*/
@Data
public class LicenseResultDTO extends CompareBaseResultDTO {
}

View File

@ -0,0 +1,24 @@
package net.educoder.quality.dto;
import lombok.Data;
import java.util.List;
/**
* @Author: youys
* @Date: 2022/10/17
* @Description: 缺陷中心返回结果
*/
@Data
public class ProjectBugCenterCodeDetailDTO {
/**
* 代码
*/
private List<FileSourceDTO> codes;
/**
* 示例代码
*/
private String example;
}

View File

@ -0,0 +1,44 @@
package net.educoder.quality.dto;
import lombok.Data;
import java.util.List;
/**
* @Author: youys
* @Date: 2023/3/9
* @Description: 缺陷中心>查看详情 v2版本
*/
@Data
public class ProjectBugCenterCodeDetailV2DTO {
private String filePath;
/**
* 代码行号
*/
private Integer line;
/**
* 缺陷名称
*/
private String bugName;
/**
* 缺陷描述
*/
private String description;
/**
* 正确代码示例
*/
private String example;
/**
* 错误代码示例
*/
private String errorExample;
/**
* 代码所属错误分类
*/
private String parentBugCatalog;
/**
* 代码
*/
private List<FileSourceDTO> codes;
}

View File

@ -0,0 +1,56 @@
package net.educoder.quality.dto;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.util.Date;
/**
* @Author: youys
* @Date: 2022/9/27
* @Description:
*/
@Data
@ExcelIgnoreUnannotated
public class ProjectBugCenterDTO {
/**
* 缺陷名称
*/
@ExcelProperty("缺陷名称")
private String bugName;
/**
* 缺陷描述
*/
@ExcelProperty("缺陷描述")
private String bugDescription;
/**
* 文件路径
*/
@ExcelProperty("文件路径")
private String filePath;
/**
* 行号
*/
@ExcelProperty("行号")
private String rowNumber;
/**
* 缺陷级别
*/
@ExcelProperty("缺陷级别")
private String bugLevel;
/**
* 检测时间
*/
@ExcelProperty("检测时间")
private Date detectTime;
/**
* 找文件唯一标识
*/
private String uuid;
private Integer ruleId;
}

View File

@ -0,0 +1,35 @@
package net.educoder.quality.dto;
import lombok.Data;
import java.util.List;
/**
* @Author: youys
* @Date: 2022/9/21
* @Description: 项目缺陷展示数据
*/
@Data
public class ProjectBugDTO {
/**
* 代码行数
*/
private Integer codeNumber;
/**
* 👈🏻展示数据
*/
private List<KeyValuePair> left;
/**
* 缺陷数
*/
private Integer bugNumber;
/**
* 👉🏻展示数据
*/
private List<KeyValuePair> right;
}

View File

@ -0,0 +1,100 @@
package net.educoder.quality.dto;
import lombok.Data;
import java.util.Date;
/**
* @Author: youys
* @Date: 2022/9/26
* @Description: 缺陷检测详情
*/
@Data
public class ProjectBugDetailDTO {
/**
* 检测基本信息
*/
private DetectInfo detectInfo;
/**
* 检测结果
*/
private DetectResult detectResult;
@Data
public static class DetectInfo {
/**
* 语言
*/
private String language;
/**
* 创建人
*/
private String creator;
/**
* git仓库地址
*/
private String gitUrl;
/**
* 检测模板
*/
private Long templateId;
/**
* 开始检测时间
*/
private Date startTime;
/**
* 结束检测时间
*/
private Date endTime;
/**
* 状态
*/
private Integer status;
/**
* 检测时长
*/
private Integer detectTime;
}
@Data
public static class DetectResult {
private Integer fileNumber;
private Integer codeNumber;
private Long bugTotalNumber;
/**
* 严重的 对应 critical
*/
private Long critical;
/**
* 高危 对应 blocker
*/
private Long high;
/**
* 对应 major
*/
private Long middle;
/**
* 对应 minor
*/
private Long low;
/**
* 未知
*/
private Long unKnow = 0L;
}
}

View File

@ -0,0 +1,22 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* @Author: youys
* @Date: 2022/9/20
* @Description:
*/
@Data
@AllArgsConstructor
public class ProjectMetricsDTO {
private Integer bugNumber;
private Integer vulnerabilityNumber;
/**
* 代码行数
*/
private Integer codeNumber;
}

View File

@ -0,0 +1,95 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: youys
* @Date: 2022/9/20
* @Description: 项目概览展示数据
*/
@Data
public class ProjectOverviewDTO {
/**
* 漏洞
*/
private Metres vulnerability;
/**
* 缺陷
*/
private Metres bug;
/**
* 组件
*/
private Metres component;
/**
* 许可证
*/
private Metres license;
/**
* 检测内容
*/
private DetectContent detectContent;
/**
* 缺陷 & 漏洞
*/
private BugResultDTO bugDetail;
private VulnerabilityResultDTO vulnerabilityDetail;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Metres {
/**
* 原始数量
*/
private Integer originNumber = 0;
/**
* 新增数量
*/
private Integer newNumber = 0;
}
/**
* 检测内容
*/
@Data
public static class DetectContent {
/**
* 代码行数
*/
private Integer codeNumber = 0;
/**
* 文件数
*/
private Integer fileNumber = 0;
/**
* 文件大小
*/
private String size = "0k";
}
/**
* 溯源信息
*/
@Data
public static class RootsInfo {
}
/**
* 许可证
*/
@Data
public static class LicenseInfo {
}
}

View File

@ -0,0 +1,40 @@
package net.educoder.quality.dto;
import lombok.Data;
/**
* @Author: youys
* @Date: 2022/9/28
* @Description: 项目漏洞统计信息
*/
@Data
public class ProjectVulnerabilityDTO extends CompareBaseResultDTO {
/**
* 未知
*/
private Long unKnow = 0L;
private Long newUnKnow = 0L;
/**
* 严重的 对应 critical
*/
private Long newCritical = 0L;
/**
* 高危 对应 blocker
*/
private Long newHigh = 0L;
/**
* 对应 major
*/
private Long newMiddle = 0L;
/**
* 对应 minor
*/
private Long newLow = 0L;
}

View File

@ -0,0 +1,55 @@
package net.educoder.quality.dto;
import lombok.Data;
import java.util.Date;
/**
* @Author: youys
* @Date: 2022/9/28
* @Description: 项目漏洞详情
*/
@Data
public class ProjectVulnerabilityDetailDTO {
private String uuid;
/**
* 漏洞编号
*/
private String vulnerabilityNumber;
/**
* 漏洞名称
*/
private String vulnerabilityName;
/**
* 风险等级
*/
private String riskLevel;
/**
* 发布日期
*/
private String publishDate;
/**
* 利用难度困难
*/
private String difficulty;
/**
* 攻击类型远程
*/
private String attackType;
/**
* 漏洞描述
*/
private String description;
/**
* 修复建议
*/
private String repairSuggestions;
}

View File

@ -0,0 +1,43 @@
package net.educoder.quality.dto;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/**
* @Author: youys
* @Date: 2022/9/28
* @Description: 项目漏洞列表
*/
@Data
public class ProjectVulnerabilityListDTO {
/**
* 漏洞编号
*/
@ExcelProperty("漏洞编号")
private String vulnerabilityNumber;
/**
* 漏洞名称
*/
@ExcelProperty("漏洞名称")
private String vulnerabilityName;
/**
* 风险等级
*/
@ExcelProperty("风险等级")
private String riskLevel;
/**
* 修复方案
*/
@ExcelProperty("修复方案")
private Boolean fixPlan;
/**
* uuid
*/
@ExcelIgnore
private String uuid;
}

View File

@ -15,4 +15,9 @@ public class ProjectsDTO extends Projects {
* 检测次数
*/
private Integer detectNum;
/**
*
*/
private DetectConfigDTO detectConfig;
}

View File

@ -0,0 +1,29 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import net.educoder.quality.entity.postgres.PgIssues;
import java.util.List;
/**
* @Date: 2023/01/19
* @author jshixiong
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ReportDetailDTO {
private CompareBaseResultDTO vulnerabilityCount;
private CompareBaseResultDTO bugCount;
private Integer components;
private List<PgIssues> bugIssues;
private List<ComponentParseRecordDetailDTO> parseRecordDetails;
}

View File

@ -0,0 +1,14 @@
package net.educoder.quality.dto;
import lombok.Data;
@Data
public class SastBugDTO {
private Long bugId;
private String bugType;
private int line;
private String filePath;
private String message;
private String methodName;
private String variable;
}

View File

@ -4,12 +4,13 @@ import lombok.Data;
import net.educoder.quality.entity.mysql.ProjectDetectionTaskInfo;
import net.educoder.quality.entity.mysql.ProjectFileUpload;
import net.educoder.quality.entity.mysql.ProjectSecretKey;
import net.educoder.quality.entity.mysql.Projects;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
* @Author: youys
* @Date: 2022/1/18
* @Description:
* @Description: sonar扫描参数
*/
@Data
public class SonarScannerParam {
@ -31,19 +32,33 @@ public class SonarScannerParam {
private String taskId;
private String source;
private String language;
/**
* 工作目录
*/
private String workspace;
private ProjectFileUpload fileUpload;
private ProjectSecretKey projectSecretKey;
private ProjectDetectionTaskInfo taskInfo;
private Projects projects;
/**
* 查询结果线程池
*/
private ThreadPoolTaskExecutor sonarQueryResultThreadPool;
/**
* git用户名
*/
private String gitUsername;
/**
* git密码
*/
private String gitPassword;
/**
* .net代码sonar扫描服务
*/
private String donetSonarServer;
}

View File

@ -1,6 +1,8 @@
package net.educoder.quality.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: youys
@ -8,26 +10,5 @@ import lombok.Data;
* @Description:
*/
@Data
public class VulnerabilityResultDTO {
private Long total;
/**
* 严重的 对应 critical
*/
private Long critical;
/**
* 高危 对应 blocker
*/
private Long high;
/**
* 对应 major
*/
private Long middle;
/**
* 对应 minor
*/
private Long low;
public class VulnerabilityResultDTO extends CompareBaseResultDTO{
}

View File

@ -0,0 +1,24 @@
package net.educoder.quality.entity.gitea;
import lombok.Data;
import java.util.Date;
/**
* @Author: youys
* @Date: 2023/1/17
* @Description: 许可证
*/
@Data
public class PgCodeLicense {
private Long id;
private String name;
private String riskLevel;
private String version;
private Date createTime;
private String content;
private String description;
private String publicUrl;
}

View File

@ -0,0 +1,44 @@
package net.educoder.quality.entity.mysql;
import lombok.Data;
import net.educoder.quality.common.util.AbstractDO;
import java.util.Date;
import javax.persistence.*;
@Data
@Table(name = "clone_detection")
public class CloneDetection extends AbstractDO {
/**
* 源工程ID
*/
@Column(name = "project_id")
private Long projectId;
/**
* 目标工程名
*/
@Column(name = "target_project_name")
private String targetProjectName;
/**
* 目标工程URL
*/
@Column(name = "target_project_url")
private String targetProjectUrl;
/**
* 目标工程用户名
*/
@Column(name = "target_project_username")
private String targetProjectUsername;
/**
* 目标工程密码
*/
@Column(name = "target_project_password")
private String targetProjectPassword;
}

View File

@ -0,0 +1,98 @@
package net.educoder.quality.entity.mysql;
import lombok.Data;
import net.educoder.quality.common.util.AbstractDO;
import javax.persistence.Column;
import javax.persistence.Table;
@Data
@Table(name = "clone_detection_result_file_code_level")
public class CloneDetectionResultFileCodeLevel extends AbstractDO {
/**
* 源工程ID
*/
@Column(name = "project_id")
private Long projectId;
/**
* 源文件路径
*/
@Column(name = "source_file_path")
private String sourceFilePath;
/**
* 源文件开始行
*/
@Column(name = "source_file_start_line")
private Integer sourceFileStartLine;
/**
* 源文件结束行
*/
@Column(name = "source_file_end_line")
private Integer sourceFileEndLine;
/**
* 目标文件路径
*/
@Column(name = "target_file_path")
private String targetFilePath;
/**
* 目标文件开始行
*/
@Column(name = "target_file_start_line")
private Integer targetFileStartLine;
/**
* 目标文件结束行
*/
@Column(name = "target_file_end_line")
private Integer targetFileEndLine;
/**
* 相似比
*/
@Column(name = "common_source_percent")
private Double commonSourcePercent;
/**
* 相似行数
*/
@Column(name = "common_source_line")
private Integer commonSourceLine;
/**
* 克隆检测ID
*/
@Column(name = "clone_detection_id")
private Long cloneDetectionId;
/**
* 目标项目名称
*/
@Column(name = "target_project_name")
private String targetProjectName;
/**
* 目标项目URL
*/
@Column(name = "target_project_url")
private String targetProjectUrl;
/**
* 源文件代码
*/
@Column(name = "source_file_code")
private String sourceFileCode;
/**
* 目标文件代码
*/
@Column(name = "target_file_code")
private String targetFileCode;
}

View File

@ -0,0 +1,91 @@
package net.educoder.quality.entity.mysql;
import lombok.Data;
import net.educoder.quality.common.util.AbstractDO;
import javax.persistence.Column;
import javax.persistence.Table;
@Data
@Table(name = "clone_detection_result_project_level")
public class CloneDetectionResultProjectLevel extends AbstractDO {
/**
* 克隆检测ID
*/
@Column(name = "clone_detection_id")
private Long cloneDetectionId;
/**
* 相似文件比
*/
@Column(name = "similarity_file_percent")
private Double similarityFilePercent;
/**
* 相似文件数
*/
@Column(name = "similarity_file")
private Integer similarityFile;
/**
* 总文件数
*/
@Column(name = "total_file")
private Long totalFile;
/**
* 相似行数
*/
@Column(name = "similarity_line")
private Long similarityLine;
/**
* 相似行数比
*/
@Column(name = "similarity_line_percent")
private Double similarityLinePercent;
/**
* 总行数
*/
@Column(name = "total_line")
private Long totalLine;
/**
* 相似容量
*/
@Column(name = "similarity_capacity")
private Long similarityCapacity;
/**
* 相似容量比
*/
@Column(name = "similarity_capacity_percent")
private Double similarityCapacityPercent;
/**
* 总容量
*/
@Column(name = "total_capacity")
private Long totalCapacity;
/**
* 源工程ID
*/
@Column(name = "project_id")
private Long projectId;
/**
* 目标项目名称
*/
@Column(name = "target_project_name")
private String targetProjectName;
/**
* 目标项目URL
*/
@Column(name = "target_project_url")
private String targetProjectUrl;
}

View File

@ -0,0 +1,23 @@
package net.educoder.quality.entity.mysql;
import lombok.Data;
import java.util.Date;
/**
* @Author: youys
* @Date: 2023/1/17
* @Description: 组件库
*/
@Data
public class ComponentLibrary {
private Long id;
private String language;
private String componentName;
private String shortName;
private String license;
private Date createTime;
private String homeUrl;
}

View File

@ -0,0 +1,14 @@
package net.educoder.quality.entity.mysql;
import lombok.Data;
import net.educoder.quality.common.util.AbstractDO;
@Data
public class ComponentParseRecord extends AbstractDO {
private Long projectId;
private String result;
}

View File

@ -0,0 +1,58 @@
package net.educoder.quality.entity.mysql;
import lombok.Data;
import net.educoder.quality.common.util.AbstractDO;
@Data
public class ComponentParseRecordDetail extends AbstractDO {
private Long componentId;
/**
* 组件名称
*/
private String componentName;
/**
* 语言
*/
private String language;
/**
* 风险等级
*/
private String riskLevel;
/**
* 漏洞
*/
private String vulnerability;
/**
* 版本
*/
private String version;
/**
* 依赖方式直接 or 间接
*/
private String dependWay;
/**
* 依赖路径
*/
private String dependPath;
/**
* 父组件
*/
private String parentUuid;
/**
* 唯一标识
*/
private String uuid;
private String vulnerabilities;
}

View File

@ -0,0 +1,39 @@
package net.educoder.quality.entity.mysql;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import net.educoder.quality.common.util.AbstractDO;
import javax.persistence.Column;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
/**
* <p>
* 项目检测配置
* </p>
*
* @author jshixiong
* @since 2022-09-20
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Table(name = "detection_config")
public class DetectionConfig extends AbstractDO {
@NotNull(message = "执行时间不能为空")
@Column(name = "job_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private LocalDateTime jobTime;
@NotNull(message = "项目id不能为空")
@Column(name = "project_id")
private Long projectId;
@NotNull(message = "模板id不能为空")
@Column(name = "template_id")
private Long templateId;
}

View File

@ -22,6 +22,11 @@ public class DetectionTemplate extends AbstractDO {
private String securityDetection;
/**
* 依赖函数库
*/
private String dependFunction;
/**
* 仓库所属用户
*/

View File

@ -0,0 +1,91 @@
package net.educoder.quality.entity.mysql;
import lombok.Data;
import net.educoder.quality.common.util.AbstractDO;
import javax.persistence.Table;
import java.util.Objects;
@Data
@Table(name = "project_vulnerability_detail")
public class ProjectVulnerabilityDetail extends AbstractDO {
/**
* 漏洞编号
*/
private String vulnerabilityNumber;
/**
* 漏洞名称
*/
private String vulnerabilityName;
/**
* 风险等级
*/
private Integer riskLevel;
/**
* 发布日期
*/
private String publishDate;
/**
* 利用难度
*/
private Integer difficulty;
/**
* 攻击类型远程
*/
private String attackType;
/**
* 漏洞描述
*/
private String description;
/**
* 修复建议
*/
private String repairSuggestions;
/**
* 组件ID
*/
private Long componentId;
/**
* 工程ID
*/
private Long projectId;
@Override
public boolean equals(Object o) {
if (this == o){
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ProjectVulnerabilityDetail that = (ProjectVulnerabilityDetail) o;
return strEquals(vulnerabilityNumber,that.vulnerabilityNumber) && strEquals(vulnerabilityName,that.vulnerabilityName) && intEquals(riskLevel, that.riskLevel) && strEquals(publishDate, that.publishDate) && intEquals(difficulty, that.difficulty) && strEquals(attackType, that.attackType) && strEquals(description, that.description) && strEquals(repairSuggestions, that.repairSuggestions);
}
private boolean strEquals(String a,String b){
if (a==null || "".equals(a)){
return b == null || "".equals(b);
}
return a.equals(b);
}
private boolean intEquals(Integer a,Integer b){
if (a==null){
return b == null;
}
return a.equals(b);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), vulnerabilityNumber, vulnerabilityName, riskLevel, publishDate, difficulty, attackType, description, repairSuggestions);
}
}

View File

@ -13,23 +13,58 @@ import java.util.Date;
@Data
public class Projects extends AbstractDO {
/**
* 项目名称
*/
private String projectName;
private String source;
/**
* 分支
*/
private String branch;
/**
* git地址
*/
private String gitUrl;
/**
* 检测时长
*/
private Integer duration;
/**
* 目标文件数量
*/
private Integer targetFileNum;
/**
* 文件大小
*/
private String targetFileSize;
/**
* 检测状态 0:待检测 1检测中 2检测成功 -1 检测失败
*/
private Integer status;
/**
* 创建人
*/
private String creator;
/**
* 仓库
*/
private String repository;
/**
* 检测时间
*/
private Date testingTime;
/**
* 项目语言
*/
private String language;
}

View File

@ -0,0 +1,49 @@
package net.educoder.quality.entity.mysql;
import lombok.Data;
import net.educoder.quality.common.util.AbstractDO;
@Data
public class ReportCenter extends AbstractDO {
/**
* 报告类型
*/
private Integer reportType;
/**
* 报告名称
*/
private String reportName;
/**
* 所属项目
*/
private Long projectId;
/**
* 报告格式 word , pdf
*/
private String format;
/**
* 缺陷级别
*/
private String bugLevel;
/**
* 项目名称下载内容中的标题
*/
private String projectName;
/**
* 创建人
*/
private String creator;
private String repoOwner;
private String repository;
}

View File

@ -0,0 +1,208 @@
package net.educoder.quality.entity.mysql;
import java.util.Date;
import javax.persistence.*;
import lombok.Data;
import net.educoder.quality.common.util.AbstractDO;
@Data
@Table(name = "sast_analysis_detail")
public class SastAnalysisDetail extends AbstractDO {
/**
* bug分类
*/
@Column(name = "bug_catalog")
private String bugCatalog;
/**
* bug大分类
*/
@Column(name = "parent_bug_catalog")
private String parentBugCatalog;
/**
* bug类型编号
*/
@Column(name = "bug_no")
private String bugNo;
/**
* bug名称
*/
@Column(name = "bug_name")
private String bugName;
/**
* bug类型父级编号
*/
@Column(name = "parent_bug_no")
private String parentBugNo;
/**
* bug类型号
*/
@Column(name = "bug_type")
private String bugType;
/**
* bug类型名
*/
@Column(name = "bug_type_name")
private String bugTypeName;
/**
* bug级别
*/
@Column(name = "bug_level")
private String bugLevel;
/**
* 常见后果关键词
*/
@Column(name = "frequent_result_keyword")
private String frequentResultKeyword;
/**
* 创建时间
*/
@Column(name = "create_time")
private Date createTime;
/**
* 更新时间
*/
@Column(name = "update_time")
private Date updateTime;
/**
* 工程id
*/
@Column(name = "project_id")
private Long projectId;
/**
* 任务id
*/
@Column(name = "task_id")
private String taskId;
/**
* 简介
*/
private String synopsis;
/**
* 描述
*/
private String description;
/**
* 常见后果
*/
@Column(name = "frequent_result")
private String frequentResult;
/**
* 修复意见
*/
@Column(name = "repair_opinion")
private String repairOpinion;
/**
* 示例
*/
private String example;
/**
* 错误示例
*/
@Column(name = "error_example")
private String errorExample;
@Column(name = "method_name")
private String methodName;
private String variable;
private Integer line;
@Column(name = "file_path")
private String filePath;
public static final String ID = "id";
public static final String DB_ID = "id";
public static final String BUG_CATALOG = "bugCatalog";
public static final String DB_BUG_CATALOG = "bug_catalog";
public static final String BUG_NO = "bugNo";
public static final String DB_BUG_NO = "bug_no";
public static final String BUG_NAME = "bugName";
public static final String DB_BUG_NAME = "bug_name";
public static final String PARENT_BUG_NO = "parentBugNo";
public static final String DB_PARENT_BUG_NO = "parent_bug_no";
public static final String BUG_TYPE = "bugType";
public static final String DB_BUG_TYPE = "bug_type";
public static final String BUG_TYPE_NAME = "bugTypeName";
public static final String DB_BUG_TYPE_NAME = "bug_type_name";
public static final String BUG_LEVEL = "bugLevel";
public static final String DB_BUG_LEVEL = "bug_level";
public static final String FREQUENT_RESULT_KEYWORD = "frequentResultKeyword";
public static final String DB_FREQUENT_RESULT_KEYWORD = "frequent_result_keyword";
public static final String CREATE_TIME = "createTime";
public static final String DB_CREATE_TIME = "create_time";
public static final String UPDATE_TIME = "updateTime";
public static final String DB_UPDATE_TIME = "update_time";
public static final String PROJECT_ID = "projectId";
public static final String DB_PROJECT_ID = "project_id";
public static final String TASK_ID = "taskId";
public static final String DB_TASK_ID = "task_id";
public static final String SYNOPSIS = "synopsis";
public static final String DB_SYNOPSIS = "synopsis";
public static final String DESCRIPTION = "description";
public static final String DB_DESCRIPTION = "description";
public static final String FREQUENT_RESULT = "frequentResult";
public static final String DB_FREQUENT_RESULT = "frequent_result";
public static final String REPAIR_OPINION = "repairOpinion";
public static final String DB_REPAIR_OPINION = "repair_opinion";
public static final String EXAMPLE = "example";
public static final String DB_EXAMPLE = "example";
public static final String ERROR_EXAMPLE = "errorExample";
public static final String DB_ERROR_EXAMPLE = "error_example";
}

View File

@ -0,0 +1,62 @@
package net.educoder.quality.entity.postgres;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.InvalidProtocolBufferException;
import lombok.Data;
import net.educoder.quality.protobuf.DbFileSources;
import net.jpountz.lz4.LZ4BlockInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import static java.lang.String.format;
/**
* @Author: youys
* @Date: 2022/9/27
* @Description:
*/
@Data
public class PgFileSource {
private static final String SIZE_LIMIT_EXCEEDED_EXCEPTION_MESSAGE = "Protocol message was too large. May be malicious. " +
"Use CodedInputStream.setSizeLimit() to increase the size limit.";
private Long id;
private String projectUuid;
private String fileUuid;
private String lineHashes;
private String srcHash;
private byte[] binaryData = new byte[0];
private String dataHash;
public DbFileSources.Data decodeSourceData(byte[] binaryData) {
try {
return decodeRegularSourceData(binaryData);
} catch (IOException e) {
throw new IllegalStateException(
format("Fail to decompress and deserialize source data [id=%s,fileUuid=%s,projectUuid=%s]", id, fileUuid, projectUuid),
e);
}
}
private static DbFileSources.Data decodeRegularSourceData(byte[] binaryData) throws IOException {
try (LZ4BlockInputStream lz4Input = new LZ4BlockInputStream(new ByteArrayInputStream(binaryData))) {
return DbFileSources.Data.parseFrom(lz4Input);
} catch (InvalidProtocolBufferException e) {
if (SIZE_LIMIT_EXCEEDED_EXCEPTION_MESSAGE.equals(e.getMessage())) {
return decodeHugeSourceData(binaryData);
}
throw e;
}
}
private static DbFileSources.Data decodeHugeSourceData(byte[] binaryData) throws IOException {
try (LZ4BlockInputStream lz4Input = new LZ4BlockInputStream(new ByteArrayInputStream(binaryData))) {
CodedInputStream input = CodedInputStream.newInstance(lz4Input);
input.setSizeLimit(Integer.MAX_VALUE);
return DbFileSources.Data.parseFrom(input);
}
}
}

View File

@ -14,7 +14,28 @@ public class PgIssues {
private String kee;
private Integer ruleId;
private String severity;
private String message;
private String status;
private String projectUuid;
private Integer issueType;
private byte[] locations = new byte[0];
/**
* bug名称
*/
private String name;
/**
* bug描述
*/
private String description;
/**
* 文件路径
*/
private String path;
/**
* 对应file_sources表的file_uuid
* 对应issue表的component_uuid
*/
private String uuid;
}

View File

@ -0,0 +1,18 @@
package net.educoder.quality.entity.postgres;
import lombok.Data;
import java.math.BigDecimal;
/**
* @Author: youys
* @Date: 2022/9/22
* @Description:
*/
@Data
public class PgProjectMeasures {
private Long id;
private BigDecimal value;
private String textValue;
}

View File

@ -0,0 +1,16 @@
package net.educoder.quality.entity.postgres;
import lombok.Data;
/**
* @Author: youys
* @Date: 2022/10/17
* @Description:
*/
@Data
public class PgRule {
private Long id;
private String name;
private String description;
}

View File

@ -0,0 +1,216 @@
package net.educoder.quality.entity.sast;
import java.util.Date;
import javax.persistence.*;
import lombok.Data;
@Data
@Table(name = "biz_knowledge_bug")
public class BizKnowledgeBug {
/**
* 知识库BUG类型ID
*/
@Id
@Column(name = "OID_KNOWLEDGE_BUG_ID")
private String oidKnowledgeBugId;
/**
* 知识库目录ID
*/
@Column(name = "OID_KNOWLEDGE_CATALOG_ID")
private String oidKnowledgeCatalogId;
/**
* BUG类型编号
*/
@Column(name = "BUG_NO")
private String bugNo;
/**
* BUG名称
*/
@Column(name = "BUG_NAME")
private String bugName;
/**
* BUG类型父级编号
*/
@Column(name = "PARENT_BUG_NO")
private String parentBugNo;
/**
* BUG类型号
*/
@Column(name = "BUG_TYPE")
private String bugType;
/**
* BUG类型名
*/
@Column(name = "BUG_TYPE_NAME")
private String bugTypeName;
/**
* BUG级别
*/
@Column(name = "BUG_LEVEL")
private String bugLevel;
/**
* 常见后果关键词
*/
@Column(name = "FREQUENT_RESULT_KEYWORD")
private String frequentResultKeyword;
/**
* 删除FLG
*/
@Column(name = "DEL_FLG")
private String delFlg;
/**
* 作成者ID
*/
@Column(name = "INS_USER_ID")
private String insUserId;
/**
* 作成日
*/
@Column(name = "INS_DATE")
private Date insDate;
/**
* 更新者ID
*/
@Column(name = "UPD_USER_ID")
private String updUserId;
/**
* 更新日
*/
@Column(name = "UPD_DATE")
private Date updDate;
/**
* 简介
*/
@Column(name = "SYNOPSIS")
private String synopsis;
/**
* 描述
*/
@Column(name = "DESCRIPTION")
private String description;
/**
* 常见后果
*/
@Column(name = "FREQUENT_RESULT")
private String frequentResult;
/**
* 修复意见
*/
@Column(name = "REPAIR_OPINION")
private String repairOpinion;
/**
* 示例
*/
@Column(name = "EXAMPLE")
private String example;
/**
* 错误示例
*/
@Column(name = "ERROR_EXAMPLE")
private String errorExample;
@Transient
private String bugCatalog;
@Transient
private String parentBugCatalog;
public static final String OID_KNOWLEDGE_BUG_ID = "oidKnowledgeBugId";
public static final String DB_OID_KNOWLEDGE_BUG_ID = "OID_KNOWLEDGE_BUG_ID";
public static final String OID_KNOWLEDGE_CATALOG_ID = "oidKnowledgeCatalogId";
public static final String DB_OID_KNOWLEDGE_CATALOG_ID = "OID_KNOWLEDGE_CATALOG_ID";
public static final String BUG_NO = "bugNo";
public static final String DB_BUG_NO = "BUG_NO";
public static final String BUG_NAME = "bugName";
public static final String DB_BUG_NAME = "BUG_NAME";
public static final String PARENT_BUG_NO = "parentBugNo";
public static final String DB_PARENT_BUG_NO = "PARENT_BUG_NO";
public static final String BUG_TYPE = "bugType";
public static final String DB_BUG_TYPE = "BUG_TYPE";
public static final String BUG_TYPE_NAME = "bugTypeName";
public static final String DB_BUG_TYPE_NAME = "BUG_TYPE_NAME";
public static final String BUG_LEVEL = "bugLevel";
public static final String DB_BUG_LEVEL = "BUG_LEVEL";
public static final String FREQUENT_RESULT_KEYWORD = "frequentResultKeyword";
public static final String DB_FREQUENT_RESULT_KEYWORD = "FREQUENT_RESULT_KEYWORD";
public static final String DEL_FLG = "delFlg";
public static final String DB_DEL_FLG = "DEL_FLG";
public static final String INS_USER_ID = "insUserId";
public static final String DB_INS_USER_ID = "INS_USER_ID";
public static final String INS_DATE = "insDate";
public static final String DB_INS_DATE = "INS_DATE";
public static final String UPD_USER_ID = "updUserId";
public static final String DB_UPD_USER_ID = "UPD_USER_ID";
public static final String UPD_DATE = "updDate";
public static final String DB_UPD_DATE = "UPD_DATE";
public static final String SYNOPSIS = "synopsis";
public static final String DB_SYNOPSIS = "SYNOPSIS";
public static final String DESCRIPTION = "description";
public static final String DB_DESCRIPTION = "DESCRIPTION";
public static final String FREQUENT_RESULT = "frequentResult";
public static final String DB_FREQUENT_RESULT = "FREQUENT_RESULT";
public static final String REPAIR_OPINION = "repairOpinion";
public static final String DB_REPAIR_OPINION = "REPAIR_OPINION";
public static final String EXAMPLE = "example";
public static final String DB_EXAMPLE = "EXAMPLE";
public static final String ERROR_EXAMPLE = "errorExample";
public static final String DB_ERROR_EXAMPLE = "ERROR_EXAMPLE";
}

View File

@ -0,0 +1,32 @@
package net.educoder.quality.init;
import lombok.extern.slf4j.Slf4j;
import net.educoder.quality.service.DetectionConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* 启动未过时的定时检测配置
* @author jshixiong
*/
@Slf4j
@Component
public class DetectionConfigInit {
@Autowired
private DetectionConfigService detectionConfigService;
@PostConstruct
public void init() {
log.info("******检测配置-启动定时检测任务******");
try {
detectionConfigService.detectionConfigInit();
}catch (Exception e){
e.printStackTrace();
log.error("******检测配置-启动定时检测任务失败******");
}
log.info("******检测配置-启动定时检测任务完成******");
}
}

View File

@ -0,0 +1,19 @@
package net.educoder.quality.mapper.gitea;
import net.educoder.quality.entity.gitea.PgCodeLicense;
/**
* @Author: youys
* @Date: 2023/1/17
* @Description:
*/
public interface PgCodeLicenseMapper {
/**
* 根据许可证名称查询
* @param name
* @return
*/
PgCodeLicense selectByName(String name);
}

View File

@ -0,0 +1,7 @@
package net.educoder.quality.mapper.mysql;
import net.educoder.quality.entity.mysql.CloneDetection;
import tk.mybatis.mapper.common.Mapper;
public interface CloneDetectionMapper extends Mapper<CloneDetection> {
}

View File

@ -0,0 +1,7 @@
package net.educoder.quality.mapper.mysql;
import net.educoder.quality.entity.mysql.CloneDetectionResultFileCodeLevel;
import tk.mybatis.mapper.common.Mapper;
public interface CloneDetectionResultFileCodeLevelMapper extends Mapper<CloneDetectionResultFileCodeLevel> {
}

Some files were not shown because too many files have changed in this diff Show More