forked from fortify/fcli
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
kadraman
committed
Mar 6, 2025
1 parent
d9bcb7b
commit 87d87a0
Showing
8 changed files
with
379 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
...-core/fcli-fod/src/main/java/com/fortify/cli/fod/issue/cli/cmd/FoDIssueUpdateCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/******************************************************************************* | ||
* Copyright 2021, 2025 Open Text. | ||
* | ||
* The only warranties for products and services of Open Text | ||
* and its affiliates and licensors ("Open Text") are as may | ||
* be set forth in the express warranty statements accompanying | ||
* such products and services. Nothing herein should be construed | ||
* as constituting an additional warranty. Open Text shall not be | ||
* liable for technical or editorial errors or omissions contained | ||
* herein. The information contained herein is subject to change | ||
* without notice. | ||
*******************************************************************************/ | ||
|
||
package com.fortify.cli.fod.issue.cli.cmd; | ||
|
||
import java.util.ArrayList; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; | ||
import com.fortify.cli.common.output.transform.IActionCommandResultSupplier; | ||
import com.fortify.cli.fod._common.cli.mixin.FoDDelimiterMixin; | ||
import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDJsonNodeOutputCommand; | ||
import com.fortify.cli.fod._common.util.FoDEnums.DeveloperStatusType; | ||
import com.fortify.cli.fod._common.util.FoDEnums.AuditorStatusType; | ||
import com.fortify.cli.fod._common.util.FoDEnums.VulnerabilitySeverityType; | ||
import com.fortify.cli.fod.issue.helper.FoDBulkIssueUpdateRequest; | ||
import com.fortify.cli.fod.issue.helper.FoDBulkIssueUpdateResponse; | ||
import com.fortify.cli.fod.issue.helper.FoDIssueHelper; | ||
import com.fortify.cli.fod.release.cli.mixin.FoDReleaseByQualifiedNameOrIdResolverMixin; | ||
import com.fortify.cli.fod.release.helper.FoDReleaseDescriptor; | ||
|
||
import kong.unirest.UnirestInstance; | ||
import lombok.Getter; | ||
import picocli.CommandLine.Command; | ||
import picocli.CommandLine.Mixin; | ||
import picocli.CommandLine.Option; | ||
|
||
@Command(name = OutputHelperMixins.Update.CMD_NAME) | ||
public class FoDIssueUpdateCommand extends AbstractFoDJsonNodeOutputCommand implements IActionCommandResultSupplier { | ||
private static final Logger LOG = LoggerFactory.getLogger(FoDIssueUpdateCommand.class); | ||
@Getter @Mixin private OutputHelperMixins.Update outputHelper; | ||
@Mixin private FoDDelimiterMixin delimiterMixin; // Is automatically injected in resolver mixins | ||
@Mixin private FoDReleaseByQualifiedNameOrIdResolverMixin.RequiredOption releaseResolver; | ||
|
||
@Option(names = {"--user"}, required = true) | ||
protected String user; | ||
@Option(names = {"--dev-status"}, required = false) | ||
protected DeveloperStatusType developerStatus; | ||
@Option(names = {"--auditor-status"}, required = false) | ||
protected AuditorStatusType auditorStatus; | ||
@Option(names = {"--severity"}, required = false) | ||
protected VulnerabilitySeverityType severity; | ||
@Option(names = {"--comment"}, required = false) | ||
protected String comment; | ||
@Option(names = {"--ids"}, required = true, split=",") | ||
protected ArrayList<String> vulnIds; | ||
|
||
private long errorCount = 0; | ||
|
||
@Override | ||
public JsonNode getJsonNode(UnirestInstance unirest) { | ||
FoDReleaseDescriptor releaseDescriptor = releaseResolver.getReleaseDescriptor(unirest); | ||
|
||
FoDBulkIssueUpdateRequest issueUpdateRequest = FoDBulkIssueUpdateRequest.builder() | ||
.user(unirest, user) | ||
.developerStatus(developerStatus.getValue()) | ||
.auditorStatus(auditorStatus.getValue()) | ||
.severity(severity.toString()) | ||
.comment(comment) | ||
.vulnerabilityIds(vulnIds) | ||
.build().validate(); | ||
|
||
LOG.debug("Updating issues: {}", vulnIds.toString()); | ||
FoDBulkIssueUpdateResponse resp = FoDIssueHelper.updateIssues(unirest, releaseDescriptor.getReleaseId(), issueUpdateRequest); | ||
errorCount = resp.getResults() | ||
.stream() | ||
.filter(r -> r.getErrorCode() != 0) | ||
.count(); | ||
resp.setIssueCount(resp.getResults().size()); | ||
resp.setErrorCount(errorCount); | ||
LOG.debug("Response: {}", resp.getResults().toString()); | ||
|
||
return resp.asObjectNode().put("issueCount", resp.getResults().size()).put("errorCount", errorCount); | ||
} | ||
|
||
@Override | ||
public String getActionCommandResult() { | ||
return (errorCount == 0 ? "ISSUES_UPDATED" : "ISSUES_UPDATED_WITH_ERRORS"); | ||
} | ||
|
||
@Override | ||
public boolean isSingular() { | ||
return true; | ||
} | ||
|
||
} |
80 changes: 80 additions & 0 deletions
80
...re/fcli-fod/src/main/java/com/fortify/cli/fod/issue/helper/FoDBulkIssueUpdateRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/******************************************************************************* | ||
* Copyright 2021, 2025 Open Text. | ||
* | ||
* The only warranties for products and services of Open Text | ||
* and its affiliates and licensors ("Open Text") are as may | ||
* be set forth in the express warranty statements accompanying | ||
* such products and services. Nothing herein should be construed | ||
* as constituting an additional warranty. Open Text shall not be | ||
* liable for technical or editorial errors or omissions contained | ||
* herein. The information contained herein is subject to change | ||
* without notice. | ||
*******************************************************************************/ | ||
|
||
package com.fortify.cli.fod.issue.helper; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.function.Consumer; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnore; | ||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import com.formkiq.graalvm.annotations.Reflectable; | ||
import com.fortify.cli.common.exception.FcliSimpleException; | ||
import com.fortify.cli.common.util.StringUtils; | ||
import com.fortify.cli.fod.access_control.helper.FoDUserHelper; | ||
import kong.unirest.UnirestInstance; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.ToString; | ||
|
||
@Reflectable @NoArgsConstructor @AllArgsConstructor | ||
@Getter | ||
@ToString | ||
@Builder | ||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
public class FoDBulkIssueUpdateRequest { | ||
private Integer userId; | ||
private String developerStatus; | ||
private String auditorStatus; | ||
private String severity; | ||
private String comment; | ||
private ArrayList<String> vulnerabilityIds; | ||
|
||
@JsonIgnore | ||
public final FoDBulkIssueUpdateRequest validate(Consumer<List<String>> validationMessageConsumer) { | ||
var messages = new ArrayList<String>(); | ||
validateRequired(messages, vulnerabilityIds, "Vulnerability Ids not specified"); | ||
if ( !messages.isEmpty() ) { | ||
validationMessageConsumer.accept(messages); | ||
} | ||
return this; | ||
} | ||
|
||
@JsonIgnore | ||
public final FoDBulkIssueUpdateRequest validate() { | ||
return validate(messages->{throw new FcliSimpleException("Unable to update issues:\n\t"+String.join("\n\t", messages)); }); | ||
} | ||
|
||
@JsonIgnore | ||
private final void validateRequired(List<String> messages, Object obj, String message) { | ||
if ( obj==null || (obj instanceof String && StringUtils.isBlank((String)obj)) ) { | ||
messages.add(message); | ||
} | ||
} | ||
|
||
public static class FoDBulkIssueUpdateRequestBuilder { | ||
public FoDBulkIssueUpdateRequestBuilder user(UnirestInstance unirest, String user) { | ||
int userId = 0; | ||
if (user == null) return userId(null); | ||
try { | ||
userId = Integer.parseInt(user); | ||
} catch (NumberFormatException nfe) { | ||
userId = FoDUserHelper.getUserDescriptor(unirest, user, true).getUserId(); | ||
} | ||
return userId(userId); | ||
} | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
...e/fcli-fod/src/main/java/com/fortify/cli/fod/issue/helper/FoDBulkIssueUpdateResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/******************************************************************************* | ||
* Copyright 2021, 2025 Open Text. | ||
* | ||
* The only warranties for products and services of Open Text | ||
* and its affiliates and licensors ("Open Text") are as may | ||
* be set forth in the express warranty statements accompanying | ||
* such products and services. Nothing herein should be construed | ||
* as constituting an additional warranty. Open Text shall not be | ||
* liable for technical or editorial errors or omissions contained | ||
* herein. The information contained herein is subject to change | ||
* without notice. | ||
*******************************************************************************/ | ||
|
||
package com.fortify.cli.fod.issue.helper; | ||
|
||
import java.util.ArrayList; | ||
import com.formkiq.graalvm.annotations.Reflectable; | ||
import com.fortify.cli.common.json.JsonNodeHolder; | ||
import lombok.Data; | ||
import lombok.EqualsAndHashCode; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Reflectable @NoArgsConstructor | ||
@Data @EqualsAndHashCode(callSuper = true) | ||
public class FoDBulkIssueUpdateResponse extends JsonNodeHolder { | ||
private ArrayList<VulnerabilityBulkUpdateResult> results; | ||
private long issueCount; | ||
private long errorCount; | ||
|
||
@Reflectable @NoArgsConstructor | ||
@Data | ||
public static final class VulnerabilityBulkUpdateResult { | ||
private String vulnerabilityId; | ||
private Integer errorCode; | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/issue/helper/FoDIssueHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/******************************************************************************* | ||
* Copyright 2021, 2023 Open Text. | ||
* | ||
* The only warranties for products and services of Open Text | ||
* and its affiliates and licensors ("Open Text") are as may | ||
* be set forth in the express warranty statements accompanying | ||
* such products and services. Nothing herein should be construed | ||
* as constituting an additional warranty. Open Text shall not be | ||
* liable for technical or editorial errors or omissions contained | ||
* herein. The information contained herein is subject to change | ||
* without notice. | ||
*******************************************************************************/ | ||
package com.fortify.cli.fod.issue.helper; | ||
|
||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.fasterxml.jackson.databind.node.ObjectNode; | ||
import com.fortify.cli.common.json.JsonHelper; | ||
import com.fortify.cli.common.output.transform.fields.RenameFieldsTransformer; | ||
import com.fortify.cli.fod._common.rest.FoDUrls; | ||
import kong.unirest.UnirestInstance; | ||
import lombok.Getter; | ||
|
||
public class FoDIssueHelper { | ||
@Getter | ||
private static ObjectMapper objectMapper = new ObjectMapper(); | ||
|
||
public static final JsonNode transformRecord(JsonNode record) { | ||
return new RenameFieldsTransformer(new String[]{}).transform(record); | ||
} | ||
|
||
public static final FoDBulkIssueUpdateResponse updateIssues(UnirestInstance unirest, String releaseId, FoDBulkIssueUpdateRequest issueUpdateRequest) { | ||
ObjectNode body = objectMapper.valueToTree(issueUpdateRequest); | ||
var result = unirest.post(FoDUrls.VULNERABILITIES + "/bulk-edit") | ||
.routeParam("relId", releaseId) | ||
.body(body).asObject(JsonNode.class).getBody(); | ||
return getResponse(result); | ||
} | ||
|
||
private static final FoDBulkIssueUpdateResponse getResponse(JsonNode node) { | ||
return node==null ? null : JsonHelper.treeToValue(node, FoDBulkIssueUpdateResponse.class); | ||
} | ||
|
||
} |
Oops, something went wrong.