From 40aa4e42f10f2dbd8400cef0ca1321be6e774e19 Mon Sep 17 00:00:00 2001 From: gilseara <> Date: Wed, 1 Apr 2026 15:57:07 +0200 Subject: [PATCH 1/2] feat: Add --force-delete option to sc-dast scan delete command Add --force-delete / -f option that appends forceDelete=true query parameter to the scan-action API call, enabling forced deletion of SC DAST scans via /api/v2/scans/?forceDelete=true. --- .../action/AbstractSCDastScanActionCommand.java | 15 ++++++++++++--- .../cli/cmd/action/SCDastScanDeleteCommand.java | 16 ++++++++++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/AbstractSCDastScanActionCommand.java b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/AbstractSCDastScanActionCommand.java index fab8e1a358..7b47e8d5a2 100644 --- a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/AbstractSCDastScanActionCommand.java +++ b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/AbstractSCDastScanActionCommand.java @@ -43,12 +43,21 @@ public final JsonNode getJsonNode() { SCDastScanDescriptor descriptor = scanResolver.getScanDescriptor(unirest); ObjectNode body = new ObjectMapper().createObjectNode() .put("scanActionType", getAction().name()); - unirest.post("/api/v2/scans/{id}/scan-action") - .routeParam("id", descriptor.getId()) - .body(body) + var request = unirest.post("/api/v2/scans/{id}/scan-action") + .routeParam("id", descriptor.getId()); + request = updateRequest(request); + request.body(body) .asString().getBody(); // TODO Does SC DAST return proper HTTP codes if there are any errors, or should we parse the response? return descriptor.asJsonNode(); } + + /** + * Subclasses can override this method to add query parameters or other + * modifications to the request before it is sent. + */ + protected kong.unirest.core.HttpRequestWithBody updateRequest(kong.unirest.core.HttpRequestWithBody request) { + return request; + } @Override public final String getActionCommandResult() { diff --git a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/SCDastScanDeleteCommand.java b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/SCDastScanDeleteCommand.java index 263b20e2fb..cc50db61e8 100644 --- a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/SCDastScanDeleteCommand.java +++ b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/SCDastScanDeleteCommand.java @@ -14,16 +14,28 @@ import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import kong.unirest.core.HttpRequestWithBody; import lombok.Getter; import picocli.CommandLine.Command; import picocli.CommandLine.Mixin; +import picocli.CommandLine.Option; @Command(name = OutputHelperMixins.Delete.CMD_NAME) public class SCDastScanDeleteCommand extends AbstractSCDastScanActionCommand { -@Getter @Mixin private OutputHelperMixins.Delete outputHelper; - + @Getter @Mixin private OutputHelperMixins.Delete outputHelper; + @Option(names = {"--force-delete", "-f"}, description = "Force deletion of the scan by adding forceDelete=true query parameter") + private boolean forceDelete; + @Override protected SCDastScanAction getAction() { return SCDastScanAction.DeleteScan; } + + @Override + protected HttpRequestWithBody updateRequest(HttpRequestWithBody request) { + if (forceDelete) { + request.queryString("forceDelete", "true"); + } + return request; + } } From 41402944bbba256da4c79cefc95507819444c8ac Mon Sep 17 00:00:00 2001 From: gilseara <> Date: Wed, 1 Apr 2026 17:38:19 +0200 Subject: [PATCH 2/2] fix: Use Map instead of kong.unirest.core type for query parameters The kong.unirest.core package is not available in the sc-dast module's classpath. Replace the updateRequest hook with a getQueryParameters method that returns a Map, avoiding the dependency issue. --- .../cmd/action/AbstractSCDastScanActionCommand.java | 13 ++++++++----- .../cli/cmd/action/SCDastScanDeleteCommand.java | 10 ++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/AbstractSCDastScanActionCommand.java b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/AbstractSCDastScanActionCommand.java index 7b47e8d5a2..02938c792d 100644 --- a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/AbstractSCDastScanActionCommand.java +++ b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/AbstractSCDastScanActionCommand.java @@ -12,6 +12,9 @@ */ package com.fortify.cli.sc_dast.scan.cli.cmd.action; +import java.util.Collections; +import java.util.Map; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -45,18 +48,18 @@ public final JsonNode getJsonNode() { .put("scanActionType", getAction().name()); var request = unirest.post("/api/v2/scans/{id}/scan-action") .routeParam("id", descriptor.getId()); - request = updateRequest(request); + getQueryParameters().forEach(request::queryString); request.body(body) .asString().getBody(); // TODO Does SC DAST return proper HTTP codes if there are any errors, or should we parse the response? return descriptor.asJsonNode(); } /** - * Subclasses can override this method to add query parameters or other - * modifications to the request before it is sent. + * Subclasses can override this method to provide additional query parameters + * for the scan-action request. */ - protected kong.unirest.core.HttpRequestWithBody updateRequest(kong.unirest.core.HttpRequestWithBody request) { - return request; + protected Map getQueryParameters() { + return Collections.emptyMap(); } @Override diff --git a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/SCDastScanDeleteCommand.java b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/SCDastScanDeleteCommand.java index cc50db61e8..19ffdeb271 100644 --- a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/SCDastScanDeleteCommand.java +++ b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/action/SCDastScanDeleteCommand.java @@ -12,9 +12,11 @@ */ package com.fortify.cli.sc_dast.scan.cli.cmd.action; +import java.util.Collections; +import java.util.Map; + import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; -import kong.unirest.core.HttpRequestWithBody; import lombok.Getter; import picocli.CommandLine.Command; import picocli.CommandLine.Mixin; @@ -32,10 +34,10 @@ protected SCDastScanAction getAction() { } @Override - protected HttpRequestWithBody updateRequest(HttpRequestWithBody request) { + protected Map getQueryParameters() { if (forceDelete) { - request.queryString("forceDelete", "true"); + return Map.of("forceDelete", "true"); } - return request; + return Collections.emptyMap(); } }