diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/output/mixin/FoDOutputHelperMixins.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/output/mixin/FoDOutputHelperMixins.java index 6aac3996e1..724769a968 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/output/mixin/FoDOutputHelperMixins.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/output/mixin/FoDOutputHelperMixins.java @@ -26,15 +26,24 @@ public class FoDOutputHelperMixins { public static class DownloadLatest extends OutputHelperMixins.TableNoQuery { public static final String CMD_NAME = "download-latest"; } - public static class SetupSast extends OutputHelperMixins.DetailsNoQuery { + public static class SetupSast extends OutputHelperMixins.TableNoQuery { public static final String CMD_NAME = "setup-sast"; } - public static class SetupDast extends OutputHelperMixins.DetailsNoQuery { + public static class SetupDast extends OutputHelperMixins.TableNoQuery { public static final String CMD_NAME = "setup-dast"; } - public static class SetupMobile extends OutputHelperMixins.DetailsNoQuery { + public static class SetupMobile extends OutputHelperMixins.TableNoQuery { public static final String CMD_NAME = "setup-mobile"; } + public static class SetupWebsite extends OutputHelperMixins.TableNoQuery { + public static final String CMD_NAME = "setup-website"; + } + public static class SetupWorkflow extends OutputHelperMixins.TableNoQuery { + public static final String CMD_NAME = "setup-workflow"; + } + public static class SetupApi extends OutputHelperMixins.TableNoQuery { + public static final String CMD_NAME = "setup-api"; + } public static class GetConfig extends OutputHelperMixins.DetailsNoQuery { public static final String CMD_NAME = "get-config"; } @@ -94,4 +103,8 @@ public static class StartLegacy extends OutputHelperMixins.TableNoQuery { public static class GetConfigLegacy extends OutputHelperMixins.DetailsNoQuery { public static final String CMD_NAME = "get-config-legacy"; } + + public static class UploadFile extends OutputHelperMixins.TableNoQuery { + public static final String CMD_NAME = "upload-file"; + } } diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/FoDUrls.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/FoDUrls.java index ad36211698..8c4d299980 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/FoDUrls.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/FoDUrls.java @@ -53,6 +53,7 @@ public class FoDUrls { public static final String ENTITLEMENTS = ApiBase + "/tenant-entitlements"; public static final String OSS_SCANS = ApiBase + "/releases/{relId}/open-source-scans"; public static final String OSS_SCANS_START = OSS_SCANS + "/start-scan"; + public static final String DAST_AUTOMATED_SCANS = ApiBase + "/releases/{relId}/dast-automated-scans"; public static final String REPORTS = ApiBase + "/reports"; public static final String REPORT = ApiBase + "/reports/{reportId}"; } diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/helper/FoDDataHelper.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/helper/FoDDataHelper.java index 83f6f13b26..e9be2de8a7 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/helper/FoDDataHelper.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/helper/FoDDataHelper.java @@ -1,13 +1,13 @@ /** * Copyright 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 + * 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._common.rest.helper; @@ -41,15 +41,15 @@ public static final ArrayNode findMatching(HttpRequest request, Predicate request, String... filters) { return getUnique(findMatching(request, filters)); } - + public static final JsonNode findUnique(HttpRequest request, Predicate predicate) { return getUnique(findMatching(request, predicate)); } - + public static final JsonNode getUnique(ArrayNode nodes) { switch (nodes.size()) { case 0: return null; @@ -57,14 +57,14 @@ public static final JsonNode getUnique(ArrayNode nodes) { default: throw new IllegalStateException("Multiple matches found"); } } - + private static final Predicate asPredicate(String filter) { int idx = filter.indexOf(':'); String key = filter.substring(0, idx); String value = filter.substring(idx+1); return node -> matches(node, key, value); } - + private static final boolean matches(JsonNode node, String fieldName, String valueToMatch) { JsonNode valueNode = node==null ? null : node.get(fieldName); return valueNode==null ? false : valueToMatch.equals(valueNode.asText()); diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/helper/FoDFileTransferHelper.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/helper/FoDFileTransferHelper.java index 9604b40fdb..c08c962af7 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/helper/FoDFileTransferHelper.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/helper/FoDFileTransferHelper.java @@ -1,13 +1,13 @@ /******************************************************************************* * 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 + * 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. *******************************************************************************/ @@ -32,12 +32,32 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; -// TODO Based on some recent messages on FortifySSC, potentially we may need +// TODO Based on some recent messages on FortifySSC, potentially we may need // chunked uploads for SC DAST as well, so consider refactoring into a // generic class in fcli-common. public final class FoDFileTransferHelper { private static final int chunkSize = FoDConstants.DEFAULT_CHUNK_SIZE; + @SneakyThrows + public static final JsonNode upload(UnirestInstance unirest, HttpRequest baseRequest, File f) { + if (!f.exists() || !f.canRead()) { + throw new IllegalArgumentException("Could not read file: " + f.getPath()); + } + String body = null; + try ( FoDProgressMonitor uploadMonitor = new FoDProgressMonitor("Upload") ) { + body = unirest.request(baseRequest.getHttpMethod().name(), baseRequest.getUrl()) + .noCharset() + .multiPartContent() + .field("file", f) + .uploadMonitor(uploadMonitor) + .asString() + .getBody(); + } catch (Exception e) { + throw new RuntimeException("Error uploading file", e); + } + return new ObjectMapper().readTree(body); + } + @SneakyThrows public static final JsonNode uploadChunked(UnirestInstance unirest, HttpRequest baseRequest, File f) { if (!f.exists() || !f.canRead()) { @@ -64,7 +84,7 @@ public static final JsonNode uploadChunked(UnirestInstance unirest, HttpRequest< } lastBody = unirest.request( - String.valueOf(baseRequest.getHttpMethod()), + String.valueOf(baseRequest.getHttpMethod()), getUri(baseRequest, fragmentNumber++, offset)) .contentType("application/octet-stream") .header("Accept", "application/json") diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanFileUploadCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanFileUploadCommand.java new file mode 100644 index 0000000000..be839afbd3 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanFileUploadCommand.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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._common.scan.cli.cmd; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fortify.cli.common.cli.mixin.CommonOptionMixins; +import com.fortify.cli.common.cli.util.CommandGroup; +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.AbstractFoDJsonNodeOutputCommand; +import com.fortify.cli.fod._common.rest.helper.FoDFileTransferHelper; +import com.fortify.cli.fod.release.cli.mixin.FoDReleaseByQualifiedNameOrIdResolverMixin; +import kong.unirest.HttpRequest; +import kong.unirest.UnirestInstance; +import picocli.CommandLine.Mixin; + +@CommandGroup("*-scan-upload-file") +public abstract class AbstractFoDScanFileUploadCommand extends AbstractFoDJsonNodeOutputCommand implements IActionCommandResultSupplier { + @Mixin private FoDDelimiterMixin delimiterMixin; // Is automatically injected in resolver mixins + @Mixin private FoDReleaseByQualifiedNameOrIdResolverMixin.RequiredOption releaseResolver; + + @Mixin private CommonOptionMixins.RequiredFile uploadFileMixin; + + @Override + public final JsonNode getJsonNode(UnirestInstance unirest) { + var releaseDescriptor = releaseResolver.getReleaseDescriptor(unirest); + var releaseId = releaseDescriptor.getReleaseId(); + HttpRequest baseRequest = getBaseRequest(unirest, releaseId); + JsonNode response = FoDFileTransferHelper.upload(unirest, baseRequest, uploadFileMixin.getFile()); + return releaseDescriptor.asObjectNode() + .put("fileType", getFileType()) + .put("filename", uploadFileMixin.getFile().getName()) + .put("fileId", response.get("fileId").intValue()); + } + + protected abstract String getFileType(); + + protected abstract HttpRequest getBaseRequest(UnirestInstance unirest, String releaseId); + + @Override + public final String getActionCommandResult() { + return "UPLOADED"; + } + + @Override + public final boolean isSingular() { + return true; + } + +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanSetupCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanSetupCommand.java new file mode 100644 index 0000000000..52caee40d8 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanSetupCommand.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * 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._common.scan.cli.cmd; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fortify.cli.common.cli.mixin.CommonOptionMixins; +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.AbstractFoDJsonNodeOutputCommand; +import com.fortify.cli.fod._common.rest.FoDUrls; +import com.fortify.cli.fod._common.rest.helper.FoDFileTransferHelper; +import com.fortify.cli.fod._common.scan.cli.mixin.FoDEntitlementFrequencyTypeMixins; +import com.fortify.cli.fod._common.scan.helper.FoDScanType; +import com.fortify.cli.fod.release.cli.mixin.FoDReleaseByQualifiedNameOrIdResolverMixin; +import kong.unirest.HttpRequest; +import kong.unirest.HttpResponse; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import picocli.CommandLine.Mixin; +import picocli.CommandLine.Option; + +public abstract class AbstractFoDScanSetupCommand extends AbstractFoDJsonNodeOutputCommand implements IActionCommandResultSupplier { + @Getter private static final ObjectMapper objectMapper = new ObjectMapper(); + + private static final Log LOG = LogFactory.getLog(AbstractFoDScanSetupCommand.class); + + + @Mixin protected FoDDelimiterMixin delimiterMixin; // Is automatically injected in resolver mixins + @Mixin protected FoDReleaseByQualifiedNameOrIdResolverMixin.RequiredOption releaseResolver; + + @Option(names = {"--assessment-type"}, required = true) + protected String assessmentType; // Plain text name as custom assessment types can be created + @Mixin + protected FoDEntitlementFrequencyTypeMixins.RequiredOption entitlementFrequencyTypeMixin; + @Option(names = {"--entitlement-id"}) + protected Integer entitlementId = 0; + + @Mixin + protected CommonOptionMixins.OptionalFile uploadFileMixin; + + // the File Id previously uploaded or uploaded using "uploadFileToUse" below + private int fileId = 0; + + protected void setFileId(int fileId) { + this.fileId = fileId; + } + + protected int uploadFileToUse(UnirestInstance unirest, String releaseId, FoDScanType scanType, String fileType) { + int fileIdToUse = 0; + HttpRequest uploadFileRequest = null; + switch (scanType) { + case Dynamic: + // Only supporting DAST Automated file uploads from fcli for now + uploadFileRequest = getDastAutomatedUploadFileRequest(unirest, releaseId, fileType); + break; + case Static: + case Mobile: + // Neither Static or Mobile require any file uploads yet + break; + default: + } + JsonNode response = FoDFileTransferHelper.upload(unirest, uploadFileRequest, uploadFileMixin.getFile()); + fileIdToUse = response.get("fileId").intValue(); fileId = fileIdToUse; + return fileIdToUse; + } + + protected HttpRequest getDastAutomatedUploadFileRequest(UnirestInstance unirest, String releaseId, String dastFileType) { + return unirest.patch(FoDUrls.DAST_AUTOMATED_SCANS + "/scan-setup/file-upload") + .routeParam("relId", releaseId) + .queryString("dastFileType", dastFileType); + } + + @Override + public final JsonNode getJsonNode(UnirestInstance unirest) { + var releaseDescriptor = releaseResolver.getReleaseDescriptor(unirest); + var releaseId = releaseDescriptor.getReleaseId(); + HttpRequest request = getBaseRequest(unirest, releaseId); + HttpResponse response = request.asString(); // successful invocation returns empty response + return releaseDescriptor.asObjectNode() + .put("scanType", getScanType()) + .put("setupType", getSetupType()) + .put("filename", (uploadFileMixin.getFile() != null ? uploadFileMixin.getFile().getName() : "N/A")) + .put("entitlementId", entitlementId) + .put("fileId", fileId); + } + + protected abstract String getScanType(); + protected abstract String getSetupType(); + + protected abstract HttpRequest getBaseRequest(UnirestInstance unirest, String releaseId); + + @Override + public final String getActionCommandResult() { + return "SETUP"; + } + + @Override + public final boolean isSingular() { + return true; + } +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanStartCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanStartCommand.java index 32fd7415ee..591a354b87 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanStartCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanStartCommand.java @@ -25,7 +25,7 @@ import kong.unirest.UnirestInstance; import picocli.CommandLine.Mixin; -@CommandGroup("*-scan") +@CommandGroup("*-scan-start") public abstract class AbstractFoDScanStartCommand extends AbstractFoDJsonNodeOutputCommand implements IActionCommandResultSupplier { @Mixin private FoDDelimiterMixin delimiterMixin; // Is automatically injected in resolver mixins @Mixin private FoDReleaseByQualifiedNameOrIdResolverMixin.RequiredOption releaseResolver; diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/mixin/FoDDastFileTypeMixins.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/mixin/FoDDastFileTypeMixins.java new file mode 100644 index 0000000000..d4d027495c --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/mixin/FoDDastFileTypeMixins.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * 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._common.scan.cli.mixin; + +import com.fortify.cli.fod._common.util.FoDEnums; +import lombok.Getter; +import picocli.CommandLine.Option; + +public class FoDDastFileTypeMixins { + public static class RequiredOption { + @Option(names = {"--file-type", "--dast-file-type"}, required = true, descriptionKey = "fcli.fod.scan.dast-file-type") + @Getter private FoDEnums.DastAutomatedFileTypes dastFileType; + } + public static class OptionalOption { + @Option(names = {"--file-type", "--dast-file-type"}, required = false, descriptionKey = "fcli.fod.scan.dast-file-type") + @Getter private FoDEnums.DastAutomatedFileTypes dastFileType; + } +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/FoDFileUploadDescriptor.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/FoDFileUploadDescriptor.java new file mode 100644 index 0000000000..9811ac4069 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/FoDFileUploadDescriptor.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * 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._common.scan.helper; + +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 FoDFileUploadDescriptor extends JsonNodeHolder { + private String fileId; +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/FoDScanAssessmentTypeDescriptor.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/FoDScanAssessmentTypeDescriptor.java index c44274d29d..ae68f721e2 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/FoDScanAssessmentTypeDescriptor.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/FoDScanAssessmentTypeDescriptor.java @@ -14,15 +14,14 @@ package com.fortify.cli.fod._common.scan.helper; import com.formkiq.graalvm.annotations.Reflectable; -import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastDescriptor; +import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastLegacyDescriptor; import com.fortify.cli.fod.sast_scan.helper.FoDScanConfigSastDescriptor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.ToString; +import lombok.*; -@Reflectable @NoArgsConstructor +@Reflectable @NoArgsConstructor @AllArgsConstructor @Data @ToString +@Builder public class FoDScanAssessmentTypeDescriptor { private Integer assessmentTypeId; private String name; @@ -33,7 +32,7 @@ public class FoDScanAssessmentTypeDescriptor { private Integer frequencyTypeId; private String frequencyType; - public FoDScanAssessmentTypeDescriptor copyFromCurrentSetup(FoDScanConfigDastDescriptor curSetup) { + public FoDScanAssessmentTypeDescriptor copyFromCurrentSetup(FoDScanConfigDastLegacyDescriptor curSetup) { this.assessmentTypeId = curSetup.getAssessmentTypeId(); this.entitlementId = curSetup.getEntitlementId(); this.entitlementDescription = curSetup.getEntitlementDescription(); diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/FoDScanHelper.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/FoDScanHelper.java index 6e4e4ef66c..275a7d6fce 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/FoDScanHelper.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/FoDScanHelper.java @@ -13,39 +13,49 @@ package com.fortify.cli.fod._common.scan.helper; -import static java.util.function.Predicate.not; - -import java.util.Calendar; -import java.util.Optional; - import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fortify.cli.common.json.JsonHelper; +import com.fortify.cli.common.rest.unirest.UnexpectedHttpResponseException; import com.fortify.cli.fod._common.rest.FoDUrls; +import com.fortify.cli.fod._common.scan.helper.dast.*; +import com.fortify.cli.fod._common.util.FoDEnums; +import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastAutomatedDescriptor; +import com.fortify.cli.fod.release.helper.FoDReleaseAssessmentTypeDescriptor; +import com.fortify.cli.fod.release.helper.FoDReleaseAssessmentTypeHelper; import com.fortify.cli.fod.rest.lookup.helper.FoDLookupDescriptor; import com.fortify.cli.fod.rest.lookup.helper.FoDLookupHelper; import com.fortify.cli.fod.rest.lookup.helper.FoDLookupType; - import kong.unirest.HttpRequest; import kong.unirest.UnirestInstance; import lombok.Getter; +import lombok.SneakyThrows; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.BeanUtils; + +import java.util.*; + +import static java.util.function.Predicate.not; -// TODO Class contains some fairly long methods; consider splitting methods public class FoDScanHelper { @Getter private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final Log LOG = LogFactory.getLog(FoDScanHelper.class); + + // max retention period (in years) of FPRs public static int MAX_RETENTION_PERIOD = 2; public static final FoDScanDescriptor getScanDescriptor(UnirestInstance unirest, String scanId) { var result = unirest.get(FoDUrls.SCAN + "/summary") - .routeParam("scanId", scanId) - .asObject(ObjectNode.class) - .getBody(); + .routeParam("scanId", scanId) + .asObject(ObjectNode.class) + .getBody(); return getDescriptor(result); } @@ -90,20 +100,140 @@ public static void validateScanDate(FoDScanDescriptor scanDescriptor, int retent } } - // + public static FoDScanAssessmentTypeDescriptor getEntitlementToUse(UnirestInstance unirest, String relId, FoDScanType scanType, + String assessmentType, FoDEnums.EntitlementFrequencyType entitlementFrequencyType, + int entitlementId) { + FoDScanConfigDastAutomatedDescriptor currentSetup = null; + try { + currentSetup = FoDScanDastAutomatedHelper.getSetupDescriptor(unirest, relId); + } catch (UnexpectedHttpResponseException ex) { + // we have no current setup; + LOG.info("Unable to find current setup: " + ex); + } + Integer entitlementIdToUse = 0; + Integer assessmentTypeId = 0; + LOG.info("Finding/Validating entitlement to use."); + + // first find an appropriate assessment type to use + Optional atd = Arrays.stream( + FoDReleaseAssessmentTypeHelper.getAssessmentTypes(unirest, relId, scanType, entitlementFrequencyType, + false, true) + ).filter(n -> n.getName().equals(assessmentType)) + .findFirst(); + if (atd.isEmpty()) { + throw new IllegalArgumentException("Cannot find appropriate assessment type for specified options."); + } + assessmentTypeId = atd.get().getAssessmentTypeId(); + entitlementIdToUse = atd.get().getEntitlementId(); + + // validate entitlement specified or currently in use against assessment type found + if (entitlementId > 0) { + // check if "entitlement id" explicitly matches what has been found + if (!Objects.equals(entitlementIdToUse, entitlementId)) { + throw new IllegalArgumentException("Cannot appropriate assessment type for use with entitlement: " + entitlementId); + } + LOG.info("The 'entitlement-id' specified by user '" + entitlementId + "' is valid."); + } else { + if (currentSetup != null && (currentSetup.getEntitlementId() != null && currentSetup.getEntitlementId() > 0)) { + // check if "entitlement id" is already configured + if (!Objects.equals(entitlementIdToUse, currentSetup.getEntitlementId())) { + LOG.warn("Changing current release entitlement from '" + currentSetup.getEntitlementId() + "'."); + } + } + } + LOG.info("Configuring release to use entitlement '" + entitlementIdToUse + "'."); - private static final FoDScanDescriptor getDescriptor(JsonNode node) { - return JsonHelper.treeToValue(node, FoDScanDescriptor.class); - } + // check if the entitlement is still valid + FoDReleaseAssessmentTypeHelper.validateEntitlement(relId, atd.get()); + LOG.info("The entitlement '" + entitlementIdToUse + "' is still valid."); - private static final FoDScanDescriptor getEmptyDescriptor() { - return JsonHelper.treeToValue(getObjectMapper().createObjectNode(), FoDScanDescriptor.class); + return FoDScanAssessmentTypeDescriptor.builder() + .assessmentTypeId(assessmentTypeId) + .frequencyType(String.valueOf(FoDEnums.EntitlementFrequencyType.Subscription)) + .entitlementId(entitlementIdToUse) + .build(); } + public static final HttpRequest addDefaultScanListParams(HttpRequest request) { return request.queryString("orderBy", "startedDateTime") .queryString("orderByDirection", "DESC"); } + public static HttpRequest getPostmanSetupRequest(UnirestInstance unirest, String releaseId, + FoDScanDastAutomatedSetupBaseRequest base, + ArrayList collectionFileIds) { + FoDScanDastAutomatedSetupPostmanRequest setupRequest = FoDScanDastAutomatedSetupPostmanRequest.builder() + .collectionFileIds(collectionFileIds) + .build(); + BeanUtils.copyProperties(base, setupRequest); + + return unirest.put(FoDUrls.DAST_AUTOMATED_SCANS + "/postman-scan-setup") + .routeParam("relId", releaseId) + .body(setupRequest); + } + + @SneakyThrows + public static HttpRequest getOpenApiSetupRequest(UnirestInstance unirest, String releaseId, + FoDScanDastAutomatedSetupBaseRequest base, + Integer fileId, String apiUrl, String apiKey) { + boolean isUrl = (apiUrl != null && !apiUrl.isEmpty()); + int fileIdToUse = (fileId != null ? fileId : 0); + FoDScanDastAutomatedSetupOpenApiRequest setupRequest = FoDScanDastAutomatedSetupOpenApiRequest.builder() + .sourceType(isUrl ? "Url" : "FileId") + .sourceUrn(isUrl ? apiUrl : String.valueOf(fileIdToUse)) + .apiKey(apiKey) + .build(); + BeanUtils.copyProperties(base, setupRequest); + + return unirest.put(FoDUrls.DAST_AUTOMATED_SCANS + "/openapi-scan-setup") + .routeParam("relId", releaseId) + .body(setupRequest); + } + + public static HttpRequest getGraphQlSetupRequest(UnirestInstance unirest, String releaseId, + FoDScanDastAutomatedSetupBaseRequest base, + Integer fileId, String apiUrl, FoDEnums.ApiSchemeType schemeType, String host, String servicePath) { + boolean isUrl = (apiUrl != null && !apiUrl.isEmpty()); + int fileIdToUse = (fileId != null ? fileId : 0); + FoDScanDastAutomatedSetupGraphQlRequest setupRequest = FoDScanDastAutomatedSetupGraphQlRequest.builder() + .sourceType(isUrl ? "Url" : "FileId") + .sourceUrn(isUrl ? apiUrl : String.valueOf(fileIdToUse)) + .schemeType(schemeType) + .host(host) + .servicePath(servicePath) + .build(); + BeanUtils.copyProperties(base, setupRequest); + + return unirest.put(FoDUrls.DAST_AUTOMATED_SCANS + "/graphql-scan-setup") + .routeParam("relId", releaseId) + .body(setupRequest); + } + + public static HttpRequest getGrpcSetupRequest(UnirestInstance unirest, String releaseId, + FoDScanDastAutomatedSetupBaseRequest base, + Integer fileId, FoDEnums.ApiSchemeType schemeType, String host, String servicePath) { + FoDScanDastAutomatedSetupGrpcRequest setupRequest = FoDScanDastAutomatedSetupGrpcRequest.builder() + .fileId(fileId) + .schemeType(schemeType) + .host(host) + .servicePath(servicePath) + .build(); + BeanUtils.copyProperties(base, setupRequest); + + return unirest.put(FoDUrls.DAST_AUTOMATED_SCANS + "/grpc-scan-setup") + .routeParam("relId", releaseId) + .body(setupRequest); + } + + // + + private static final FoDScanDescriptor getDescriptor(JsonNode node) { + return JsonHelper.treeToValue(node, FoDScanDescriptor.class); + } + + private static final FoDScanDescriptor getEmptyDescriptor() { + return JsonHelper.treeToValue(getObjectMapper().createObjectNode(), FoDScanDescriptor.class); + } } diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedHelper.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedHelper.java new file mode 100644 index 0000000000..f5a1caf35f --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedHelper.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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._common.scan.helper.dast; + +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.fod._common.rest.FoDUrls; +import com.fortify.cli.fod._common.scan.helper.FoDScanDescriptor; +import com.fortify.cli.fod._common.scan.helper.FoDScanHelper; +import com.fortify.cli.fod._common.scan.helper.FoDScanType; +import com.fortify.cli.fod._common.scan.helper.FoDStartScanResponse; +import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastAutomatedDescriptor; +import com.fortify.cli.fod.release.helper.FoDReleaseDescriptor; +import kong.unirest.HttpRequest; +import kong.unirest.UnirestInstance; +import lombok.Getter; + +public class FoDScanDastAutomatedHelper extends FoDScanHelper { + @Getter + private static final ObjectMapper objectMapper = new ObjectMapper(); + + public static final FoDScanConfigDastAutomatedDescriptor getSetupDescriptor(UnirestInstance unirest, String relId) { + var body = unirest.get(FoDUrls.DAST_AUTOMATED_SCANS + "/scan-setup") + .routeParam("relId", relId) + .asObject(ObjectNode.class) + .getBody(); + return JsonHelper.treeToValue(body, FoDScanConfigDastAutomatedDescriptor.class); + } + + public static final FoDScanDescriptor startScan(UnirestInstance unirest, FoDReleaseDescriptor releaseDescriptor) { + JsonNode response = unirest.post(FoDUrls.DAST_AUTOMATED_SCANS + "/start-scan") + .routeParam("relId", releaseDescriptor.getReleaseId()) + .asObject(JsonNode.class).getBody(); + FoDStartScanResponse startScanResponse = JsonHelper.treeToValue(response, FoDStartScanResponse.class); + if (startScanResponse == null || startScanResponse.getScanId() <= 0) { + throw new RuntimeException("Unable to retrieve scan id from response when starting Dynamic scan."); + } + JsonNode node = objectMapper.createObjectNode() + .put("scanId", startScanResponse.getScanId()) + .put("scanType", FoDScanType.Dynamic.name()) + .put("analysisStatusType", "Pending") + .put("applicationName", releaseDescriptor.getApplicationName()) + .put("releaseName", releaseDescriptor.getReleaseName()) + .put("microserviceName", releaseDescriptor.getMicroserviceName()); + return JsonHelper.treeToValue(node, FoDScanDescriptor.class); + } +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupBaseRequest.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupBaseRequest.java new file mode 100644 index 0000000000..02345c867e --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupBaseRequest.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * 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._common.scan.helper.dast; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.formkiq.graalvm.annotations.Reflectable; +import com.fortify.cli.fod._common.util.FoDEnums; +import lombok.*; +import lombok.experimental.SuperBuilder; + +@Reflectable @NoArgsConstructor @AllArgsConstructor +@Data @SuperBuilder +@JsonInclude(JsonInclude.Include.NON_NULL) +public class FoDScanDastAutomatedSetupBaseRequest { + + @Reflectable @NoArgsConstructor @AllArgsConstructor + @Getter @ToString + public static class NetworkAuthenticationType { + FoDEnums.DynamicScanNetworkAuthenticationType networkAuthenticationType; + String userName; + String password; + } + + public Integer assessmentTypeId; + public Integer entitlementId; + public FoDEnums.EntitlementFrequencyType entitlementFrequencyType; // ['SingleScan', 'Subscription'] + @Builder.Default + public FoDEnums.DynamicScanEnvironmentFacingType dynamicScanEnvironmentFacingType = FoDEnums.DynamicScanEnvironmentFacingType.External; // ['Internal', 'External'] + @Builder.Default + public String timeZone = FoDEnums.TimeZones.UTC.name(); + @Builder.Default + public Boolean requiresNetworkAuthentication = false; + public NetworkAuthenticationType networkAuthenticationSettings; + private Integer timeBoxInHours; + @Builder.Default + private Boolean requestFalsePositiveRemoval = false; + +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupGraphQlRequest.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupGraphQlRequest.java new file mode 100644 index 0000000000..b01549d1c5 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupGraphQlRequest.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * 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._common.scan.helper.dast; + +import com.formkiq.graalvm.annotations.Reflectable; +import com.fortify.cli.fod._common.util.FoDEnums; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + + +@EqualsAndHashCode(callSuper = true) +@Reflectable @NoArgsConstructor @AllArgsConstructor +@Data @SuperBuilder +public class FoDScanDastAutomatedSetupGraphQlRequest extends FoDScanDastAutomatedSetupBaseRequest { + + public String sourceType; + public String sourceUrn; + public FoDEnums.ApiSchemeType schemeType; + public String host; + public String servicePath; + +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupGrpcRequest.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupGrpcRequest.java new file mode 100644 index 0000000000..e0f8317fe8 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupGrpcRequest.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * 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._common.scan.helper.dast; + +import com.formkiq.graalvm.annotations.Reflectable; +import com.fortify.cli.fod._common.util.FoDEnums; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + + +@EqualsAndHashCode(callSuper = true) +@Reflectable @NoArgsConstructor @AllArgsConstructor +@Data @SuperBuilder +public class FoDScanDastAutomatedSetupGrpcRequest extends FoDScanDastAutomatedSetupBaseRequest { + + public Integer fileId; + public FoDEnums.ApiSchemeType schemeType; + public String host; + public String servicePath; + +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupOpenApiRequest.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupOpenApiRequest.java new file mode 100644 index 0000000000..ce71e1386c --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupOpenApiRequest.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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._common.scan.helper.dast; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.formkiq.graalvm.annotations.Reflectable; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +@EqualsAndHashCode(callSuper = true) +@Reflectable @NoArgsConstructor @AllArgsConstructor +@Data @SuperBuilder +@JsonInclude(JsonInclude.Include.NON_NULL) +public class FoDScanDastAutomatedSetupOpenApiRequest extends FoDScanDastAutomatedSetupBaseRequest { + + public String sourceType; + public String sourceUrn; + public String apiKey; + +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupPostmanRequest.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupPostmanRequest.java new file mode 100644 index 0000000000..5351522f19 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupPostmanRequest.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * 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._common.scan.helper.dast; + +import com.formkiq.graalvm.annotations.Reflectable; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Reflectable @NoArgsConstructor @AllArgsConstructor +@Data @SuperBuilder +public class FoDScanDastAutomatedSetupPostmanRequest extends FoDScanDastAutomatedSetupBaseRequest { + public ArrayList collectionFileIds; +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupWebsiteRequest.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupWebsiteRequest.java new file mode 100644 index 0000000000..d8e868ab04 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupWebsiteRequest.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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._common.scan.helper.dast; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.formkiq.graalvm.annotations.Reflectable; +import com.fortify.cli.fod._common.util.FoDEnums; +import lombok.*; +import lombok.experimental.SuperBuilder; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Reflectable @NoArgsConstructor @AllArgsConstructor +@Data @SuperBuilder +@JsonInclude(JsonInclude.Include.NON_NULL) +public class FoDScanDastAutomatedSetupWebsiteRequest extends FoDScanDastAutomatedSetupBaseRequest { + + @Reflectable @NoArgsConstructor @AllArgsConstructor + @Getter @ToString + public static class Exclusion { + String value; + } + + @Reflectable @NoArgsConstructor @AllArgsConstructor + @Getter @ToString + public static class LoginMacroFileCreationType { + String primaryUsername; + String primaryPassword; + String secondaryUsername; + String secondaryPassword; + } + + @Builder.Default + private Boolean enableRedundantPageDetection = false; + @Builder.Default + public String policy = "Standard"; // ['Standard', 'Api', 'CriticalsAndHighs', 'PassiveScan'] + private String dynamicSiteUrl; + @Builder.Default + private Integer loginMacroFileId = 0; + @Builder.Default + private Boolean requiresSiteAuthentication = false; + private ArrayList exclusionsList; + @Builder.Default + private Boolean restrictToDirectoryAndSubdirectories = false; + @Builder.Default + private Boolean requestLoginMacroFileCreation = false; + private LoginMacroFileCreationType loginMacroFileCreationDetails; +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupWorkflowRequest.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupWorkflowRequest.java new file mode 100644 index 0000000000..bf93eed2b5 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastAutomatedSetupWorkflowRequest.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * 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._common.scan.helper.dast; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.formkiq.graalvm.annotations.Reflectable; +import com.fortify.cli.fod._common.util.FoDEnums; +import lombok.*; +import lombok.experimental.SuperBuilder; + +import java.util.ArrayList; + +@EqualsAndHashCode(callSuper = true) +@Reflectable @NoArgsConstructor @AllArgsConstructor +@Data @SuperBuilder +@JsonInclude(JsonInclude.Include.NON_NULL) +public class FoDScanDastAutomatedSetupWorkflowRequest extends FoDScanDastAutomatedSetupBaseRequest { + + @Reflectable @NoArgsConstructor @AllArgsConstructor + @Getter @ToString + public static class WorkflowDrivenMacro { + Integer fileId; + ArrayList allowedHosts; + } + + @Builder.Default + public String policy = "Standard"; // ['Standard', 'Api', 'CriticalsAndHighs', 'PassiveScan'] + public ArrayList workflowDrivenMacro; +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastHelper.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastLegacyHelper.java similarity index 91% rename from fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastHelper.java rename to fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastLegacyHelper.java index 07e1fe8a3a..f7b701fcd5 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastHelper.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastLegacyHelper.java @@ -1,13 +1,13 @@ /******************************************************************************* * 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 + * 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. *******************************************************************************/ @@ -27,7 +27,7 @@ import kong.unirest.UnirestInstance; import lombok.Getter; -public class FoDScanDastHelper extends FoDScanHelper { +public class FoDScanDastLegacyHelper extends FoDScanHelper { @Getter private static final ObjectMapper objectMapper = new ObjectMapper(); @@ -41,7 +41,7 @@ public class FoDScanDastHelper extends FoDScanHelper { return JsonHelper.treeToValue(response, FoDDastScanSetupDescriptor.class); }*/ - public static final FoDScanDescriptor startScan(UnirestInstance unirest, FoDReleaseDescriptor releaseDescriptor, FoDScanDastStartRequest startDastScanRequest) { + public static final FoDScanDescriptor startScan(UnirestInstance unirest, FoDReleaseDescriptor releaseDescriptor, FoDScanDastLegacyStartRequest startDastScanRequest) { ObjectNode body = objectMapper.valueToTree(startDastScanRequest); JsonNode response = unirest.post(FoDUrls.DYNAMIC_SCANS + "/start-scan") .routeParam("relId", releaseDescriptor.getReleaseId()) diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastStartRequest.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastLegacyStartRequest.java similarity index 97% rename from fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastStartRequest.java rename to fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastLegacyStartRequest.java index 4b77746c4a..9cf1582e71 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastStartRequest.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/helper/dast/FoDScanDastLegacyStartRequest.java @@ -24,7 +24,7 @@ @Reflectable @NoArgsConstructor @AllArgsConstructor @Getter @ToString @Builder -public class FoDScanDastStartRequest { +public class FoDScanDastLegacyStartRequest { @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM/dd/yyyy HH:mm") private String startDate; diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/util/FoDEnums.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/util/FoDEnums.java index 81adcd96d0..8d044f9483 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/util/FoDEnums.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/util/FoDEnums.java @@ -12,6 +12,8 @@ *******************************************************************************/ package com.fortify.cli.fod._common.util; +import com.fasterxml.jackson.annotation.JsonProperty; + // TODO Any good reason for having one big class defining many enums? Was this somehow generated from FoD? // TODO Are all these enums actually used? // TODO Maybe better to have top-level enums in the entity packages that use them, if applicable. @@ -410,7 +412,47 @@ public enum UserGroupMembershipAction { Add, Remove } + public enum DastAutomatedFileTypes { + OpenAPIDefinition, + PostmanCollection, + GraphQLDefinition, + GRPCDefinition, + WorkflowDrivenMacro, + LoginMacro + } + public enum DynamicScanNetworkAuthenticationType { + Basic, + NTLM, + Kerberos, + Digest, + Automatic, + ADFS_CBT + } + public enum DastAutomatedApiTypes { + OpenApi, + Postman, + GraphQL, + GRPC; + + public FoDEnums.DastAutomatedFileTypes getDastFileType() { + switch (this) { + case OpenApi -> { return DastAutomatedFileTypes.OpenAPIDefinition; } + case Postman -> { return DastAutomatedFileTypes.PostmanCollection; } + case GRPC -> { return DastAutomatedFileTypes.GRPCDefinition; } + case GraphQL -> { return DastAutomatedFileTypes.GraphQLDefinition; } + } + return null; + } + } + public enum ApiSchemeType { + @JsonProperty("http") + HTTP, + @JsonProperty("https") + HTTPS, + @JsonProperty("http,https") + HTTPandHTTPs; + } } diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanGetConfigCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanGetConfigCommand.java new file mode 100644 index 0000000000..cf75daee5e --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanGetConfigCommand.java @@ -0,0 +1,32 @@ +/** + * Copyright 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.dast_scan.cli.cmd; + +import com.fortify.cli.fod._common.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod._common.scan.cli.cmd.AbstractFoDScanConfigGetCommand; +import com.fortify.cli.fod._common.scan.helper.dast.FoDScanDastAutomatedHelper; +import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastAutomatedDescriptor; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; + +@Command(name = FoDOutputHelperMixins.GetConfig.CMD_NAME) +public class FoDDastAutomatedScanGetConfigCommand extends AbstractFoDScanConfigGetCommand { + @Getter @Mixin private FoDOutputHelperMixins.GetConfig outputHelper; + + @Override + protected FoDScanConfigDastAutomatedDescriptor getDescriptor(UnirestInstance unirest, String releaseId) { + return FoDScanDastAutomatedHelper.getSetupDescriptor(unirest, releaseId); + } +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanSetupApiCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanSetupApiCommand.java new file mode 100644 index 0000000000..706820456f --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanSetupApiCommand.java @@ -0,0 +1,138 @@ +/** + * Copyright 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.dast_scan.cli.cmd; + +import com.fortify.cli.common.cli.util.CommandGroup; +import com.fortify.cli.fod._common.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod._common.scan.cli.cmd.AbstractFoDScanSetupCommand; +import com.fortify.cli.fod._common.scan.helper.FoDScanAssessmentTypeDescriptor; +import com.fortify.cli.fod._common.scan.helper.FoDScanHelper; +import com.fortify.cli.fod._common.scan.helper.FoDScanType; +import com.fortify.cli.fod._common.scan.helper.dast.FoDScanDastAutomatedSetupBaseRequest; +import com.fortify.cli.fod._common.util.FoDEnums; +import kong.unirest.HttpRequest; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; +import picocli.CommandLine.Option; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +@Command(name = FoDOutputHelperMixins.SetupApi.CMD_NAME) @CommandGroup("*-scan-setup") +public class FoDDastAutomatedScanSetupApiCommand extends AbstractFoDScanSetupCommand { + @Getter @Mixin private FoDOutputHelperMixins.SetupWorkflow outputHelper; + + @Option(names={"--type"}, required = true) + private FoDEnums.DastAutomatedApiTypes apiType; + + @Option(names = {"--file-id"}) + private Integer fileId; + + @Option(names = {"--url", "--api-url"}) + private String apiUrl; + + @Option(names = {"--key", "--api-key"}) + private String apiKey; + @Option(names = {"--scheme-type"}) + private FoDEnums.ApiSchemeType apiSchemeType; + @Option(names = {"--host"}) + private String apiHost; + @Option(names = {"--service-path"}) + private String apiServicePath; + + @Option(names={"--environment"}, defaultValue = "External") + private FoDEnums.DynamicScanEnvironmentFacingType environmentFacingType; + @Option(names={"--timebox"}) + private Integer timebox; + @Option(names = {"--timezone"}) + private String timezone; + @Option(names = {"--network-auth-type"}) + private FoDEnums.DynamicScanNetworkAuthenticationType networkAuthenticationType; + @Option(names = {"-u", "--network-username"}) + private String username; + @Option(names = {"-p", "--network-password"}) + private String password; + @Option(names = {"--false-positive-removal"}) + private Boolean requestFalsePositiveRemoval; + + @Override + protected String getScanType() { + return "DAST Automated"; + } + @Override + protected String getSetupType() { + return "API"; + } + + @Override + protected HttpRequest getBaseRequest(UnirestInstance unirest, String releaseId) { + validate(); + + FoDEnums.DastAutomatedFileTypes dastFileType = apiType.getDastFileType(); + boolean requiresNetworkAuthentication = false; + Integer fileIdToUse = fileId; + + if (uploadFileMixin != null && uploadFileMixin.getFile() != null) { + fileIdToUse = uploadFileToUse(unirest, releaseId, FoDScanType.Dynamic, dastFileType.name()); + } + FoDScanDastAutomatedSetupBaseRequest.NetworkAuthenticationType networkAuthenticationSettings = null; + if (networkAuthenticationType != null) { + requiresNetworkAuthentication = true; + networkAuthenticationSettings = new FoDScanDastAutomatedSetupBaseRequest.NetworkAuthenticationType(networkAuthenticationType, username, password); + } + String timeZoneToUse = FoDScanHelper.validateTimezone(unirest, timezone); + + FoDScanAssessmentTypeDescriptor assessmentTypeDescriptor = FoDScanHelper.getEntitlementToUse(unirest, releaseId, FoDScanType.Dynamic, + assessmentType, entitlementFrequencyTypeMixin.getEntitlementFrequencyType(), entitlementId); + entitlementId = assessmentTypeDescriptor.getEntitlementId(); + + FoDScanDastAutomatedSetupBaseRequest setupBaseRequest = FoDScanDastAutomatedSetupBaseRequest.builder() + .dynamicScanEnvironmentFacingType(environmentFacingType != null ? + environmentFacingType : + FoDEnums.DynamicScanEnvironmentFacingType.Internal) + .requestFalsePositiveRemoval(requestFalsePositiveRemoval != null ? requestFalsePositiveRemoval : false) + .timeZone(timeZoneToUse) + .requiresNetworkAuthentication(requiresNetworkAuthentication) + .networkAuthenticationSettings(networkAuthenticationSettings) + .timeBoxInHours(timebox) + .assessmentTypeId(assessmentTypeDescriptor.getAssessmentTypeId()) + .entitlementId(entitlementId) + .entitlementFrequencyType(FoDEnums.EntitlementFrequencyType.valueOf(assessmentTypeDescriptor.getFrequencyType())) + .build(); + + if (apiType.equals(FoDEnums.DastAutomatedApiTypes.Postman)) { + ArrayList collectionFileIds = new ArrayList<>(Collections.singletonList(fileIdToUse)); + return FoDScanHelper.getPostmanSetupRequest(unirest, releaseId, setupBaseRequest, collectionFileIds); + } else if (apiType.equals(FoDEnums.DastAutomatedApiTypes.OpenApi)) { + return FoDScanHelper.getOpenApiSetupRequest(unirest, releaseId, setupBaseRequest, fileIdToUse, apiUrl, apiKey); + } else if (apiType.equals(FoDEnums.DastAutomatedApiTypes.GraphQL)) { + return FoDScanHelper.getGraphQlSetupRequest(unirest, releaseId, setupBaseRequest, fileIdToUse, apiUrl, apiSchemeType, apiHost, apiServicePath); + } else if (apiType.equals(FoDEnums.DastAutomatedApiTypes.GRPC)) { + return FoDScanHelper.getGrpcSetupRequest(unirest, releaseId, setupBaseRequest, fileIdToUse, apiSchemeType, apiHost, apiServicePath); + } else { + throw new IllegalArgumentException("Unexpected DAST Automated API type: " + apiType); + } + } + + private void validate() { + if (apiUrl != null && !apiUrl.isEmpty()) { + if (!apiUrl.matches("^https://.*")) { + throw new IllegalArgumentException("The 'apiUrl' option must include SSL with hostname."); + } + } + } + +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanSetupWebsiteCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanSetupWebsiteCommand.java new file mode 100644 index 0000000000..3decb4761d --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanSetupWebsiteCommand.java @@ -0,0 +1,148 @@ +/** + * Copyright 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.dast_scan.cli.cmd; + +import com.fortify.cli.common.cli.util.CommandGroup; +import com.fortify.cli.fod._common.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod._common.rest.FoDUrls; +import com.fortify.cli.fod._common.scan.cli.cmd.AbstractFoDScanSetupCommand; +import com.fortify.cli.fod._common.scan.helper.FoDScanAssessmentTypeDescriptor; +import com.fortify.cli.fod._common.scan.helper.FoDScanHelper; +import com.fortify.cli.fod._common.scan.helper.FoDScanType; +import com.fortify.cli.fod._common.scan.helper.dast.FoDScanDastAutomatedSetupWebsiteRequest; +import com.fortify.cli.fod._common.util.FoDEnums; +import kong.unirest.HttpRequest; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; +import picocli.CommandLine.Option; + +import java.util.ArrayList; +import java.util.Set; + +@Command(name = FoDOutputHelperMixins.SetupWebsite.CMD_NAME) @CommandGroup("*-scan-setup") +public class FoDDastAutomatedScanSetupWebsiteCommand extends AbstractFoDScanSetupCommand { + @Getter @Mixin private FoDOutputHelperMixins.SetupWebsite outputHelper; + private final static FoDEnums.DastAutomatedFileTypes dastFileType = FoDEnums.DastAutomatedFileTypes.LoginMacro; + + @Option(names = {"--url", "--site-url"}, required = true) + private String siteUrl; + @Option(names = {"--redundant-page-detection"}) + private Boolean redundantPageProtection; + @Option(names = {"--file-id"}) + private Integer loginMacroFileId; + @Option(names={"-e", "--exclusions"}, split=",") + private Set exclusions; + @Option(names={"--restrict"}) + private Boolean restrictToDirectoryAndSubdirectories; + @Option(names={"--policy"}, required = true, defaultValue = "Standard") + private String scanPolicy; + @Option(names={"--timebox"}) + private Integer timebox; + @Option(names={"--environment"}, defaultValue = "External") + private FoDEnums.DynamicScanEnvironmentFacingType environmentFacingType; + @Option(names = {"--timezone"}) + private String timezone; + @Option(names = {"--network-auth-type"}) + private FoDEnums.DynamicScanNetworkAuthenticationType networkAuthenticationType; + @Option(names = {"-u", "--network-username"}) + private String username; + @Option(names = {"-p", "--network-password"}) + private String password; + @Option(names = {"--false-positive-removal"}) + private Boolean requestFalsePositiveRemoval; + @Option(names = {"--create-login-macro"}) + private Boolean createLoginMacro; + @Option(names = {"--macro-primary-username"}) + private String macroPrimaryUsername; + @Option(names = {"--macro-primary-password"}) + private String macroPrimaryPassword; + @Option(names = {"--macro-secondary-username"}) + private String macroSecondaryUsername; + @Option(names = {"--macro-secondary-password"}) + private String macroSecondaryPassword; + + @Override + protected String getScanType() { + return "DAST Automated"; + } + @Override + protected String getSetupType() { + return "Website"; + } + + @Override + protected HttpRequest getBaseRequest(UnirestInstance unirest, String releaseId) { + boolean requiresSiteAuthentication = false; + boolean requiresNetworkAuthentication = false; + boolean requiresLoginMacroCreation = false; + int fileIdToUse = (loginMacroFileId != null ? loginMacroFileId : 0); + + if (loginMacroFileId != null && loginMacroFileId > 0) { + requiresSiteAuthentication = true; + } + if (uploadFileMixin != null && uploadFileMixin.getFile() != null) { + requiresSiteAuthentication = true; + fileIdToUse = uploadFileToUse(unirest, releaseId, FoDScanType.Dynamic, dastFileType.name()); + } + FoDScanDastAutomatedSetupWebsiteRequest.NetworkAuthenticationType networkAuthenticationSettings = null; + if (networkAuthenticationType != null) { + requiresNetworkAuthentication = true; + networkAuthenticationSettings = new FoDScanDastAutomatedSetupWebsiteRequest.NetworkAuthenticationType(networkAuthenticationType, username, password); + } + ArrayList exclusionsList = new ArrayList<>(); + if (exclusions != null && !exclusions.isEmpty()) { + for (String s: exclusions) { + exclusionsList.add(new FoDScanDastAutomatedSetupWebsiteRequest.Exclusion(s)); + } + } + String timeZoneToUse = FoDScanHelper.validateTimezone(unirest, timezone); + FoDScanDastAutomatedSetupWebsiteRequest.LoginMacroFileCreationType loginMacroFileCreationSettings = null; + if (createLoginMacro != null) { + requiresSiteAuthentication = true; + requiresLoginMacroCreation = createLoginMacro; + loginMacroFileCreationSettings = new FoDScanDastAutomatedSetupWebsiteRequest.LoginMacroFileCreationType(macroPrimaryUsername, + macroPrimaryPassword, macroSecondaryUsername, macroSecondaryPassword); + } + + FoDScanAssessmentTypeDescriptor assessmentTypeDescriptor = FoDScanHelper.getEntitlementToUse(unirest, releaseId, FoDScanType.Dynamic, + assessmentType, entitlementFrequencyTypeMixin.getEntitlementFrequencyType(), entitlementId); + entitlementId = assessmentTypeDescriptor.getEntitlementId(); + FoDScanDastAutomatedSetupWebsiteRequest setupRequest = FoDScanDastAutomatedSetupWebsiteRequest.builder() + .dynamicSiteUrl(siteUrl) + .enableRedundantPageDetection(redundantPageProtection != null ? redundantPageProtection : false) + .requiresSiteAuthentication(requiresSiteAuthentication) + .loginMacroFileId(fileIdToUse) + .exclusionsList(exclusionsList) + .restrictToDirectoryAndSubdirectories(restrictToDirectoryAndSubdirectories != null ? restrictToDirectoryAndSubdirectories : false) + .policy(scanPolicy) + .timeBoxInHours(timebox) + .dynamicScanEnvironmentFacingType(environmentFacingType != null ? environmentFacingType : FoDEnums.DynamicScanEnvironmentFacingType.Internal) + .timeZone(timeZoneToUse) + .requiresNetworkAuthentication(requiresNetworkAuthentication) + .networkAuthenticationSettings(networkAuthenticationSettings) + .assessmentTypeId(assessmentTypeDescriptor.getAssessmentTypeId()) + .entitlementId(entitlementId) + .entitlementFrequencyType(FoDEnums.EntitlementFrequencyType.valueOf(assessmentTypeDescriptor.getFrequencyType())) + .requestFalsePositiveRemoval(requestFalsePositiveRemoval != null ? requestFalsePositiveRemoval : false) + .requestLoginMacroFileCreation(requiresLoginMacroCreation) + .loginMacroFileCreationDetails(loginMacroFileCreationSettings) + .build(); + + return unirest.put(FoDUrls.DAST_AUTOMATED_SCANS + "/website-scan-setup") + .routeParam("relId", releaseId) + .body(setupRequest); + } + +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanSetupWorkflowCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanSetupWorkflowCommand.java new file mode 100644 index 0000000000..938008d5bc --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanSetupWorkflowCommand.java @@ -0,0 +1,128 @@ +/** + * Copyright 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.dast_scan.cli.cmd; + +import com.fortify.cli.common.cli.util.CommandGroup; +import com.fortify.cli.fod._common.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod._common.rest.FoDUrls; +import com.fortify.cli.fod._common.scan.cli.cmd.AbstractFoDScanSetupCommand; +import com.fortify.cli.fod._common.scan.helper.FoDScanAssessmentTypeDescriptor; +import com.fortify.cli.fod._common.scan.helper.FoDScanHelper; +import com.fortify.cli.fod._common.scan.helper.FoDScanType; +import com.fortify.cli.fod._common.scan.helper.dast.FoDScanDastAutomatedSetupWorkflowRequest; +import com.fortify.cli.fod._common.util.FoDEnums; +import kong.unirest.HttpRequest; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; +import picocli.CommandLine.Option; + +import java.util.ArrayList; + +@Command(name = FoDOutputHelperMixins.SetupWorkflow.CMD_NAME) @CommandGroup("*-scan-setup") +public class FoDDastAutomatedScanSetupWorkflowCommand extends AbstractFoDScanSetupCommand { + @Getter @Mixin private FoDOutputHelperMixins.SetupWorkflow outputHelper; + + private final static FoDEnums.DastAutomatedFileTypes dastFileType = FoDEnums.DastAutomatedFileTypes.WorkflowDrivenMacro; + + @Option(names={"--hosts", "--allowed-hosts"}, split=",") + private ArrayList allowedHosts; + @Option(names = {"--file-id"}) + private Integer workflowMacroFileId; + @Option(names={"--policy"}, required = true, defaultValue = "Standard") + private String scanPolicy; + @Option(names={"--environment"}, defaultValue = "External") + private FoDEnums.DynamicScanEnvironmentFacingType environmentFacingType; + @Option(names = {"--timezone"}) + private String timezone; + @Option(names = {"--network-auth-type"}) + private FoDEnums.DynamicScanNetworkAuthenticationType networkAuthenticationType; + @Option(names = {"-u", "--network-username"}) + private String username; + @Option(names = {"-p", "--network-password"}) + private String password; + @Option(names = {"--false-positive-removal"}) + private Boolean requestFalsePositiveRemoval; + + @Override + protected String getScanType() { + return "DAST Automated"; + } + @Override + protected String getSetupType() { + return "Workflow"; + } + + @Override + protected HttpRequest getBaseRequest(UnirestInstance unirest, String releaseId) { + validate(); + + boolean requiresNetworkAuthentication = false; + Integer fileIdToUse = workflowMacroFileId; + + if (uploadFileMixin != null && uploadFileMixin.getFile() != null) { + fileIdToUse = uploadFileToUse(unirest, releaseId, FoDScanType.Dynamic, dastFileType.name()); + } + ArrayList workflowDrivenMacros = new ArrayList<>(); + FoDScanDastAutomatedSetupWorkflowRequest.WorkflowDrivenMacro workflowDrivenMacro = + new FoDScanDastAutomatedSetupWorkflowRequest.WorkflowDrivenMacro(fileIdToUse, allowedHosts); + workflowDrivenMacros.add(workflowDrivenMacro); + FoDScanDastAutomatedSetupWorkflowRequest.NetworkAuthenticationType networkAuthenticationSettings = null; + if (networkAuthenticationType != null) { + requiresNetworkAuthentication = true; + networkAuthenticationSettings = new FoDScanDastAutomatedSetupWorkflowRequest.NetworkAuthenticationType(networkAuthenticationType, username, password); + } + String timeZoneToUse = FoDScanHelper.validateTimezone(unirest, timezone); + + FoDScanAssessmentTypeDescriptor assessmentTypeDescriptor = FoDScanHelper.getEntitlementToUse(unirest, releaseId, FoDScanType.Dynamic, + assessmentType, entitlementFrequencyTypeMixin.getEntitlementFrequencyType(), entitlementId); + entitlementId = assessmentTypeDescriptor.getEntitlementId(); + FoDScanDastAutomatedSetupWorkflowRequest setupRequest = FoDScanDastAutomatedSetupWorkflowRequest.builder() + .workflowDrivenMacro(workflowDrivenMacros) + .policy(scanPolicy) + .dynamicScanEnvironmentFacingType(environmentFacingType != null ? environmentFacingType : FoDEnums.DynamicScanEnvironmentFacingType.Internal) + .timeZone(timeZoneToUse) + .requiresNetworkAuthentication(requiresNetworkAuthentication) + .networkAuthenticationSettings(networkAuthenticationSettings) + .assessmentTypeId(assessmentTypeDescriptor.getAssessmentTypeId()) + .entitlementId(entitlementId) + .entitlementFrequencyType(FoDEnums.EntitlementFrequencyType.valueOf(assessmentTypeDescriptor.getFrequencyType())) + .requestFalsePositiveRemoval(requestFalsePositiveRemoval != null ? requestFalsePositiveRemoval : false) + .build(); + + return unirest.put(FoDUrls.DAST_AUTOMATED_SCANS + "/workflow-scan-setup") + .routeParam("relId", releaseId) + .body(setupRequest); + } + + private void validate() { + // check we have a valid workflow file + if (uploadFileMixin == null || uploadFileMixin.getFile() == null) { + throw new IllegalArgumentException("A valid workflow macro file needs to be provided."); + } else { + if (allowedHosts == null || allowedHosts.isEmpty()) { + throw new IllegalArgumentException("Please specify at least one '--allowed-hosts'."); + } + } + // check allowed hosts is valid + if (allowedHosts != null && !allowedHosts.isEmpty()) { + allowedHosts.forEach((h) -> { + if (h.matches("^https?://.*")) { + throw new IllegalArgumentException("The 'allowedHosts' options should not include 'http://' or 'https://'."); + } + }); + } + } + +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanStartCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanStartCommand.java new file mode 100644 index 0000000000..88bb4ecbce --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastAutomatedScanStartCommand.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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.dast_scan.cli.cmd; + +import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.common.rest.unirest.UnexpectedHttpResponseException; +import com.fortify.cli.fod._common.scan.cli.cmd.AbstractFoDScanStartCommand; +import com.fortify.cli.fod._common.scan.helper.FoDScanDescriptor; +import com.fortify.cli.fod._common.scan.helper.dast.FoDScanDastAutomatedHelper; +import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastAutomatedDescriptor; +import com.fortify.cli.fod.release.helper.FoDReleaseDescriptor; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; + +@Command(name = OutputHelperMixins.Start.CMD_NAME) +public class FoDDastAutomatedScanStartCommand extends AbstractFoDScanStartCommand { + @Getter @Mixin private OutputHelperMixins.Start outputHelper; + + @Override + protected FoDScanDescriptor startScan(UnirestInstance unirest, FoDReleaseDescriptor releaseDescriptor) { + String relId = releaseDescriptor.getReleaseId(); + + // get current setup to ensure the scan has been configured + FoDScanConfigDastAutomatedDescriptor currentSetup = FoDScanDastAutomatedHelper.getSetupDescriptor(unirest, relId); + + return FoDScanDastAutomatedHelper.startScan(unirest, releaseDescriptor); + } +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanGetConfigLegacyCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastLegacyScanGetConfigCommand.java similarity index 66% rename from fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanGetConfigLegacyCommand.java rename to fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastLegacyScanGetConfigCommand.java index 279736e3b2..2257d1f687 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanGetConfigLegacyCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastLegacyScanGetConfigCommand.java @@ -14,8 +14,8 @@ import com.fortify.cli.fod._common.output.mixin.FoDOutputHelperMixins; import com.fortify.cli.fod._common.scan.cli.cmd.AbstractFoDScanConfigGetCommand; -import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastDescriptor; -import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastHelper; +import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastLegacyDescriptor; +import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastLegacyHelper; import kong.unirest.UnirestInstance; import lombok.Getter; @@ -23,11 +23,11 @@ import picocli.CommandLine.Mixin; @Command(name = FoDOutputHelperMixins.GetConfigLegacy.CMD_NAME, hidden = true) -public class FoDDastScanGetConfigLegacyCommand extends AbstractFoDScanConfigGetCommand { - @Getter @Mixin private FoDOutputHelperMixins.GetConfig outputHelper; +public class FoDDastLegacyScanGetConfigCommand extends AbstractFoDScanConfigGetCommand { + @Getter @Mixin private FoDOutputHelperMixins.GetConfigLegacy outputHelper; @Override - protected FoDScanConfigDastDescriptor getDescriptor(UnirestInstance unirest, String releaseId) { - return FoDScanConfigDastHelper.getSetupDescriptor(unirest, releaseId); + protected FoDScanConfigDastLegacyDescriptor getDescriptor(UnirestInstance unirest, String releaseId) { + return FoDScanConfigDastLegacyHelper.getSetupDescriptor(unirest, releaseId); } } diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanStartLegacyCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastLegacyScanStartCommand.java similarity index 90% rename from fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanStartLegacyCommand.java rename to fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastLegacyScanStartCommand.java index eba636df1e..7cf59e3b3f 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanStartLegacyCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastLegacyScanStartCommand.java @@ -20,6 +20,7 @@ import java.util.Optional; import java.util.Properties; +import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastLegacyHelper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -33,11 +34,10 @@ import com.fortify.cli.fod._common.scan.cli.mixin.FoDRemediationScanPreferenceTypeMixins; import com.fortify.cli.fod._common.scan.helper.FoDScanDescriptor; import com.fortify.cli.fod._common.scan.helper.FoDScanType; -import com.fortify.cli.fod._common.scan.helper.dast.FoDScanDastHelper; -import com.fortify.cli.fod._common.scan.helper.dast.FoDScanDastStartRequest; +import com.fortify.cli.fod._common.scan.helper.dast.FoDScanDastLegacyHelper; +import com.fortify.cli.fod._common.scan.helper.dast.FoDScanDastLegacyStartRequest; import com.fortify.cli.fod._common.util.FoDEnums; -import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastDescriptor; -import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastHelper; +import com.fortify.cli.fod.dast_scan.helper.FoDScanConfigDastLegacyDescriptor; import com.fortify.cli.fod.release.helper.FoDReleaseAssessmentTypeDescriptor; import com.fortify.cli.fod.release.helper.FoDReleaseAssessmentTypeHelper; import com.fortify.cli.fod.release.helper.FoDReleaseDescriptor; @@ -49,8 +49,8 @@ import picocli.CommandLine.Option; @Command(name = FoDOutputHelperMixins.StartLegacy.CMD_NAME, hidden = true) -public class FoDDastScanStartLegacyCommand extends AbstractFoDScanStartCommand { - private static final Log LOG = LogFactory.getLog(FoDDastScanStartLegacyCommand.class); +public class FoDDastLegacyScanStartCommand extends AbstractFoDScanStartCommand { + private static final Log LOG = LogFactory.getLog(FoDDastLegacyScanStartCommand.class); DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm"); @Getter @Mixin private OutputHelperMixins.Start outputHelper; @@ -73,7 +73,7 @@ public class FoDDastScanStartLegacyCommand extends AbstractFoDScanStartCommand { private FoDEntitlementFrequencyTypeMixins.RequiredOption entitlementFrequencyTypeMixin; @Mixin private ProgressWriterFactoryMixin progressWriterFactory; - + @Override protected FoDScanDescriptor startScan(UnirestInstance unirest, FoDReleaseDescriptor releaseDescriptor) { try ( var progressWriter = progressWriterFactory.create() ) { @@ -92,7 +92,7 @@ protected FoDScanDescriptor startScan(UnirestInstance unirest, FoDReleaseDescrip } // get current setup - FoDScanConfigDastDescriptor currentSetup = FoDScanConfigDastHelper.getSetupDescriptor(unirest, relId); + FoDScanConfigDastLegacyDescriptor currentSetup = FoDScanConfigDastLegacyHelper.getSetupDescriptor(unirest, relId); if (currentSetup.getAssessmentTypeId() == null || currentSetup.getAssessmentTypeId() <= 0) { throw new IllegalStateException("The dynamic scan configuration for release with id '" + relId + "' has not been setup correctly - 'Assessment Type' is missing or empty."); @@ -137,7 +137,7 @@ protected FoDScanDescriptor startScan(UnirestInstance unirest, FoDReleaseDescrip String startDateStr = (startDate == null || startDate.isEmpty()) ? LocalDateTime.now().format(dtf) : LocalDateTime.parse(startDate, dtf).toString(); - FoDScanDastStartRequest startScanRequest = FoDScanDastStartRequest.builder() + FoDScanDastLegacyStartRequest startScanRequest = FoDScanDastLegacyStartRequest.builder() .startDate(startDateStr) .assessmentTypeId(assessmentTypeId) .entitlementId(entitlementIdToUse) @@ -149,7 +149,7 @@ protected FoDScanDescriptor startScan(UnirestInstance unirest, FoDReleaseDescrip .scanToolVersion(fcliProperties.getProperty("projectVersion", "unknown")).build(); //System.out.println(startScanRequest); - return FoDScanDastHelper.startScan(unirest, releaseDescriptor, startScanRequest); + return FoDScanDastLegacyHelper.startScan(unirest, releaseDescriptor, startScanRequest); } } } diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanCommands.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanCommands.java index fa596be8a1..df5683ffc7 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanCommands.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanCommands.java @@ -24,12 +24,17 @@ FoDDastScanDownloadCommand.class, FoDDastScanDownloadLatestCommand.class, FoDDastScanGetCommand.class, - FoDDastScanGetConfigLegacyCommand.class, + FoDDastLegacyScanGetConfigCommand.class, FoDDastScanImportCommand.class, FoDDastScanListCommand.class, - //FoDDastScanSetupCommand.class, - FoDDastScanStartLegacyCommand.class, + FoDDastAutomatedScanSetupWebsiteCommand.class, + FoDDastAutomatedScanSetupWorkflowCommand.class, + FoDDastAutomatedScanSetupApiCommand.class, + FoDDastAutomatedScanGetConfigCommand.class, + FoDDastAutomatedScanStartCommand.class, + FoDDastLegacyScanStartCommand.class, FoDDastScanWaitForCommand.class, + FoDDastScanFileUploadCommand.class } ) @DefaultVariablePropertyName("scanId") diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanFileUploadCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanFileUploadCommand.java new file mode 100644 index 0000000000..c55df66372 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/cli/cmd/FoDDastScanFileUploadCommand.java @@ -0,0 +1,43 @@ +/** + * Copyright 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.dast_scan.cli.cmd; + +import com.fortify.cli.fod._common.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod._common.rest.FoDUrls; +import com.fortify.cli.fod._common.scan.cli.cmd.AbstractFoDScanFileUploadCommand; +import com.fortify.cli.fod._common.scan.cli.mixin.FoDDastFileTypeMixins; +import kong.unirest.HttpRequest; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; + +@Command(name = FoDOutputHelperMixins.UploadFile.CMD_NAME) +public class FoDDastScanFileUploadCommand extends AbstractFoDScanFileUploadCommand { + @Getter @Mixin private FoDOutputHelperMixins.UploadFile outputHelper; + + @Mixin private FoDDastFileTypeMixins.RequiredOption dastFileType; + + @Override + protected String getFileType() { + return dastFileType.getDastFileType().name(); + } + + @Override + protected HttpRequest getBaseRequest(UnirestInstance unirest, String releaseId) { + return unirest.patch(FoDUrls.DAST_AUTOMATED_SCANS + "/scan-setup/file-upload") + .routeParam("relId", releaseId) + .queryString("dastFileType", getFileType()); + } + +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastAutomatedDescriptor.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastAutomatedDescriptor.java new file mode 100644 index 0000000000..2cdc60f022 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastAutomatedDescriptor.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * 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.dast_scan.helper; + +import com.formkiq.graalvm.annotations.Reflectable; +import com.fortify.cli.common.json.JsonNodeHolder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Reflectable @NoArgsConstructor +@Data @ToString +@EqualsAndHashCode(callSuper=false) +public class FoDScanConfigDastAutomatedDescriptor extends JsonNodeHolder { + private Integer assessmentTypeId; + private Integer entitlementId; + private String entitlementFrequencyType; + private String scanType; +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastDescriptor.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastLegacyDescriptor.java similarity index 94% rename from fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastDescriptor.java rename to fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastLegacyDescriptor.java index e243e1dd2d..a249bd4469 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastDescriptor.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastLegacyDescriptor.java @@ -24,7 +24,7 @@ @Reflectable @NoArgsConstructor @Data @ToString @EqualsAndHashCode(callSuper=false) -public class FoDScanConfigDastDescriptor extends JsonNodeHolder { +public class FoDScanConfigDastLegacyDescriptor extends JsonNodeHolder { private Integer assessmentTypeId; private Integer entitlementId; private String entitlementDescription; diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastHelper.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastLegacyHelper.java similarity index 81% rename from fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastHelper.java rename to fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastLegacyHelper.java index f6130f9ee5..17ca1f9819 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastHelper.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastLegacyHelper.java @@ -19,12 +19,12 @@ import kong.unirest.UnirestInstance; -public class FoDScanConfigDastHelper { - public static final FoDScanConfigDastDescriptor getSetupDescriptor(UnirestInstance unirest, String relId) { +public class FoDScanConfigDastLegacyHelper { + public static final FoDScanConfigDastLegacyDescriptor getSetupDescriptor(UnirestInstance unirest, String relId) { var body = unirest.get(FoDUrls.DYNAMIC_SCANS + "/scan-setup") .routeParam("relId", relId) .asObject(ObjectNode.class) .getBody(); - return JsonHelper.treeToValue(body, FoDScanConfigDastDescriptor.class); + return JsonHelper.treeToValue(body, FoDScanConfigDastLegacyDescriptor.class); } } diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastSetupRequest.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastLegacySetupRequest.java similarity index 98% rename from fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastSetupRequest.java rename to fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastLegacySetupRequest.java index 6232f29311..8a4fa309b2 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastSetupRequest.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/dast_scan/helper/FoDScanConfigDastLegacySetupRequest.java @@ -26,7 +26,7 @@ @Reflectable @NoArgsConstructor @AllArgsConstructor @Getter @ToString @Builder -public class FoDScanConfigDastSetupRequest { +public class FoDScanConfigDastLegacySetupRequest { @Reflectable @NoArgsConstructor @Getter @ToString diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/oss_scan/cli/cmd/FoDOssScanDownloadLatestCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/oss_scan/cli/cmd/FoDOssScanDownloadLatestCommand.java index 9a395dfaa3..d338464bfe 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/oss_scan/cli/cmd/FoDOssScanDownloadLatestCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/oss_scan/cli/cmd/FoDOssScanDownloadLatestCommand.java @@ -1,13 +1,13 @@ /** * Copyright 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 + * 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.oss_scan.cli.cmd; @@ -27,13 +27,13 @@ @Command(name = FoDOutputHelperMixins.DownloadLatest.CMD_NAME) public class FoDOssScanDownloadLatestCommand extends AbstractFoDScanDownloadLatestCommand { @Getter @Mixin private FoDOutputHelperMixins.DownloadLatest outputHelper; - + @Override protected GetRequest getDownloadRequest(UnirestInstance unirest, FoDReleaseDescriptor releaseDescriptor, FoDScanDescriptor scanDescriptor) { return unirest.get("/api/v3/open-source-scans/{scanId}/sbom") .routeParam("scanId", scanDescriptor.getScanId()); } - + @Override protected FoDScanType getScanType() { return FoDScanType.OpenSource; diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/helper/FoDReleaseAssessmentTypeHelper.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/helper/FoDReleaseAssessmentTypeHelper.java index 14c131db8b..c1de4d1e1c 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/helper/FoDReleaseAssessmentTypeHelper.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/helper/FoDReleaseAssessmentTypeHelper.java @@ -61,15 +61,15 @@ public final static void validateEntitlement(String relId, throw new IllegalStateException("Invalid or empty FODAssessmentTypeDescriptor."); } // check entitlement has not expired - if (atd.getSubscriptionEndDate() == null || + if (atd.getSubscriptionEndDate() != null && atd.getSubscriptionEndDate().before(Date.from(Instant.now()))) { LOG.debug("Current Date: " + Date.from(Instant.now()).toString()); LOG.debug("Subscription End Date: " + atd.getSubscriptionEndDate()); - LOG.warn("Warning: the entitlement has expired."); + LOG.debug("Warning: the entitlement has expired."); } // warn if all units are consumed or not enough for "new" scan if (atd.getUnitsAvailable() == 0) { - LOG.warn("Warning: all units of the entitlement have been consumed."); + LOG.debug("Warning: all units of the entitlement have been consumed."); } } } diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/rest/lookup/helper/FoDLookupType.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/rest/lookup/helper/FoDLookupType.java index dfc1010778..09d8fb8910 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/rest/lookup/helper/FoDLookupType.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/rest/lookup/helper/FoDLookupType.java @@ -1,61 +1,64 @@ /** * Copyright 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 + * 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.rest.lookup.helper; public enum FoDLookupType { All, - MobileScanPlatformTypes, - MobileScanFrameworkTypes, - MobileScanEnvironmentTypes, - MobileScanRoleTypes, - MobileScanExternalDeviceTypes, - DynamicScanEnvironmentFacingTypes, - DynamicScanAuthenticationTypes, - TimeZones, - RepeatScheduleTypes, - GeoLocations, - SDLCStatusTypes, - DayOfWeekTypes, - BusinessCriticalityTypes, - ReportTemplateTypes, AnalysisStatusTypes, - ScanStatusTypes, - ReportFormats, - Roles, - ScanPreferenceTypes, - AuditPreferenceTypes, - EntitlementFrequencyTypes, ApplicationTypes, - ScanTypes, - AttributeTypes, + AssessmentTypes, AttributeDataTypes, - MultiFactorAuthorizationTypes, - ReportTypes, - ReportStatusTypes, - PassFailReasonTypes, - DynamicScanWebServiceTypes, - VulnerabilitySeverityTypes, - TechnologyTypes, - LanguageLevels, + AttributeTypes, AuditActionTypes, - NotificationTriggerTypes, + AuditPreferenceTypes, + AuditTemplateConditionTypes, + BusinessCriticalityTypes, ConcurrentRequestThreadsTypes, - MobileScanAuditPreferenceTypes, + DastAutomatedScanPolicies, + DastAutomatedScanTypes, DataExportTypes, + DayOfWeekTypes, + DynamicMobileScanTypeAuditTemplateFieldTypes, + DynamicScanAuthenticationTypes, + DynamicScanEnvironmentFacingTypes, + DynamicScanWebServiceTypes, + EntitlementFrequencyTypes, + GeoLocations, + LanguageLevels, + MobileScanAuditPreferenceTypes, + MobileScanEnvironmentTypes, + MobileScanExternalDeviceTypes, + MobileScanFrameworkTypes, + MobileScanPlatformTypes, + MobileScanRoleTypes, + MultiFactorAuthorizationTypes, + NotificationTriggerTypes, + OpenSourceScanTypeAuditTemplateFieldTypes, + PassFailReasonTypes, + RepeatScheduleTypes, + ReportFormats, + ReportStatusTypes, + ReportTemplateTypes, + ReportTypes, + Roles, + SDLCStatusTypes, ScanMethodTypes, + ScanPreferenceTypes, + ScanStatusTypes, + ScanTypes, StartScanMethodTypes, - AuditTemplateConditionTypes, - OpenSourceScanTypeAuditTemplateFieldTypes, StaticScanTypeAuditTemplateFieldTypes, - DynamicMobileScanTypeAuditTemplateFieldTypes -} \ No newline at end of file + TechnologyTypes, + TimeZones, + VulnerabilitySeverityTypes +} diff --git a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/i18n/FoDMessages.properties b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/i18n/FoDMessages.properties index 17fb96ab45..020931067f 100644 --- a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/i18n/FoDMessages.properties +++ b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/i18n/FoDMessages.properties @@ -48,6 +48,7 @@ fcli.fod.group.group-name-or-id = Group id or name. Note that numeric values are fcli.fod.filters-param = Server-side queries are automatically generated from the -q / --query option if possible; \ generated queries can be viewed in the debug log. The --q-param option can be used to override the automatically generated query, \ for example to further optimize the request. See the Fortify on Demand REST API documentation for information on supported formats. +fcli.fod.scan.dast-file-type = The type of DAST Automated file to upload. Valid values: ${COMPLETION-CANDIDATES}. fcli.fod.report.report-id = Report id(s). fcli.fod.report.report-template.name-or-id = Report template name or id. @@ -78,6 +79,9 @@ output.header.performOpenSourceAnalysis = OSS Analysis output.header.dynamicSiteURL = Website URL output.header.webServiceType = Webservice Type output.header.importScanSessionId = Import Id +output.header.fileId = File Id +output.header.fileType = File Type +output.header.filename = File Name ### fcli fod session fcli.fod.session.usage.header = Manage FoD sessions (start here). @@ -384,7 +388,7 @@ fcli.fod.sast-scan.setup.usage.description.0 = This command is not fully impleme any workflows in which this command is being used. fcli.fod.sast-scan.setup.usage.description.1 = To correctly setup a scan you will need to provide the name of the \ assessment type using the '--assessment-type=xxx' option. Since assessment types can potentially be configured \ - differently for each tenant, you can find the correct name using the 'fod release list-assessment-types' command. + differently for each tenant, you can find the correct name using the 'fod rest lookup AssessmentTypes' command. fcli.fod.sast-scan.setup.usage.description.2 = If you know the Id of an entitlement that you want to use then you \ can supply it to the '--entitlement-id=xxx' option. If not, you can supply both '--assessment-type' and \ '--entitlement-frequency' options and the command will try to find an appropriate entitlement. @@ -424,6 +428,11 @@ fcli.fod.dast-scan.output.header.microserviceName = Microservice fcli.fod.dast-scan.output.header.releaseName = Release fcli.fod.dast-scan.cancel.usage.header = (PREVIEW) Cancel a DAST scan. fcli.fod.dast-scan.get.usage.header = (PREVIEW) Get DAST scan details. +fcli.fod.dast-scan.get-config.usage.header = (PREVIEW) Get current DAST Automated scan configuration. +fcli.fod.dast-scan.get-config.usage.description = This command is intended for DAST Automated scanning. \ + Please note: DAST Automated scanning is still in technical preview and therefore, command name, options and \ + behavior may change at any time, even between patch or minor releases, potentially affecting any workflows in \ + which this command is being used. fcli.fod.dast-scan.get-config-legacy.usage.header = (LEGACY) Get current DAST scan configuration. fcli.fod.dast-scan.get-config-legacy.usage.description = This command is intended for legacy DAST scanning (not DAST Automated). \ Command name, options and behavior may change at any time, even between patch or minor releases, potentially affecting \ @@ -438,6 +447,13 @@ fcli.fod.dast-scan.wait-for.usage.description.2 = ${fcli.fod.scan.states:-See fc fcli.fod.dast-scan.wait-for.until = ${fcli.fod.scan.wait-for.until} fcli.fod.dast-scan.wait-for.while = ${fcli.fod.scan.wait-for.while} fcli.fod.dast-scan.wait-for.any-state = ${fcli.fod.scan.wait-for.any-state} +fcli.fod.dast-scan.start.usage.header = (PREVIEW) Start a new DAST Automated scan. +fcli.fod.dast-scan.start.usage.description.0 = This command is intended for DAST Automated scanning. \ + Please note: DAST Automated scanning is still in technical preview and therefore, command name, options and \ + behavior may change at any time, even between patch or minor releases, potentially affecting any workflows in \ + which this command is being used. +fcli.fod.dast-scan.start.usage.description.1 = The scan will need to have been previously setup using the FoD UI or one of the \ + 'fod dast-scan setup-xxx' commands. fcli.fod.dast-scan.start-legacy.usage.header = (LEGACY) Start a new DAST scan. fcli.fod.dast-scan.start-legacy.usage.description.0 = This command is not fully implemented and is intended for legacy DAST scanning (not DAST Automated). \ It can only be used for starting a configured Dynamic scan and does not support file uploads (i.e. API definitions \ @@ -448,13 +464,13 @@ fcli.fod.dast-scan.start-legacy.usage.description.1 = The scan will need to have 'fod dast-scan setup' command. fcli.fod.dast-scan.start-legacy.usage.description.2 = To correctly start a scan you will need to provide the name of the \ assessment type using the '--assessment-type=xxx' option. Since assessment types can potentially be configured \ - differently for each tenant, you can find the correct name using the 'fod release list-assessment-types --scan-types=Dynamic' command. + differently for each tenant, you can find the correct name using the 'fod rest lookup AssessmentTypes' command. fcli.fod.dast-scan.start-legacy.usage.description.3 = The scan will need to have been previously setup using the FoD UI or the \ 'fod dast-scan setup' command. fcli.fod.dast-scan.start-legacy.usage.description.4 = If you know the Id of an entitlement that you want to use then you \ can supply it to the '--entitlement-id=xxx' option. If not, you can supply both '--assessment-type' and \ '--entitlement-frequency' options and the command will try to find an appropriate entitlement. -fcli.fod.dast-scan.start-legacy.assessment-type = The type of Dynamic assessment to carry out. Use 'release list-assessment-types' to find valid values. +fcli.fod.dast-scan.start-legacy.assessment-type = The type of Dynamic assessment to carry out. Use 'fod rest lookup AssessmentTypes' to find valid values. fcli.fod.dast-scan.start-legacy.start-date = ${fcli.fod.sast-scan.start.start-date} fcli.fod.dast-scan.start-legacy.entitlement-id = ${fcli.fod.sast-scan.start.entitlement-id} fcli.fod.dast-scan.start-legacy.notes = ${fcli.fod.sast-scan.start.notes} @@ -468,6 +484,99 @@ fcli.fod.dast-scan.download.usage.header = Download scan results. fcli.fod.dast-scan.download.file = File path and name where to save the FPR file. fcli.fod.dast-scan.download-latest.usage.header = Download latest scan results from release. fcli.fod.dast-scan.download-latest.file = File path and name where to save the FPR file. +fcli.fod.dast-scan.upload-file.usage.header = (PREVIEW) Uploads a file for use with DAST Automated scans. +fcli.fod.dast-scan.upload-file.file = File path and name of file to upload. +fcli.fod.dast-scan.upload-file.dastFileType = The type of DAST Automated file to upload. + +fcli.fod.dast-scan.setup-website.usage.header = (PREVIEW) Configure DAST Automated Website scan for the release. +fcli.fod.dast-scan.setup-workflow.usage.header = (PREVIEW) Configure DAST Automated Workflow scan for the release. +fcli.fod.dast-scan.setup-api.usage.header = (PREVIEW) Configure DAST Automated API scan for the release. + +fcli.fod.dast-scan.setup-website.usage.description.0 = This command is intended for preview only. \ + Command name, options and behavior may change at any time, even between patch or minor releases, potentially affecting \ + any workflows in which this command is being used. +fcli.fod.dast-scan.setup-website.usage.description.1 = To correctly setup a scan you will need to provide the name of the \ + assessment type using the '--assessment-type=xxx' option. Since assessment types can potentially be configured \ + differently for each tenant, you can find the correct name using the 'fod rest lookup AssessmentTypes' command. +fcli.fod.dast-scan.setup-website.usage.description.2 = If you know the Id of an entitlement that you want to use then you \ + can supply it to the '--entitlement-id=xxx' option. If not, you can supply both '--assessment-type' and \ + '--entitlement-frequency' options and the command will try to find an appropriate entitlement. +fcli.fod.dast-scan.setup-website.usage.description.3 = If you wish to use a Login Macro for authentication then you \ + can upload it directly using the '--file' option, or you can refer to a previously uploaded File Id that was uploaded \ + using the 'fod dast-scan upload-file' command. +fcli.fod.dast-scan.setup-workflow.usage.description.0 = ${fcli.fod.dast-scan.setup-website.usage.description.0} +fcli.fod.dast-scan.setup-api.usage.description.0 = ${fcli.fod.dast-scan.setup-website.usage.description.0} +fcli.fod.dast-scan.setup-workflow.usage.description.1 = ${fcli.fod.dast-scan.setup-website.usage.description.1} +fcli.fod.dast-scan.setup-api.usage.description.1 = ${fcli.fod.dast-scan.setup-website.usage.description.1} +fcli.fod.dast-scan.setup-workflow.usage.description.2 = ${fcli.fod.dast-scan.setup-website.usage.description.2} +fcli.fod.dast-scan.setup-api.usage.description.2 = ${fcli.fod.dast-scan.setup-website.usage.description.2} +fcli.fod.dast-scan.setup-workflow.usage.description.3 = In order to use a Workflow Macro you can upload it directly \ + using the '--file' option, or you can refer to a previously uploaded File Id that was uploaded using the \ + 'fod dast-scan upload-file' command. +fcli.fod.dast-scan.setup-api.usage.description.3 = In order to use an OpenAPI specification, Postman collection, \ + GraphQL schema file or GRPC proto file, you can upload it directly using the '--file' option, or you can refer to \ + a previously uploaded File Id that was uploaded using the 'fod dast-scan upload-file' command. + +fcli.fod.dast-scan.setup-website.file = A Login Macro file to upload and use for authentication in the website scan. +fcli.fod.dast-scan.setup-website.entitlement-id = Entitlement Id to use. If not specified Frequency and Assessment Type will be used to find one. +fcli.fod.dast-scan.setup-website.assessment-type = The type of DAST assessment to carry out. Use 'fod rest lookup AssessmentTypes' to display valid values. +fcli.fod.dast-scan.setup-website-setup-scan.entitlement-frequency = The Entitlement Frequency to use. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.dast-scan.setup-website.site-url = The URL of the website to be scanned. This cannot be changed after a scan has been completed on the release. +fcli.fod.dast-scan.setup-website.redundant-page-detection = Enable redundant page detection. +fcli.fod.dast-scan.setup-website.file-id = The file Id of a Login Macro previously uploaded using the 'fod dast-scan upload-file' command. +fcli.fod.dast-scan.setup-website.exclusions = A comma separated list of URLs to exclude from being scanned. +fcli.fod.dast-scan.setup-website.restrict = Restrict the scan to the URL directory and subdirectories. If not selected then the entire host will be scanned. +fcli.fod.dast-scan.setup-website.policy = The Scan Policy to use. Use 'fod rest lookup DastAutomatedScanPolicies' to display valid values. +fcli.fod.dast-scan.setup-website.timebox = Timebox for the scan duration (in hours). +fcli.fod.dast-scan.setup-website.environment = The public facing visibility of the environment. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.dast-scan.setup-website.timezone = The timezone in which the website is running in. +fcli.fod.dast-scan.setup-website.network-auth-type = The Network Authentication type to use. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.dast-scan.setup-website.network-username = The Network Username to use. +fcli.fod.dast-scan.setup-website.network-password = The Network Password to use. +fcli.fod.dast-scan.setup-website.false-positive-removal = Request false positive removal by the testing team (once per application). +fcli.fod.dast-scan.setup-website.create-login-macro = Request generation of a login macro by the testing team (once per application). +fcli.fod.dast-scan.setup-website.macro-primary-username = Login macro username for the primary user. +fcli.fod.dast-scan.setup-website.macro-primary-password = Login macro password for the primary user. +fcli.fod.dast-scan.setup-website.macro-secondary-username = Login macro username for the secondary user. +fcli.fod.dast-scan.setup-website.macro-secondary-password = Login macro password for the secondary user. + +fcli.fod.dast-scan.setup-workflow.file = A Workflow file to upload and use for authentication in the website scan. +fcli.fod.dast-scan.setup-workflow.allowed-hosts = The FQDN and port of any hosts that that you want to be scanned, e.g. "test.mysite.com:443". +fcli.fod.dast-scan.setup-workflow.entitlement-id = ${fcli.fod.dast-scan.setup-website.entitlement-id} +fcli.fod.dast-scan.setup-workflow.assessment-type = ${fcli.fod.dast-scan.setup-website.assessment-type} +fcli.fod.dast-scan.setup-workflow-setup-scan.entitlement-frequency = The Entitlement Frequency to use. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.dast-scan.setup-workflow.redundant-page-detection = ${fcli.fod.dast-scan.setup-website.redundant-page-detection} +fcli.fod.dast-scan.setup-workflow.file-id = The Id of a file previously uploaded using the 'fod dast-scan upload-file' command. +fcli.fod.dast-scan.setup-workflow.policy = ${fcli.fod.dast-scan.setup-website.policy} +fcli.fod.dast-scan.setup-workflow.timebox = ${fcli.fod.dast-scan.setup-website.timebox} +fcli.fod.dast-scan.setup-workflow.environment = The public facing visibility of the environment. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.dast-scan.setup-workflow.timezone = ${fcli.fod.dast-scan.setup-website.timezone} +fcli.fod.dast-scan.setup-workflow.network-auth-type = The Network Authentication type to use. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.dast-scan.setup-workflow.network-username = ${fcli.fod.dast-scan.setup-website.network-username} +fcli.fod.dast-scan.setup-workflow.network-password = ${fcli.fod.dast-scan.setup-website.network-password} +fcli.fod.dast-scan.setup-workflow.false-positive-removal = ${fcli.fod.dast-scan.setup-website.false-positive-removal} + +fcli.fod.dast-scan.setup-api.type = The type of API to scan. Valid Values: ${COMPLETION-CANDIDATES} +fcli.fod.dast-scan.setup-api.file = An OpenAPI specification, Postman collection, GraphQL schema file or GRPC proto file. +fcli.fod.dast-scan.setup-api.url = The URL to the API definition file. +fcli.fod.dast-scan.setup-api.key = API Key to use for authentication. +fcli.fod.dast-scan.setup-api.scheme-type = API Scheme Type. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.dast-scan.setup-api.host = API Host. +fcli.fod.dast-scan.setup-api.service-path = API Service Path. +fcli.fod.dast-scan.setup-api.allowed-hosts = The FQDN and port of any hosts that that you want to be scanned, e.g. "test.mysite.com:443". +fcli.fod.dast-scan.setup-api.entitlement-id = ${fcli.fod.dast-scan.setup-website.entitlement-id} +fcli.fod.dast-scan.setup-api.assessment-type = ${fcli.fod.dast-scan.setup-website.assessment-type} +fcli.fod.dast-scan.setup-api-setup-scan.entitlement-frequency = The Entitlement Frequency to use. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.dast-scan.setup-api.redundant-page-detection = ${fcli.fod.dast-scan.setup-website.redundant-page-detection} +fcli.fod.dast-scan.setup-api.file-id = The file Id of a Workflow Macro previously uploaded using the 'fod dast-scan upload-file' command. +fcli.fod.dast-scan.setup-api.policy = ${fcli.fod.dast-scan.setup-website.policy} +fcli.fod.dast-scan.setup-api.timebox = ${fcli.fod.dast-scan.setup-website.timebox} +fcli.fod.dast-scan.setup-api.environment = The public facing visibility of the environment. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.dast-scan.setup-api.timezone = ${fcli.fod.dast-scan.setup-website.timezone} +fcli.fod.dast-scan.setup-api.network-auth-type = The Network Authentication type to use. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.dast-scan.setup-api.network-username = ${fcli.fod.dast-scan.setup-website.network-username} +fcli.fod.dast-scan.setup-api.network-password = ${fcli.fod.dast-scan.setup-website.network-password} +fcli.fod.dast-scan.setup-api.false-positive-removal = ${fcli.fod.dast-scan.setup-website.false-positive-removal} ### For the "fod mast-scan" command ### fcli.fod.mast-scan.usage.header = Manage FoD MAST scans. @@ -505,14 +614,14 @@ fcli.fod.mast-scan.start.usage.description.1 = The scan will need to have been p 'fod mast-scan setup' command. fcli.fod.mast-scan.start.usage.description.2 = To correctly start a scan you will need to provide the name of the \ assessment type using the '--assessment-type=xxx' option. Since assessment types can potentially be configured \ - differently for each tenant, you can find the correct name using the 'fod release list-assessment-types --scan-types=Mobile' command. + differently for each tenant, you can find the correct name using the 'fod rest lookup AssessmentTypes' command. fcli.fod.mast-scan.start.usage.description.3 = The scan will need to have been previously setup using the FoD UI or the \ 'fod dast-scan setup' command. fcli.fod.mast-scan.start.usage.description.4 = If you know the Id of an entitlement that you want to use then you \ can supply it to the '--entitlement-id=xxx' option. If not, you can supply both '--assessment-type' and \ '--entitlement-frequency' options and the command will try to find an appropriate entitlement. fcli.fod.mast-scan.start.start-date = ${fcli.fod.sast-scan.start.start-date} -fcli.fod.mast-scan.start.assessment-type = The type of MAST assessment to carry out. Use 'release list-assessment-types' to find valid values. +fcli.fod.mast-scan.start.assessment-type = The type of MAST assessment to carry out. Use 'fod rest lookup AssessmentTypes' to find valid values. fcli.fod.mast-scan.start.entitlement-id = ${fcli.fod.sast-scan.start.entitlement-id} fcli.fod.mast-scan.start.entitlement-frequency = The Entitlement Frequency to use. Valid values: ${COMPLETION-CANDIDATES}. fcli.fod.mast-scan.start.notes = ${fcli.fod.sast-scan.start.notes} @@ -633,7 +742,9 @@ fcli.fod.*-scan.output.table.options = scanId,analysisStatusType,applicationName fcli.fod.*-scan-import.output.table.options = importScanSessionId,applicationName,microserviceName,releaseName,scanType fcli.fod.*-scan-download.output.table.options = scanId,scanType,file fcli.fod.*-scan-config.output.table.options = applicationName,microserviceName,releaseName,entitlementId,status -fcli.fod.*-scan-setup.output.table.options = applicationName,microserviceName,releaseName,entitlementId,scanType +fcli.fod.*-scan-setup.output.table.options = scanType,setupType,fileId,filename,applicationName,microserviceName,releaseName,entitlementId +fcli.fod.*-scan-start.output.table.options = scanId,scanType,analysisStatusType,applicationName,microserviceName,releaseName +fcli.fod.*-scan-upload-file.output.table.options = fileId,fileType,filename,applicationName,microserviceName,releaseName fcli.fod.session.output.table.options = name,type,url,created,expires,expired fcli.fod.rest.lookup.output.table.options = group,text,value fcli.fod.report.output.table.options = reportId,reportName,reportStatusType,reportType