Compare commits

...

5 Commits

Author SHA1 Message Date
jshixiong 88f006b9c6 dto 2023-03-09 18:55:34 +08:00
jshixiong c79b1a6e80 fix 2023-03-09 14:16:59 +08:00
jshixiong 53b9949256 fix 2023-03-09 13:52:27 +08:00
jshixiong 552b08435e fix 2023-03-09 11:22:18 +08:00
jshixiong 458b415846 组件漏洞 2023-03-09 10:14:16 +08:00
8 changed files with 251 additions and 59 deletions

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: jshixiong
* @Date: 2023/3/9
* @Description:
*/
@Data
@ExcelIgnoreUnannotated
public class ProjectSastBugCenterDTO {
/**
* 缺陷名称
*/
@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

@ -10,9 +10,5 @@ import lombok.NoArgsConstructor;
* @Description:
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class VulnerabilityResultDTO extends CompareBaseResultDTO{
private Long newTotal;
}

View File

@ -4,6 +4,8 @@ package net.educoder.quality.mapper.mysql;
import net.educoder.quality.common.util.BaseMapper;
import net.educoder.quality.entity.mysql.ComponentParseRecord;
import java.util.List;
public interface ComponentParseRecordMapper extends BaseMapper<ComponentParseRecord> {
/**
@ -12,4 +14,11 @@ public interface ComponentParseRecordMapper extends BaseMapper<ComponentParseRec
* @return
*/
ComponentParseRecord getByProjectId(Long projectId);
/**
* 项目所有分析记录
* @param projectId
* @return
*/
List<ComponentParseRecord> quaryByProjectId(Long projectId);
}

View File

@ -119,15 +119,15 @@ public class ComponentServiceImpl implements ComponentService {
, url, " -token ", token, " -path ", fullPath, " -out ", outPath);
ShellResult shellResult = ShellUtil.executeAndGetExitStatus(command);
log.info("command:{}, result:{}", command, shellResult);
componentParseRecord = new ComponentParseRecord();
componentParseRecord.setProjectId(projectId);
componentParseRecord.setCreateTime(new Date());
componentParseRecord.setUpdateTime(new Date());
if (shellResult.getExitStatus() == 0) {
String output = FileUtil.readString(outPath, Charset.defaultCharset());
componentParseRecord = new ComponentParseRecord();
componentParseRecord.setProjectId(projectId);
componentParseRecord.setResult(output);
componentParseRecord.setCreateTime(new Date());
componentParseRecord.setUpdateTime(new Date());
componentParseRecordMapper.insertSelective(componentParseRecord);
parseResult(componentParseRecord.getResult(), componentParseRecord.getId(), parseRecordDetailSet);
@ -137,6 +137,9 @@ public class ComponentServiceImpl implements ComponentService {
List<ComponentParseRecordDetail> batchList = new ArrayList<>(parseRecordDetailSet);
componentParseRecordDetailMapper.insertList(batchList);
}
}else {
componentParseRecord.setResult("");
componentParseRecordMapper.insertSelective(componentParseRecord);
}
// } else {
// log.info("projectId:{},组件已解析", projectId);
@ -160,7 +163,7 @@ public class ComponentServiceImpl implements ComponentService {
// 插入漏洞
log.info("开始插入漏洞");
try{
batchInsertVulnerability(parseRecordDetailSet, projectId);
batchInsertVulnerability(parseRecordDetailSet, projectId,componentParseRecord.getId());
log.info("插入漏洞成功");
}catch (Exception e){
log.info("插入漏洞失败");
@ -169,9 +172,75 @@ public class ComponentServiceImpl implements ComponentService {
}
/**
* 批量插入漏洞
* 批量插入漏洞增量
*/
private void batchInsertVulnerability(Set<ComponentParseRecordDetail> parseRecordDetailSet, Long projectId) {
private void batchInsertVulnerability(Set<ComponentParseRecordDetail> parseRecordDetailSet, Long projectId, Long componentId) {
List<ProjectVulnerabilityDetail> projectVulnerabilityDetailList = new ArrayList<>();
for (ComponentParseRecordDetail componentParseRecordDetail : parseRecordDetailSet) {
String vulnerabilities = componentParseRecordDetail.getVulnerabilities();
if (StringUtils.isNotEmpty(vulnerabilities)) {
JSONArray vuls = JSON.parseArray(vulnerabilities);
for (int i = 0; i < vuls.size(); i++) {
ProjectVulnerabilityDetail pvd = new ProjectVulnerabilityDetail();
JSONObject vul = vuls.getJSONObject(i);
pvd.setVulnerabilityNumber(StringUtils.firstNonBlank(vul.getString("cwe_id"), vul.getString("id").replaceAll("XMIRROR-", "")));
pvd.setDescription(vul.getString("description"));
pvd.setAttackType(vul.getString("attack_type"));
pvd.setDifficulty(vul.getInteger("exploit_level_id"));
pvd.setRiskLevel(vul.getInteger("security_level_id"));
pvd.setPublishDate(vul.getString("release_date"));
pvd.setRepairSuggestions(vul.getString("suggestion"));
pvd.setVulnerabilityName(vul.getString("name"));
pvd.setComponentId(componentId);
pvd.setProjectId(projectId);
pvd.setCreateTime(DateTime.now());
pvd.setUpdateTime(DateTime.now());
projectVulnerabilityDetailList.add(pvd);
}
}
}
//新漏洞排除已有旧漏洞
List<ComponentParseRecord> parseRecords = componentParseRecordMapper.quaryByProjectId(projectId);
List<ProjectVulnerabilityDetail> oldVulnerabilityList = new ArrayList<>();
if (parseRecords.size()>=2){
Long oldComponentId = parseRecords.get(1).getId();
ProjectVulnerabilityDetail projectVulnerabilityDetail = new ProjectVulnerabilityDetail();
projectVulnerabilityDetail.setComponentId(oldComponentId);
oldVulnerabilityList = projectVulnerabilityDetailMapper.select(projectVulnerabilityDetail);
}
if (oldVulnerabilityList.size()>0){
Iterator<ProjectVulnerabilityDetail> it = projectVulnerabilityDetailList.iterator();
while (it.hasNext()){
ProjectVulnerabilityDetail newVulnerability = it.next();
for (ProjectVulnerabilityDetail oldVulnerability:oldVulnerabilityList) {
if (newVulnerability.equals(oldVulnerability)){
it.remove();
break;
}
}
}
//新漏洞加上所有旧漏洞
for (ProjectVulnerabilityDetail oldVulnerability:oldVulnerabilityList) {
oldVulnerability.setId(null);
oldVulnerability.setComponentId(componentId);
oldVulnerability.setProjectId(projectId);
oldVulnerability.setCreateTime(new Date());
oldVulnerability.setUpdateTime(new Date());
}
projectVulnerabilityDetailList.addAll(oldVulnerabilityList);
}
log.info("本次漏洞数据有{}条", projectVulnerabilityDetailList.size());
if (CollectionUtils.isNotEmpty(projectVulnerabilityDetailList)) {
projectVulnerabilityDetailMapper.insertList(projectVulnerabilityDetailList);
}
}
/**
* 批量插入漏洞全量
*/
private void batchInsertVulnerabilityAll(Set<ComponentParseRecordDetail> parseRecordDetailSet, Long projectId) {
List<ProjectVulnerabilityDetail> projectVulnerabilityDetailList = new ArrayList<>();
for (ComponentParseRecordDetail componentParseRecordDetail : parseRecordDetailSet) {
String vulnerabilities = componentParseRecordDetail.getVulnerabilities();
@ -198,22 +267,7 @@ public class ComponentServiceImpl implements ComponentService {
}
}
//排除已有漏洞
ProjectVulnerabilityDetail detail = new ProjectVulnerabilityDetail();
detail.setProjectId(projectId);
List<ProjectVulnerabilityDetail> oldVulnerabilityList = projectVulnerabilityDetailMapper.select(detail);
Iterator<ProjectVulnerabilityDetail> it = projectVulnerabilityDetailList.iterator();
while (it.hasNext()){
ProjectVulnerabilityDetail newVulnerability = it.next();
for (ProjectVulnerabilityDetail oldVulnerability:oldVulnerabilityList) {
if (newVulnerability.equals(oldVulnerability)){
it.remove();
break;
}
}
}
log.info("需新增漏洞数据有{}条", projectVulnerabilityDetailList.size());
log.info("本次漏洞数据有{}条", projectVulnerabilityDetailList.size());
if (CollectionUtils.isNotEmpty(projectVulnerabilityDetailList)) {
projectVulnerabilityDetailMapper.insertList(projectVulnerabilityDetailList);
}

View File

@ -95,6 +95,9 @@ public class ProjectServiceImpl implements ProjectService {
@Autowired
private ComponentService componentService;
@Autowired
private ComponentParseRecordMapper componentParseRecordMapper;
@Override
public PageInfo<ProjectsDTO> getProjectList(ProjectsVO projectsVO) {
@ -333,7 +336,7 @@ public class ProjectServiceImpl implements ProjectService {
// 缺陷&漏洞
BugResultDTO bug = pgProjectsService.getBug(projectName);
VulnerabilityResultDTO vulnerability = pgProjectsService.getComponentVulnerability(projectId);
VulnerabilityResultDTO vulnerability = pgProjectsService.getNewComponentVulnerability(projectId);
projectOverviewDTO.setBugDetail(bug);
projectOverviewDTO.setVulnerabilityDetail(vulnerability);
@ -362,7 +365,8 @@ public class ProjectServiceImpl implements ProjectService {
// 缺陷&漏洞
BugResultDTO bug = pgProjectsService.getBug(projectName);
VulnerabilityResultDTO vulnerability = pgProjectsService.getComponentVulnerability(projectId);
VulnerabilityResultDTO vulnerability = pgProjectsService.getNewComponentVulnerability(projectId);
VulnerabilityResultDTO vulnerability2 = pgProjectsService.getOldComponentVulnerability(projectId);
projectOverviewDTO.setBugDetail(bug);
projectOverviewDTO.setVulnerabilityDetail(vulnerability);
@ -374,7 +378,7 @@ public class ProjectServiceImpl implements ProjectService {
projectOverviewDTO.setBug(new ProjectOverviewDTO.Metres(projectMetrics2.getBugNumber(),
projectMetrics.getBugNumber() - projectMetrics2.getBugNumber()));
projectOverviewDTO.setVulnerability(new ProjectOverviewDTO.Metres(vulnerability.getTotal().intValue(),
vulnerability.getNewTotal().intValue()));
vulnerability.getTotal().intValue() - vulnerability2.getTotal().intValue()));
projectOverviewDTO.setComponent(new ProjectOverviewDTO.Metres());
projectOverviewDTO.setLicense(new ProjectOverviewDTO.Metres());
@ -888,6 +892,7 @@ public class ProjectServiceImpl implements ProjectService {
* @return
*/
private CompareResultDTO<?> processCompareResult(DetectResultCompareEnum detectResultCompareEnum, List<ProjectDetectionTaskInfo> projectDetectionTaskInfos) {
Long projectId = projectDetectionTaskInfos.get(0).getProjectId();
if (DetectResultCompareEnum.COMPONENT.getType().equals(detectResultCompareEnum.getType())) {
CompareResultDTO<ComponentResultDTO> resultDTO = new CompareResultDTO();
resultDTO.setFirstDetect(new ComponentResultDTO());
@ -896,14 +901,14 @@ public class ProjectServiceImpl implements ProjectService {
} else if (DetectResultCompareEnum.VULNERABILITY.getType().equals(detectResultCompareEnum.getType())) {
CompareResultDTO<VulnerabilityResultDTO> resultDTO = new CompareResultDTO();
ProjectDetectionTaskInfo projectDetectionTaskInfo = projectDetectionTaskInfos.get(0);
ProjectDetectionTaskInfo projectDetectionTaskInfo2 = projectDetectionTaskInfos.get(1);
// ProjectDetectionTaskInfo projectDetectionTaskInfo = projectDetectionTaskInfos.get(0);
// ProjectDetectionTaskInfo projectDetectionTaskInfo2 = projectDetectionTaskInfos.get(1);
//
// String projectName = projectDetectionTaskInfo.getProjectName() + "-" + projectDetectionTaskInfo.getRandomStr();
// String projectName2 = projectDetectionTaskInfo2.getProjectName() + "-" + projectDetectionTaskInfo2.getRandomStr();
String projectName = projectDetectionTaskInfo.getProjectName() + "-" + projectDetectionTaskInfo.getRandomStr();
String projectName2 = projectDetectionTaskInfo2.getProjectName() + "-" + projectDetectionTaskInfo2.getRandomStr();
resultDTO.setFirstDetect(pgProjectsService.getVulnerability(projectName2));
resultDTO.setSecondDetect(pgProjectsService.getVulnerability(projectName));
resultDTO.setFirstDetect(pgProjectsService.getOldComponentVulnerability(projectId));
resultDTO.setSecondDetect(pgProjectsService.getNewComponentVulnerability(projectId));
return resultDTO;
} else if (DetectResultCompareEnum.BUG.getType().equals(detectResultCompareEnum.getType())) {

View File

@ -20,7 +20,6 @@ import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j
@Service
@ -80,10 +79,18 @@ public class VulnerabilityServiceImpl implements VulnerabilityService {
@Override
public ProjectVulnerabilityDTO vulnerabilityStatistics(Long projectId) {
ProjectVulnerabilityDetail projectVulnerabilityDetail = new ProjectVulnerabilityDetail();
projectVulnerabilityDetail.setProjectId(projectId);
List<ProjectVulnerabilityDetail> details = projectVulnerabilityDetailMapper.select(projectVulnerabilityDetail);
ProjectVulnerabilityDTO result = new ProjectVulnerabilityDTO();
List<ComponentParseRecord> recordList = componentParseRecordMapper.quaryByProjectId(projectId);
if (recordList.size() <= 0){
return result;
}
ComponentParseRecord newRecord = recordList.get(0);
ProjectVulnerabilityDetail projectVulnerabilityDetail = new ProjectVulnerabilityDetail();
projectVulnerabilityDetail.setComponentId(newRecord.getId());
List<ProjectVulnerabilityDetail> details = projectVulnerabilityDetailMapper.select(projectVulnerabilityDetail);
result.setTotal((long)details.size());
for (ProjectVulnerabilityDetail detail : details) {
switch (detail.getRiskLevel()) {
case 0:
@ -106,13 +113,15 @@ public class VulnerabilityServiceImpl implements VulnerabilityService {
}
}
//根据componentId过滤出最近新增的Vulnerability
ComponentParseRecord componentParseRecord = componentParseRecordMapper.getByProjectId(projectId);
//根据上次检测结果过滤出最近新增的Vulnerability数量
ComponentParseRecord componentParseRecord = null;
if (recordList.size() >= 2){
componentParseRecord = recordList.get(1);
}
if (componentParseRecord!=null){
Long componentId = componentParseRecord.getId();
List<ProjectVulnerabilityDetail> collects = details.stream().filter(e -> {
return componentId.equals(e.getComponentId());
}).collect(Collectors.toList());
projectVulnerabilityDetail.setComponentId(componentId);
List<ProjectVulnerabilityDetail> collects = projectVulnerabilityDetailMapper.select(projectVulnerabilityDetail);
for (ProjectVulnerabilityDetail detail : collects) {
switch (detail.getRiskLevel()) {
case 0:
@ -134,6 +143,11 @@ public class VulnerabilityServiceImpl implements VulnerabilityService {
break;
}
}
result.setNewUnKnow(result.getUnKnow() - result.getNewUnKnow());
result.setNewLow(result.getLow() - result.getNewLow());
result.setNewMiddle(result.getMiddle() - result.getNewMiddle());
result.setNewHigh(result.getHigh() - result.getNewHigh());
result.setNewCritical(result.getCritical() - result.getNewCritical());
}
return result;

View File

@ -224,6 +224,7 @@ public class PgProjectsService {
* @param projectName
* @return
*/
@Deprecated
public VulnerabilityResultDTO getVulnerability(String projectName) {
VulnerabilityResultDTO resultDTO = new VulnerabilityResultDTO();
@ -249,15 +250,21 @@ public class PgProjectsService {
}
/**
* 组件漏洞指标
* 最新一次组件漏洞指标
* @param projectId
* @return
*/
public VulnerabilityResultDTO getComponentVulnerability(Long projectId) {
public VulnerabilityResultDTO getNewComponentVulnerability(Long projectId) {
VulnerabilityResultDTO result = new VulnerabilityResultDTO();
List<ComponentParseRecord> recordList = componentParseRecordMapper.quaryByProjectId(projectId);
if (recordList.size() <= 0){
return result;
}
ComponentParseRecord newRecord = recordList.get(0);
ProjectVulnerabilityDetail projectVulnerabilityDetail = new ProjectVulnerabilityDetail();
projectVulnerabilityDetail.setProjectId(projectId);
projectVulnerabilityDetail.setComponentId(newRecord.getId());
List<ProjectVulnerabilityDetail> details = projectVulnerabilityDetailMapper.select(projectVulnerabilityDetail);
result.setTotal((long)details.size());
for (ProjectVulnerabilityDetail detail : details) {
@ -278,19 +285,59 @@ public class PgProjectsService {
break;
}
}
ComponentParseRecord componentParseRecord = componentParseRecordMapper.getByProjectId(projectId);
if (componentParseRecord!=null) {
Long componentId = componentParseRecord.getId();
long collects = details.stream().filter(e -> {
return componentId.equals(e.getComponentId());
}).count();
result.setNewTotal(collects);
}
return result;
}
/**
* 通过组件检测记录id获取漏洞指标
* @param componentId
* @return
*/
public VulnerabilityResultDTO getVulnerabilityByComponentId(Long componentId) {
VulnerabilityResultDTO result = new VulnerabilityResultDTO();
ProjectVulnerabilityDetail projectVulnerabilityDetail = new ProjectVulnerabilityDetail();
projectVulnerabilityDetail.setComponentId(componentId);
List<ProjectVulnerabilityDetail> details = projectVulnerabilityDetailMapper.select(projectVulnerabilityDetail);
result.setTotal((long)details.size());
for (ProjectVulnerabilityDetail detail : details) {
switch (detail.getRiskLevel()) {
case 1:
result.setLow(result.getLow() + 1);
break;
case 2:
result.setMiddle(result.getMiddle() + 1);
break;
case 3:
result.setHigh(result.getHigh() + 1);
break;
case 4:
result.setCritical(result.getCritical() + 1);
break;
default:
break;
}
}
return result;
}
/**
* 上一次组件漏洞检测结果
* @param projectId
* @return
*/
public VulnerabilityResultDTO getOldComponentVulnerability(Long projectId) {
List<ComponentParseRecord> recordList = componentParseRecordMapper.quaryByProjectId(projectId);
VulnerabilityResultDTO vulnerability;
if (recordList.size() <= 1){
vulnerability = new VulnerabilityResultDTO();
}else {
Long oldComponentId = recordList.get(1).getId();
vulnerability = getVulnerabilityByComponentId(oldComponentId);
}
return vulnerability;
}
/**
* 获取缺陷指标
*

View File

@ -13,4 +13,15 @@
create_time desc
limit 1
</select>
<select id="quaryByProjectId" resultType="net.educoder.quality.entity.mysql.ComponentParseRecord">
select
id,project_id,result
from
component_parse_record
where
project_id=#{projectId}
order by
create_time desc
</select>
</mapper>