Skip to content

Commit

Permalink
Merge pull request #691 from leec94/port-issue-3248
Browse files Browse the repository at this point in the history
Port: Project cloning logic for cloning policy violations and Violationanalysis
  • Loading branch information
nscuro authored May 30, 2024
2 parents 5d64fee + 8d0587f commit b0ffbb1
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.ArrayList;

final class PolicyQueryManager extends QueryManager implements IQueryManager {

Expand Down Expand Up @@ -288,6 +289,32 @@ public List<PolicyViolation> getAllPolicyViolations(final Component component, f
return query.executeList();
}

/**
* clones a policy violation
* @param sourcePolicyViolation the policy violation to clone
* @param destinationComponent the corresponding component
*/
public PolicyViolation clonePolicyViolation(PolicyViolation sourcePolicyViolation, Component destinationComponent){
//cloning PolicyViolation
final PolicyViolation policyViolation = new PolicyViolation();
policyViolation.setType(sourcePolicyViolation.getType());
policyViolation.setComponent(destinationComponent);
policyViolation.setPolicyCondition(sourcePolicyViolation.getPolicyCondition());
policyViolation.setTimestamp(sourcePolicyViolation.getTimestamp());
policyViolation.setText(sourcePolicyViolation.getText());
policyViolation.setType(sourcePolicyViolation.getType());
//cloning ViolatioAnalysis
ViolationAnalysis violationAnalysis = cloneViolationAnalysis(destinationComponent, sourcePolicyViolation);
//cloning ViolationAnalysisComments
List<ViolationAnalysisComment> comments = cloneViolationAnalysisComments(sourcePolicyViolation, violationAnalysis);
if(comments != null){
violationAnalysis.setAnalysisComments(comments);
}
policyViolation.setAnalysis(violationAnalysis);
policyViolation.getAnalysis().setPolicyViolation(policyViolation);
policyViolation.setUuid(sourcePolicyViolation.getUuid());
return policyViolation;
}
/**
* Returns a List of all Policy objects for a specific component.
* This method if designed NOT to provide paginated results.
Expand Down Expand Up @@ -378,6 +405,24 @@ public PaginatedResult getPolicyViolations(boolean includeSuppressed) {
return result;
}

/**
* clones a ViolationAnalysis
* @param destinationComponent the destinationComponent
* @param sourcePolicyViolation the PolicyViolation to clone from
* @return the cloned violationAnalysis
*/
public ViolationAnalysis cloneViolationAnalysis(Component destinationComponent, PolicyViolation sourcePolicyViolation){
ViolationAnalysis violationAnalysis = new ViolationAnalysis();
violationAnalysis.setComponent(destinationComponent);
if(sourcePolicyViolation.getAnalysis() != null){
violationAnalysis.setSuppressed(sourcePolicyViolation.getAnalysis().isSuppressed());
violationAnalysis.setViolationAnalysisState(sourcePolicyViolation.getAnalysis().getAnalysisState());
} else {
violationAnalysis.setViolationAnalysisState(ViolationAnalysisState.NOT_SET);
}
return violationAnalysis;
}

/**
* Returns a ViolationAnalysis for the specified Component and PolicyViolation.
* @param component the Component
Expand Down Expand Up @@ -416,6 +461,31 @@ public ViolationAnalysis makeViolationAnalysis(Component component, PolicyViolat
return getViolationAnalysis(violationAnalysis.getComponent(), violationAnalysis.getPolicyViolation());
}


/**
* clones ViolationAnalysisComments
* @param sourcePolicyViolation the source PolicyViolation
* @param violationAnalysis the ViolationAnalysis to clone from
* @return the cloned ViolationAnalysisComments
*/
public List<ViolationAnalysisComment> cloneViolationAnalysisComments(PolicyViolation sourcePolicyViolation, ViolationAnalysis violationAnalysis){
List<ViolationAnalysisComment> comments = new ArrayList<ViolationAnalysisComment>();
if(sourcePolicyViolation.getAnalysis() != null && sourcePolicyViolation.getAnalysis().getAnalysisComments() != null){
for(ViolationAnalysisComment c : sourcePolicyViolation.getAnalysis().getAnalysisComments()){
ViolationAnalysisComment comment = new ViolationAnalysisComment();
comment.setViolationAnalysis(violationAnalysis);
comment.setComment(c.getComment());
comment.setCommenter(c.getCommenter());
comment.setTimestamp(c.getTimestamp());
comments.add(comment);
}
}

return comments;
}



/**
* Adds a new violation analysis comment to the specified violation analysis.
* @param violationAnalysis the violation analysis object to add a comment to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.dependencytrack.model.Component;
import org.dependencytrack.model.ConfigPropertyConstants;
import org.dependencytrack.model.FindingAttribution;
import org.dependencytrack.model.PolicyViolation;
import org.dependencytrack.model.Project;
import org.dependencytrack.model.ProjectMetadata;
import org.dependencytrack.model.ProjectProperty;
Expand Down Expand Up @@ -513,7 +514,7 @@ public Project updateProject(Project transientProject, boolean commitIndex) {
@Override
public Project clone(UUID from, String newVersion, boolean includeTags, boolean includeProperties,
boolean includeComponents, boolean includeServices, boolean includeAuditHistory,
boolean includeACL) {
boolean includeACL, boolean includePolicyViolations) {
final Project source = getObjectByUuid(Project.class, from, Project.FetchGroup.ALL.name());
if (source == null) {
LOGGER.warn("Project with UUID %s was supposed to be cloned, but it does not exist anymore".formatted(from));
Expand Down Expand Up @@ -639,6 +640,17 @@ public Project clone(UUID from, String newVersion, boolean includeTags, boolean
}
}

if(includeComponents && includePolicyViolations){
final List<PolicyViolation> sourcePolicyViolations = getAllPolicyViolations(source);
if(sourcePolicyViolations != null){
for(final PolicyViolation policyViolation: sourcePolicyViolations){
final Component destinationComponent = clonedComponents.get(policyViolation.getComponent().getId());
final PolicyViolation clonedPolicyViolation = clonePolicyViolation(policyViolation, destinationComponent);
persist(clonedPolicyViolation);
}
}
}

project = getObjectById(Project.class, project.getId());
return project;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -573,9 +573,9 @@ public boolean updateNewProjectACL(Project transientProject, Principal principal

public Project clone(UUID from, String newVersion, boolean includeTags, boolean includeProperties,
boolean includeComponents, boolean includeServices, boolean includeAuditHistory,
boolean includeACL) {
boolean includeACL, boolean includePolicyViolations) {
return getProjectQueryManager().clone(from, newVersion, includeTags, includeProperties,
includeComponents, includeServices, includeAuditHistory, includeACL);
includeComponents, includeServices, includeAuditHistory, includeACL, includePolicyViolations);
}

public Project updateLastBomImport(Project p, Date date, String bomFormat) {
Expand Down Expand Up @@ -744,6 +744,10 @@ public PolicyCondition updatePolicyCondition(final PolicyCondition policyConditi
return getPolicyQueryManager().updatePolicyCondition(policyCondition);
}

public PolicyViolation clonePolicyViolation(PolicyViolation sourcePolicyViolation, Component destinationComponent){
return getPolicyQueryManager().clonePolicyViolation(sourcePolicyViolation, destinationComponent);
}

public List<PolicyViolation> getAllPolicyViolations() {
return getPolicyQueryManager().getAllPolicyViolations();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public class CloneProjectRequest {

private final boolean includeACL;

private final boolean includePolicyViolations;

@JsonCreator
public CloneProjectRequest(@JsonProperty(value = "project", required = true) String project,
@JsonProperty(value = "version", required = true) String version,
Expand All @@ -68,7 +70,8 @@ public CloneProjectRequest(@JsonProperty(value = "project", required = true) Str
@JsonProperty(value = "includeComponents") boolean includeComponents,
@JsonProperty(value = "includeServices") boolean includeServices,
@JsonProperty(value = "includeAuditHistory") boolean includeAuditHistory,
@JsonProperty(value = "includeACL") boolean includeACL) {
@JsonProperty(value = "includeACL") boolean includeACL,
@JsonProperty(value = "includePolicyViolations") boolean includePolicyViolations) {
if (includeDependencies) { // For backward compatibility
includeComponents = true;
}
Expand All @@ -81,6 +84,7 @@ public CloneProjectRequest(@JsonProperty(value = "project", required = true) Str
this.includeServices = includeServices;
this.includeAuditHistory = includeAuditHistory;
this.includeACL = includeACL;
this.includePolicyViolations = includePolicyViolations;
}

public String getProject() {
Expand Down Expand Up @@ -119,4 +123,7 @@ public boolean includeACL() {
return includeACL;
}

public boolean includePolicyViolations() {
return includePolicyViolations;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public void inform(final Event e) {
try (QueryManager qm = new QueryManager()) {
final Project project = qm.clone(UUID.fromString(request.getProject()),
request.getVersion(), request.includeTags(), request.includeProperties(),
request.includeComponents(), request.includeServices(), request.includeAuditHistory(), request.includeACL());
request.includeComponents(), request.includeServices(), request.includeAuditHistory(), request.includeACL(), request.includePolicyViolations());
LOGGER.info("Cloned project: " + request.getProject() + " to " + project.getUuid());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class CloneProjectEventTest {
@Test
public void testEvent() {
UUID uuid = UUID.randomUUID();
CloneProjectRequest request = new CloneProjectRequest(uuid.toString(), "1.0", true, true, true, true, true, true, true);
CloneProjectRequest request = new CloneProjectRequest(uuid.toString(), "1.0", true, true, true, true, true, true, true, true);
CloneProjectEvent event = new CloneProjectEvent(request);
Assert.assertEquals(request, event.getRequest());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,19 @@
package org.dependencytrack.persistence;

import org.dependencytrack.PersistenceCapableTest;
import org.dependencytrack.model.Component;
import org.dependencytrack.model.Policy;
import org.dependencytrack.model.PolicyViolation;
import org.dependencytrack.model.Project;
import org.dependencytrack.model.Tag;
import org.dependencytrack.model.ViolationAnalysis;
import org.dependencytrack.model.ViolationAnalysisComment;
import org.dependencytrack.model.ViolationAnalysisState;
import org.junit.Test;
import org.junit.Assert;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -105,4 +113,52 @@ public void testRemoveProjectFromPolicies() {
assertThat(qm.getObjectById(Policy.class, policy2.getId()).getProjects()).isEmpty();
}

@Test
public void testclonePolicyViolation() throws Exception{
PolicyViolation policyViolation = new PolicyViolation();
policyViolation.setId(1);

// Component for cloning
Component component = new Component();
component.setId(111L);
component.setName("name");
component.setVersion("1.0");
component.setCopyright("Copyright Acme");

policyViolation.setComponent(component);
policyViolation.setText("policyViolation");
policyViolation.setTimestamp(new Date());
policyViolation.setType(PolicyViolation.Type.LICENSE);

// ViolationAnalysis for cloning
ViolationAnalysis violationAnalysis = new ViolationAnalysis();
violationAnalysis.setSuppressed(true);
violationAnalysis.setViolationAnalysisState(ViolationAnalysisState.APPROVED);

// ViolationAnalysisComments
List<ViolationAnalysisComment> violationAnalysisComments = new ArrayList<>();
ViolationAnalysisComment violationAnalysisComment = new ViolationAnalysisComment();
violationAnalysisComment.setComment("testComment");
violationAnalysisComment.setCommenter("admin");
violationAnalysisComment.setTimestamp(new Date());
violationAnalysisComment.setViolationAnalysis(violationAnalysis);
violationAnalysisComments.add(violationAnalysisComment);
violationAnalysis.setAnalysisComments(violationAnalysisComments);

policyViolation.setAnalysis(violationAnalysis);

PolicyViolation clonedPolicyViolation = qm.clonePolicyViolation(policyViolation, component);
Assert.assertEquals(policyViolation.getText(), clonedPolicyViolation.getText());
Assert.assertEquals(policyViolation.getType(), clonedPolicyViolation.getType());
Assert.assertEquals(policyViolation.getTimestamp(), clonedPolicyViolation.getTimestamp());
Assert.assertEquals(policyViolation.getAnalysis().isSuppressed(), clonedPolicyViolation.getAnalysis().isSuppressed());
Assert.assertEquals(policyViolation.getAnalysis().getAnalysisState(), clonedPolicyViolation.getAnalysis().getAnalysisState());
Assert.assertEquals(policyViolation.getAnalysis().getAnalysisComments().get(0).getComment(), clonedPolicyViolation.getAnalysis().getAnalysisComments().get(0).getComment());
Assert.assertEquals(policyViolation.getAnalysis().getAnalysisComments().get(0).getCommenter(), clonedPolicyViolation.getAnalysis().getAnalysisComments().get(0).getCommenter());
Assert.assertEquals(policyViolation.getAnalysis().getAnalysisComments().get(0).getTimestamp(), clonedPolicyViolation.getAnalysis().getAnalysisComments().get(0).getTimestamp());
Assert.assertEquals(policyViolation.getComponent().getId(), clonedPolicyViolation.getComponent().getId());
Assert.assertEquals(policyViolation.getComponent().getName(), clonedPolicyViolation.getComponent().getName());
Assert.assertEquals(policyViolation.getComponent().getCopyright(), clonedPolicyViolation.getComponent().getCopyright());
Assert.assertEquals(policyViolation.getComponent().getVersion(), clonedPolicyViolation.getComponent().getVersion());
}
}

0 comments on commit b0ffbb1

Please sign in to comment.