Skip to content

Commit 0873702

Browse files
Master branch: Added proper component reconciliation on scan and bom processing - #123
1 parent 3b26b97 commit 0873702

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

src/main/java/org/owasp/dependencytrack/persistence/QueryManager.java

+39
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,45 @@ public void removeDependencyIfExist(Project project, Component component) {
917917
}
918918
}
919919

920+
/**
921+
* Intelligently adds dependencies for components that are not already a dependency
922+
* of the specified project and removes the dependency relationship for components
923+
* that are not in the list of specified components.
924+
* @param project the project to bind components to
925+
* @param components the complete list of components that should be dependencies of the project
926+
*/
927+
public void reconcileDependencies(Project project, List<Component> components) {
928+
// Holds a list of all Components that are existing dependencies of the specified project
929+
final List<Component> existingProjectDependencies = new ArrayList<>();
930+
getAllDependencies(project).forEach(item -> existingProjectDependencies.add(item.getComponent()));
931+
reconcileDependencies(project, existingProjectDependencies, components);
932+
}
933+
934+
/**
935+
* Intelligently adds dependencies for components that are not already a dependency
936+
* of the specified project and removes the dependency relationship for components
937+
* that are not in the list of specified components.
938+
* @param project the project to bind components to
939+
* @param existingProjectDependencies the complete list of existing dependent components
940+
* @param components the complete list of components that should be dependencies of the project
941+
*/
942+
public void reconcileDependencies(Project project, List<Component> existingProjectDependencies, List<Component> components) {
943+
// Removes components as dependencies to the project for all
944+
// components not included in the list provided
945+
for (Component existingDependency: existingProjectDependencies) {
946+
boolean keep = false;
947+
for (Component component: components) {
948+
if (component.getId() == existingDependency.getId()) {
949+
keep = true;
950+
}
951+
}
952+
if (!keep) {
953+
removeDependencyIfExist(project, existingDependency);
954+
}
955+
}
956+
components.forEach(component -> createDependencyIfNotExist(project, component, null, null));
957+
}
958+
920959
/**
921960
* Returns a List of all Dependency for the specified Project.
922961
* This method if designed NOT to provide paginated results.

src/main/java/org/owasp/dependencytrack/tasks/BomUploadProcessingTask.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,14 @@ public void inform(Event e) {
5454
final byte[] bomBytes = event.getBom();
5555
QueryManager qm = new QueryManager();
5656
try {
57+
final Project project = qm.getObjectByUuid(Project.class, event.getProjectUuid());
5758
final List<Component> components;
5859
final List<Component> flattenedComponents = new ArrayList<>();
60+
61+
// Holds a list of all Components that are existing dependencies of the specified project
62+
final List<Component> existingProjectDependencies = new ArrayList<>();
63+
qm.getAllDependencies(project).forEach(item -> existingProjectDependencies.add(item.getComponent()));
64+
5965
final String bomString = new String(bomBytes);
6066
if (bomString.startsWith("<?xml") && bomString.contains("<bom") && bomString.contains("http://cyclonedx.org/schema/bom")) {
6167
final CycloneDxParser parser = new CycloneDxParser(qm);
@@ -64,12 +70,13 @@ public void inform(Event e) {
6470
final SpdxDocumentParser parser = new SpdxDocumentParser(qm);
6571
components = parser.parse(bomBytes);
6672
}
67-
final Project project = qm.getObjectByUuid(Project.class, event.getProjectUuid());
6873
final Date date = new Date();
6974
final Bom bom = qm.createBom(project, date);
7075
for (Component component: components) {
7176
processComponent(qm, bom, project, component, flattenedComponents);
7277
}
78+
79+
qm.reconcileDependencies(project, existingProjectDependencies, flattenedComponents);
7380
qm.updateLastBomImport(project, date);
7481
EventService.getInstance().publish(new VulnerabilityAnalysisEvent(flattenedComponents));
7582
} catch (Exception ex) {

src/main/java/org/owasp/dependencytrack/tasks/ScanUploadProcessingTask.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,6 @@ public void inform(Event e) {
138138
component = qm.updateComponent(component, false);
139139
}
140140

141-
qm.createDependencyIfNotExist(project, component, null, null);
142-
143141
if (dependency.getVulnerabilities() != null && dependency.getVulnerabilities().getVulnerabilities() != null) {
144142
for (org.owasp.dependencytrack.parser.dependencycheck.model.Vulnerability dcvuln: dependency.getVulnerabilities().getVulnerabilities()) {
145143

@@ -171,6 +169,8 @@ public void inform(Event e) {
171169
.getSource(), evidence.getName(), evidence.getValue());
172170
}
173171
}
172+
173+
qm.reconcileDependencies(project, components);
174174
qm.updateLastScanImport(project, date);
175175
EventService.getInstance().publish(new VulnerabilityAnalysisEvent(components));
176176
} catch (Exception ex) {

0 commit comments

Comments
 (0)