From a0efd46f8adf2949e13ddac4514e7f93a352dcff Mon Sep 17 00:00:00 2001 From: Sebastien Delcoigne Date: Thu, 14 Mar 2024 12:22:48 +1100 Subject: [PATCH] Adds analysis comments for justification, state and details for new analysis added either via UI or directly via REST call. Does add more comments when using the UI but reflects state of the vulnerability audit better. Fixes: #3470 Signed-off-by: Sebastien Delcoigne --- .../resources/v1/AnalysisResource.java | 8 +-- .../resources/v1/vo/AnalysisRequest.java | 2 +- .../util/AnalysisCommentUtil.java | 55 +++++++++++++++++-- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/dependencytrack/resources/v1/AnalysisResource.java b/src/main/java/org/dependencytrack/resources/v1/AnalysisResource.java index 6b9d16a7d6..b742a52416 100644 --- a/src/main/java/org/dependencytrack/resources/v1/AnalysisResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/AnalysisResource.java @@ -35,7 +35,6 @@ import org.apache.commons.lang3.StringUtils; import org.dependencytrack.auth.Permissions; import org.dependencytrack.model.Analysis; -import org.dependencytrack.model.AnalysisState; import org.dependencytrack.model.Component; import org.dependencytrack.model.Project; import org.dependencytrack.model.Vulnerability; @@ -166,9 +165,10 @@ public Response updateAnalysis(AnalysisRequest request) { } else { analysis = qm.makeAnalysis(component, vulnerability, request.getAnalysisState(), request.getAnalysisJustification(), request.getAnalysisResponse(), request.getAnalysisDetails(), request.isSuppressed()); analysisStateChange = true; // this is a new analysis - so set to true because it was previously null - if (AnalysisState.NOT_SET != request.getAnalysisState()) { - qm.makeAnalysisComment(analysis, String.format("Analysis: %s → %s", AnalysisState.NOT_SET, request.getAnalysisState()), commenter); - } + AnalysisCommentUtil.makeFirstStateComment(qm, analysis, commenter); + AnalysisCommentUtil.makeFirstJustificationComment(qm, analysis, commenter); + AnalysisCommentUtil.makeFirstAnalysisResponseComment(qm, analysis, commenter); + AnalysisCommentUtil.makeFirstDetailsComment(qm, analysis, commenter); } final String comment = StringUtils.trimToNull(request.getComment()); diff --git a/src/main/java/org/dependencytrack/resources/v1/vo/AnalysisRequest.java b/src/main/java/org/dependencytrack/resources/v1/vo/AnalysisRequest.java index c9f73b9bc0..d875f42dec 100644 --- a/src/main/java/org/dependencytrack/resources/v1/vo/AnalysisRequest.java +++ b/src/main/java/org/dependencytrack/resources/v1/vo/AnalysisRequest.java @@ -54,7 +54,7 @@ public class AnalysisRequest { private final String comment; @JsonDeserialize(using = TrimmedStringDeserializer.class) - @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS_PLUS, message = "The comment may only contain printable characters") + @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS_PLUS, message = "The analysis details may only contain printable characters") private final String analysisDetails; private final AnalysisState analysisState; diff --git a/src/main/java/org/dependencytrack/util/AnalysisCommentUtil.java b/src/main/java/org/dependencytrack/util/AnalysisCommentUtil.java index f76810e27a..c8e72c08b8 100644 --- a/src/main/java/org/dependencytrack/util/AnalysisCommentUtil.java +++ b/src/main/java/org/dependencytrack/util/AnalysisCommentUtil.java @@ -28,35 +28,73 @@ public final class AnalysisCommentUtil { private AnalysisCommentUtil() { } + + public static void makeFirstStateComment(final QueryManager qm, final Analysis analysis, final String commenter) { + if (analysis.getAnalysisState() != null) { + addAnalysisStateComment(qm, analysis, null, analysis.getAnalysisState(), commenter); + } + } + public static boolean makeStateComment(final QueryManager qm, final Analysis analysis, final AnalysisState analysisState, final String commenter) { boolean analysisStateChange = false; if (analysisState != null && analysisState != analysis.getAnalysisState()) { analysisStateChange = true; - qm.makeAnalysisComment(analysis, String.format("Analysis: %s → %s", analysis.getAnalysisState(), analysisState), commenter); + addAnalysisStateComment(qm, analysis, analysis.getAnalysisState(), analysisState, commenter); } return analysisStateChange; } + private static void addAnalysisStateComment(QueryManager qm, Analysis analysis, AnalysisState before, AnalysisState after, String commenter) { + qm.makeAnalysisComment(analysis, String.format("Analysis: %s → %s", before, after), commenter); + } + + public static void makeFirstJustificationComment(QueryManager qm, Analysis analysis, String commenter) { + if (analysis.getAnalysisJustification() != null) { + addAnalysisJustificationComment(qm, analysis, null, analysis.getAnalysisJustification(), commenter); + } + } + public static void makeJustificationComment(final QueryManager qm, final Analysis analysis, final AnalysisJustification analysisJustification, final String commenter) { if (analysisJustification != null) { if (analysis.getAnalysisJustification() == null && AnalysisJustification.NOT_SET != analysisJustification) { - qm.makeAnalysisComment(analysis, String.format("Justification: %s → %s", AnalysisJustification.NOT_SET, analysisJustification), commenter); + addAnalysisJustificationComment(qm, analysis, AnalysisJustification.NOT_SET, analysisJustification, commenter); } else if (analysis.getAnalysisJustification() != null && analysisJustification != analysis.getAnalysisJustification()) { - qm.makeAnalysisComment(analysis, String.format("Justification: %s → %s", analysis.getAnalysisJustification(), analysisJustification), commenter); + addAnalysisJustificationComment(qm, analysis, analysis.getAnalysisJustification(), analysisJustification, commenter); } } } + private static void addAnalysisJustificationComment(QueryManager qm, Analysis analysis, AnalysisJustification before, AnalysisJustification after, String commenter) { + qm.makeAnalysisComment(analysis, String.format("Justification: %s → %s", before, after), commenter); + } + + + public static void makeFirstAnalysisResponseComment(QueryManager qm, Analysis analysis, String commenter) { + if (analysis.getAnalysisResponse() != null) { + addAnalysisResponseComment(qm, analysis, null, analysis.getAnalysisResponse(), commenter); + } + } + public static void makeAnalysisResponseComment(final QueryManager qm, final Analysis analysis, final AnalysisResponse analysisResponse, final String commenter) { if (analysisResponse != null) { if (analysis.getAnalysisResponse() == null && analysis.getAnalysisResponse() != analysisResponse) { - qm.makeAnalysisComment(analysis, String.format("Vendor Response: %s → %s", AnalysisResponse.NOT_SET, analysisResponse), commenter); + addAnalysisResponseComment(qm, analysis, AnalysisResponse.NOT_SET, analysisResponse, commenter); } else if (analysis.getAnalysisResponse() != null && analysis.getAnalysisResponse() != analysisResponse) { - qm.makeAnalysisComment(analysis, String.format("Vendor Response: %s → %s", analysis.getAnalysisResponse(), analysisResponse), commenter); + addAnalysisResponseComment(qm, analysis, analysis.getAnalysisResponse(), analysisResponse, commenter); } } } + private static void addAnalysisResponseComment(QueryManager qm, Analysis analysis, AnalysisResponse before, AnalysisResponse after, String commenter) { + qm.makeAnalysisComment(analysis, String.format("Vendor Response: %s → %s", before, after), commenter); + } + + public static void makeFirstDetailsComment(QueryManager qm, Analysis analysis, String commenter) { + if (analysis.getAnalysisDetails() != null && !analysis.getAnalysisDetails().isEmpty()) { + addAnalysisDetailsComment(qm, analysis, commenter); + } + } + public static void makeAnalysisDetailsComment(final QueryManager qm, final Analysis analysis, final String analysisDetails, final String commenter) { if (analysisDetails != null && !analysisDetails.equals(analysis.getAnalysisDetails())) { final String message = "Details: " + analysisDetails.trim(); @@ -64,6 +102,11 @@ public static void makeAnalysisDetailsComment(final QueryManager qm, final Analy } } + private static void addAnalysisDetailsComment(QueryManager qm, Analysis analysis, String commenter) { + final String message = "Details: " + analysis.getAnalysisDetails().trim(); + qm.makeAnalysisComment(analysis, message, commenter); + } + public static boolean makeAnalysisSuppressionComment(final QueryManager qm, final Analysis analysis, final Boolean suppressed, final String commenter) { boolean suppressionChange = false; if (suppressed != null && analysis.isSuppressed() != suppressed) { @@ -73,4 +116,6 @@ public static boolean makeAnalysisSuppressionComment(final QueryManager qm, fina } return suppressionChange; } + + }