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 index 16189414ab..84b644a283 100644 --- 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 @@ -51,5 +51,5 @@ public static class NetworkAuthenticationType { private Integer timeBoxInHours; @Builder.Default private Boolean requestFalsePositiveRemoval = false; - + private String networkName; // FoDConnect Network Name } diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/mixin/FoDSdlcStatusTypeOptions.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/mixin/FoDSdlcStatusTypeOptions.java index 32a609538f..644784928c 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/mixin/FoDSdlcStatusTypeOptions.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/mixin/FoDSdlcStatusTypeOptions.java @@ -21,7 +21,7 @@ //TODO Enum case? See comments in FoDAppTypeOptions public class FoDSdlcStatusTypeOptions { - public enum FoDSdlcStatusType {Development, QA, Production} + public enum FoDSdlcStatusType {Development, QA, Production, Retired} public static final class FoDSdlcStatusTypeIterable extends ArrayList<String> { private static final long serialVersionUID = 1L; 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 index 2e63473ad5..6efb0e184d 100644 --- 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 @@ -67,6 +67,8 @@ public class FoDDastAutomatedScanSetupApiCommand extends AbstractFoDScanSetupCom private String password; @Option(names = {"--false-positive-removal"}) private Boolean requestFalsePositiveRemoval; + @Option(names = {"--vpn"}) + private String fodConnectNetwork; @Override protected String getScanType() { @@ -94,11 +96,14 @@ protected HttpRequest<?> getBaseRequest(UnirestInstance unirest, String releaseI networkAuthenticationSettings = new FoDScanDastAutomatedSetupBaseRequest.NetworkAuthenticationType(networkAuthenticationType, username, password); } String timeZoneToUse = FoDScanHelper.validateTimezone(unirest, timezone); - + if (fodConnectNetwork != null) { + // if Fortify Connect network site override environmentFacingType to Internal + environmentFacingType = FoDEnums.DynamicScanEnvironmentFacingType.Internal; + } + FoDScanAssessmentTypeDescriptor assessmentTypeDescriptor = FoDScanHelper.getEntitlementToUse(unirest, releaseId, FoDScanType.Dynamic, assessmentType, entitlementFrequencyTypeMixin.getEntitlementFrequencyType(), entitlementId); entitlementId = assessmentTypeDescriptor.getEntitlementId(); - FoDScanDastAutomatedSetupBaseRequest setupBaseRequest = FoDScanDastAutomatedSetupBaseRequest.builder() .dynamicScanEnvironmentFacingType(environmentFacingType != null ? environmentFacingType : @@ -111,6 +116,7 @@ protected HttpRequest<?> getBaseRequest(UnirestInstance unirest, String releaseI .assessmentTypeId(assessmentTypeDescriptor.getAssessmentTypeId()) .entitlementId(entitlementId) .entitlementFrequencyType(FoDEnums.EntitlementFrequencyType.valueOf(assessmentTypeDescriptor.getFrequencyType())) + .networkName(fodConnectNetwork != null ? fodConnectNetwork : "") .build(); if (apiType.equals(FoDEnums.DastAutomatedApiTypes.Postman)) { 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 index 0e1402ceff..f435d773b7 100644 --- 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 @@ -73,6 +73,8 @@ public class FoDDastAutomatedScanSetupWebsiteCommand extends AbstractFoDScanSetu private String macroSecondaryUsername; @Option(names = {"--macro-secondary-password"}) private String macroSecondaryPassword; + @Option(names = {"--vpn"}) + private String fodConnectNetwork; @Override protected String getScanType() { @@ -116,6 +118,10 @@ protected HttpRequest<?> getBaseRequest(UnirestInstance unirest, String releaseI loginMacroFileCreationSettings = new FoDScanDastAutomatedSetupWebsiteRequest.LoginMacroFileCreationType(macroPrimaryUsername, macroPrimaryPassword, macroSecondaryUsername, macroSecondaryPassword); } + if (fodConnectNetwork != null) { + // if Fortify Connect network site override environmentFacingType to Internal + environmentFacingType = FoDEnums.DynamicScanEnvironmentFacingType.Internal; + } FoDScanAssessmentTypeDescriptor assessmentTypeDescriptor = FoDScanHelper.getEntitlementToUse(unirest, releaseId, FoDScanType.Dynamic, assessmentType, entitlementFrequencyTypeMixin.getEntitlementFrequencyType(), entitlementId); @@ -129,7 +135,7 @@ protected HttpRequest<?> getBaseRequest(UnirestInstance unirest, String releaseI .restrictToDirectoryAndSubdirectories(restrictToDirectoryAndSubdirectories != null ? restrictToDirectoryAndSubdirectories : false) .policy(scanPolicy) .timeBoxInHours(timebox) - .dynamicScanEnvironmentFacingType(environmentFacingType != null ? environmentFacingType : FoDEnums.DynamicScanEnvironmentFacingType.Internal) + .dynamicScanEnvironmentFacingType(environmentFacingType != null ? environmentFacingType : FoDEnums.DynamicScanEnvironmentFacingType.External) .timeZone(timeZoneToUse) .requiresNetworkAuthentication(requiresNetworkAuthentication) .networkAuthenticationSettings(networkAuthenticationSettings) @@ -139,6 +145,7 @@ protected HttpRequest<?> getBaseRequest(UnirestInstance unirest, String releaseI .requestFalsePositiveRemoval(requestFalsePositiveRemoval != null ? requestFalsePositiveRemoval : false) .requestLoginMacroFileCreation(requiresLoginMacroCreation) .loginMacroFileCreationDetails(loginMacroFileCreationSettings) + .networkName(fodConnectNetwork != null ? fodConnectNetwork : "") .build(); return unirest.put(FoDUrls.DAST_AUTOMATED_SCANS + "/website-scan-setup") 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 index 55fcb13874..1d47e919cb 100644 --- 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 @@ -55,6 +55,8 @@ public class FoDDastAutomatedScanSetupWorkflowCommand extends AbstractFoDScanSet private String password; @Option(names = {"--false-positive-removal"}) private Boolean requestFalsePositiveRemoval; + @Option(names = {"--vpn"}) + private String fodConnectNetwork; @Override protected String getScanType() { @@ -85,7 +87,11 @@ protected HttpRequest<?> getBaseRequest(UnirestInstance unirest, String releaseI networkAuthenticationSettings = new FoDScanDastAutomatedSetupWorkflowRequest.NetworkAuthenticationType(networkAuthenticationType, username, password); } String timeZoneToUse = FoDScanHelper.validateTimezone(unirest, timezone); - + if (fodConnectNetwork != null) { + // if Fortify Connect network site override environmentFacingType to Internal + environmentFacingType = FoDEnums.DynamicScanEnvironmentFacingType.Internal; + } + FoDScanAssessmentTypeDescriptor assessmentTypeDescriptor = FoDScanHelper.getEntitlementToUse(unirest, releaseId, FoDScanType.Dynamic, assessmentType, entitlementFrequencyTypeMixin.getEntitlementFrequencyType(), entitlementId); entitlementId = assessmentTypeDescriptor.getEntitlementId(); @@ -100,6 +106,7 @@ protected HttpRequest<?> getBaseRequest(UnirestInstance unirest, String releaseI .entitlementId(entitlementId) .entitlementFrequencyType(FoDEnums.EntitlementFrequencyType.valueOf(assessmentTypeDescriptor.getFrequencyType())) .requestFalsePositiveRemoval(requestFalsePositiveRemoval != null ? requestFalsePositiveRemoval : false) + .networkName(fodConnectNetwork != null ? fodConnectNetwork : "") .build(); return unirest.put(FoDUrls.DAST_AUTOMATED_SCANS + "/workflow-scan-setup") diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/cli/cmd/FoDMastScanCommands.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/cli/cmd/FoDMastScanCommands.java index 908de6d1c4..a789109431 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/cli/cmd/FoDMastScanCommands.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/cli/cmd/FoDMastScanCommands.java @@ -27,7 +27,7 @@ FoDMastScanGetConfigCommand.class, FoDMastScanImportCommand.class, FoDMastScanListCommand.class, - //FoDMastScanSetupCommand.class, + FoDMastScanSetupCommand.class, FoDMastScanStartCommand.class, FoDMastScanWaitForCommand.class, } diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/cli/cmd/FoDMastScanSetupCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/cli/cmd/FoDMastScanSetupCommand.java new file mode 100644 index 0000000000..123ac7c29c --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/cli/cmd/FoDMastScanSetupCommand.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * 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.mast_scan.cli.cmd; + +import java.time.format.DateTimeFormatter; +import java.util.Objects; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fortify.cli.common.cli.util.CommandGroup; +import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.common.output.transform.IActionCommandResultSupplier; +import com.fortify.cli.common.output.transform.IRecordTransformer; +import com.fortify.cli.common.progress.cli.mixin.ProgressWriterFactoryMixin; +import com.fortify.cli.common.util.DisableTest; +import com.fortify.cli.common.util.DisableTest.TestType; +import com.fortify.cli.fod._common.cli.mixin.FoDDelimiterMixin; +import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDJsonNodeOutputCommand; +import com.fortify.cli.fod._common.scan.cli.mixin.FoDEntitlementFrequencyTypeMixins; +import com.fortify.cli.fod._common.scan.helper.FoDScanType; +import com.fortify.cli.fod.release.cli.mixin.FoDReleaseByQualifiedNameOrIdResolverMixin; +import com.fortify.cli.fod.release.helper.FoDReleaseAssessmentTypeDescriptor; +import com.fortify.cli.fod.release.helper.FoDReleaseAssessmentTypeHelper; +import com.fortify.cli.fod.release.helper.FoDReleaseDescriptor; +import com.fortify.cli.fod.mast_scan.helper.FoDScanConfigMobileDescriptor; +import com.fortify.cli.fod.mast_scan.helper.FoDScanConfigMobileHelper; +import com.fortify.cli.fod.mast_scan.helper.FoDScanConfigMobileSetupRequest; + +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; +import picocli.CommandLine.Option; + +@Command(name = OutputHelperMixins.Setup.CMD_NAME, hidden = false) @CommandGroup("*-scan-setup") +@DisableTest(TestType.CMD_DEFAULT_TABLE_OPTIONS_PRESENT) +public class FoDMastScanSetupCommand extends AbstractFoDJsonNodeOutputCommand implements IRecordTransformer, IActionCommandResultSupplier { + private static final Log LOG = LogFactory.getLog(FoDMastScanStartCommand.class); + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm"); + @Getter @Mixin private OutputHelperMixins.Start outputHelper; + + @Mixin + private FoDDelimiterMixin delimiterMixin; // Is automatically injected in resolver mixins + @Mixin + private FoDReleaseByQualifiedNameOrIdResolverMixin.RequiredOption releaseResolver; + + @Option(names = {"--assessment-type"}, required = true) + private String mobileAssessmentType; // Plain text name as custom assessment types can be created + @Option(names = {"--entitlement-id"}) + private Integer entitlementId; + @Mixin private FoDEntitlementFrequencyTypeMixins.RequiredOption entitlementFrequencyTypeMixin; + private enum MobileFrameworks { iOS, Android } + @Option(names = {"--framework"}, required = true) + private MobileFrameworks mobileFramework; + @Option(names = {"--timezone"}, defaultValue = "UTC") + private String timezone; + private enum MobileAuditPreferenceTypes { Manual, None } + @Option(names = {"--audit-preference"}, defaultValue = "None") + private MobileAuditPreferenceTypes auditPreferenceType; + private enum MobilePlatforms { Phone, Tablet, Both } + @Option(names = {"--platform"}, required = true) + private MobilePlatforms mobilePlatform; + @Option(names={"--skip-if-exists"}) + private Boolean skipIfExists = false; + + @Mixin private ProgressWriterFactoryMixin progressWriterFactory; + + @Override + public JsonNode getJsonNode(UnirestInstance unirest) { + try (var progressWriter = progressWriterFactory.create()) { + var releaseDescriptor = releaseResolver.getReleaseDescriptor(unirest); + var setupDescriptor = FoDScanConfigMobileHelper.getSetupDescriptor(unirest, releaseDescriptor.getReleaseId()); + if ( skipIfExists && setupDescriptor.getAssessmentTypeId()!=0 ) { + return setupDescriptor.asObjectNode().put("__action__", "SKIPPED_EXISTING"); + } else { + return setup(unirest, releaseDescriptor, setupDescriptor).asObjectNode(); + } + } + } + + private FoDScanConfigMobileDescriptor setup(UnirestInstance unirest, FoDReleaseDescriptor releaseDescriptor, FoDScanConfigMobileDescriptor currentSetup) { + var relId = releaseDescriptor.getReleaseId(); + + LOG.info("Finding appropriate entitlement to use."); + + var atd = FoDReleaseAssessmentTypeHelper.getAssessmentTypeDescriptor(unirest, relId, FoDScanType.Mobile, + entitlementFrequencyTypeMixin.getEntitlementFrequencyType(), mobileAssessmentType); + Integer assessmentTypeId = atd.getAssessmentTypeId(); + Integer entitlementIdToUse = atd.getEntitlementId(); + + validateEntitlement(currentSetup, entitlementIdToUse, relId, atd); + LOG.info("Release will be usig entitlement " + entitlementIdToUse); + + FoDScanConfigMobileSetupRequest setupMastScanRequest = FoDScanConfigMobileSetupRequest.builder() + .assessmentTypeId(assessmentTypeId) + .frameworkType(mobileFramework.name()) + .platformType(mobilePlatform.name()) + .auditPreferenceType(auditPreferenceType.name()) + .timeZone(timezone).build(); + + return FoDScanConfigMobileHelper.setupScan(unirest, releaseDescriptor, setupMastScanRequest); + } + + private void validateEntitlement(FoDScanConfigMobileDescriptor currentSetup, Integer entitlementIdToUse, String relId, FoDReleaseAssessmentTypeDescriptor atd) { + // validate entitlement specified or currently in use against assessment type found + if (entitlementId != null && entitlementId > 0) { + // check if "entitlement id" explicitly matches what has been found + if (!Objects.equals(entitlementIdToUse, entitlementId)) { + throw new IllegalArgumentException("Cannot find appropriate assessment type for use with entitlement: " + entitlementId + "=" + entitlementIdToUse); + } + } else { + if (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()); + } + } + } + // check if the entitlement is still valid + FoDReleaseAssessmentTypeHelper.validateEntitlement(relId, atd); + } + + @Override + public JsonNode transformRecord(JsonNode record) { + FoDReleaseDescriptor releaseDescriptor = releaseResolver.getReleaseDescriptor(getUnirestInstance()); + return ((ObjectNode)record) + .put("scanType", mobileAssessmentType) + .put("setupType", auditPreferenceType.name()) + .put("applicationName", releaseDescriptor.getApplicationName()) + .put("releaseName", releaseDescriptor.getReleaseName()) + .put("microserviceName", releaseDescriptor.getMicroserviceName()); + } + + @Override + public String getActionCommandResult() { + return "SETUP"; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/helper/FoDScanConfigMobileHelper.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/helper/FoDScanConfigMobileHelper.java index c68906c194..c2942ed3cc 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/helper/FoDScanConfigMobileHelper.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/helper/FoDScanConfigMobileHelper.java @@ -16,6 +16,7 @@ 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.release.helper.FoDReleaseDescriptor; import kong.unirest.UnirestInstance; @@ -27,4 +28,13 @@ public static final FoDScanConfigMobileDescriptor getSetupDescriptor(UnirestInst .getBody(); return JsonHelper.treeToValue(body, FoDScanConfigMobileDescriptor.class); } + + public static final FoDScanConfigMobileDescriptor setupScan(UnirestInstance unirest, FoDReleaseDescriptor releaseDescriptor, FoDScanConfigMobileSetupRequest setupMobileScanRequest) { + var releaseId = releaseDescriptor.getReleaseId(); + unirest.put(FoDUrls.MOBILE_SCANS + "/scan-setup") + .routeParam("relId", releaseId) + .body(setupMobileScanRequest) + .asString().getBody(); + return getSetupDescriptor(unirest, releaseId); + } } diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/helper/FoDScanConfigMobileSetupRequest.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/helper/FoDScanConfigMobileSetupRequest.java new file mode 100644 index 0000000000..f467f3697a --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/mast_scan/helper/FoDScanConfigMobileSetupRequest.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.mast_scan.helper; + +import com.formkiq.graalvm.annotations.Reflectable; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Reflectable @NoArgsConstructor @AllArgsConstructor +@Data @Builder +public class FoDScanConfigMobileSetupRequest { + private Integer assessmentTypeId; + private String auditPreferenceType; + private String frameworkType; + private String platformType; + private String timeZone; +} 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 c1de4d1e1c..e49fdd6308 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 @@ -13,7 +13,9 @@ package com.fortify.cli.fod.release.helper; import java.time.Instant; +import java.util.Arrays; import java.util.Date; +import java.util.Optional; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -25,6 +27,7 @@ import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod._common.scan.helper.FoDScanType; import com.fortify.cli.fod._common.util.FoDEnums; +import com.fortify.cli.fod._common.util.FoDEnums.EntitlementFrequencyType; import kong.unirest.GetRequest; import kong.unirest.UnirestInstance; @@ -55,6 +58,18 @@ public static final FoDReleaseAssessmentTypeDescriptor[] getAssessmentTypes(Unir return JsonHelper.treeToValue(assessmentTypes, FoDReleaseAssessmentTypeDescriptor[].class); } + public static final FoDReleaseAssessmentTypeDescriptor getAssessmentTypeDescriptor(UnirestInstance unirest, String relId, + FoDScanType scanType, EntitlementFrequencyType entFreqType, String assessmentType) { + // find an appropriate assessment type to use + Optional<FoDReleaseAssessmentTypeDescriptor> atd = Arrays.stream( + FoDReleaseAssessmentTypeHelper.getAssessmentTypes(unirest, + relId, scanType, entFreqType, + false, true) + ).filter(n -> n.getName().equals(assessmentType)) + .findFirst(); + return atd.orElseThrow(()->new IllegalArgumentException("Cannot find appropriate assessment type for specified options.")); + } + public final static void validateEntitlement(String relId, FoDReleaseAssessmentTypeDescriptor atd) { if (atd == null || atd.getAssessmentTypeId() == null || atd.getAssessmentTypeId() <= 0) { diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/sast_scan/cli/cmd/FoDSastScanSetupCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/sast_scan/cli/cmd/FoDSastScanSetupCommand.java index 4bf5d20da3..16ae64b315 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/sast_scan/cli/cmd/FoDSastScanSetupCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/sast_scan/cli/cmd/FoDSastScanSetupCommand.java @@ -13,10 +13,7 @@ package com.fortify.cli.fod.sast_scan.cli.cmd; -import java.util.Arrays; import java.util.Objects; -import java.util.Optional; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -112,7 +109,8 @@ private FoDScanConfigSastDescriptor setup(UnirestInstance unirest, FoDReleaseDes LOG.info("Finding appropriate entitlement to use."); - var atd = getAssessmentTypeDescriptor(unirest, relId); + var atd = FoDReleaseAssessmentTypeHelper.getAssessmentTypeDescriptor(unirest, relId, FoDScanType.Static, + entitlementFrequencyTypeMixin.getEntitlementFrequencyType(), staticAssessmentType); var assessmentTypeId = atd.getAssessmentTypeId(); var entitlementIdToUse = atd.getEntitlementId(); @@ -182,18 +180,6 @@ private void validateEntitlement(FoDScanConfigSastDescriptor currentSetup, Integ FoDReleaseAssessmentTypeHelper.validateEntitlement(relId, atd); } - private FoDReleaseAssessmentTypeDescriptor getAssessmentTypeDescriptor(UnirestInstance unirest, String relId) { - // find an appropriate assessment type to use - Optional<FoDReleaseAssessmentTypeDescriptor> atd = Arrays.stream( - FoDReleaseAssessmentTypeHelper.getAssessmentTypes(unirest, - relId, FoDScanType.Static, - entitlementFrequencyTypeMixin.getEntitlementFrequencyType(), - false, true) - ).filter(n -> n.getName().equals(staticAssessmentType)) - .findFirst(); - return atd.orElseThrow(()->new IllegalArgumentException("Cannot find appropriate assessment type for specified options.")); - } - @Override public JsonNode transformRecord(JsonNode record) { FoDReleaseDescriptor releaseDescriptor = releaseResolver.getReleaseDescriptor(getUnirestInstance()); 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 1a4a0078de..cfb26308c2 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 @@ -36,7 +36,7 @@ fcli.fod.app.app-criticality = The business criticality of the application. Vali fcli.fod.release.sdlc-status = The SDLC lifecycle status of the release. Valid values: ${COMPLETION-CANDIDATES} fcli.fod.scan.time-period = Time period to retrieve results over. Valid values: ${COMPLETION-CANDIDATES}. Default value is Last30. fcli.fod.scan.entitlement-preference = The entitlement preference to use. Valid values: ${COMPLETION-CANDIDATES}. Default is SubscriptionFirstThenSingleScan. -fcli.fod.scan.assessment-type = The assessment type to use. Use 'release list-assessment-types' to find valid values. +fcli.fod.scan.assessment-type = The assessment type to use. Use 'fod release lsat' to find valid values. fcli.fod.scan.in-progress-action = The action to use if a scan is already in progress. Valid values: ${COMPLETION-CANDIDATES}. fcli.fod.scan.remediation-preference = The remediation preference to use. Valid values: ${COMPLETION-CANDIDATES}. fcli.fod.microservice.resolver.name = Microservice name in the format <application>:<microservice>. @@ -529,7 +529,7 @@ fcli.fod.sast-scan.setup.usage.description.3 = For the '--technology-stack' and fcli.fod.sast-scan.setup.entitlement-frequency = The Entitlement Frequency to use. Valid values: ${COMPLETION-CANDIDATES}. fcli.fod.sast-scan.setup.entitlement-id = Entitlement Id to use. If not specified Frequency and Assessment Type will be used to find one. fcli.fod.sast-scan.setup.validate-entitlement = Check if the entitlement assigned is still valid, e.g. it has not expired. -fcli.fod.sast-scan.setup.assessment-type = The type of Static assessment to carry out. Use 'release list-assessment-types' to find valid values. +fcli.fod.sast-scan.setup.assessment-type = The type of Static assessment to carry out. Use 'fod release lsat' to find valid values. fcli.fod.sast-scan.setup.technology-stack = The technology stack of the application. Default value: ${DEFAULT-VALUE}. fcli.fod.sast-scan.setup.language-level = The language level of the technology stack (if needed). fcli.fod.sast-scan.setup.oss = Perform Open Source Analysis scan. @@ -672,6 +672,7 @@ fcli.fod.dast-scan.setup-website.macro-primary-username = Login macro username f 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-website.vpn = Fortify Connect network name to use for site-to-site VPN. If specified, environment will be set to Internal. 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". @@ -688,6 +689,7 @@ fcli.fod.dast-scan.setup-workflow.network-auth-type = The Network Authentication 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-workflow.vpn = Fortify Connect network name to use for site-to-site VPN. If specified, environment will be set to Internal. 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. @@ -710,6 +712,7 @@ fcli.fod.dast-scan.setup-api.network-auth-type = The Network Authentication type 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} +fcli.fod.dast-scan.setup-api.vpn = Fortify Connect network name to use for site-to-site VPN. If specified, environment will be set to Internal. # fcli fod mast-scan fcli.fod.mast-scan.usage.header = Manage FoD MAST scans. @@ -724,11 +727,10 @@ fcli.fod.mast-scan.output.header.microserviceName = Microservice fcli.fod.mast-scan.output.header.releaseName = Release fcli.fod.mast-scan.cancel.usage.header = Cancel a MAST scan. fcli.fod.mast-scan.get.usage.header = Get MAST scan details. -fcli.fod.mast-scan.get-config.usage.header = (PREVIEW) Get current MAST scan configuration. -fcli.fod.mast-scan.get-config.usage.description = 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. \ - Please note: there is currently no API endpoint for this command and so it will fail with HTTP 405 error until this endpoint is available. +fcli.fod.mast-scan.get-config.usage.header = Get current MAST scan configuration. +fcli.fod.mast-scan.get-config.usage.description = This command will retrieve the current MAST scan configuration. \ + The API endpoint used by this command currently only returns a subset of information for Mobile+ Assessments. \ + It is therefore recommended to use this command for Mobile Assessments only. fcli.fod.mast-scan.list.usage.header = List MAST scans. fcli.fod.mast-scan.list.status = ${fcli.fod.scan.list.status} fcli.fod.mast-scan.list.type = ${fcli.fod.scan.list.type} @@ -740,22 +742,18 @@ fcli.fod.mast-scan.wait-for.usage.description.3 = ${fcli.fod.scan.wait-for.usage fcli.fod.mast-scan.wait-for.until = ${fcli.fod.scan.wait-for.until} fcli.fod.mast-scan.wait-for.while = ${fcli.fod.scan.wait-for.while} fcli.fod.mast-scan.wait-for.any-state = ${fcli.fod.scan.wait-for.any-state} -fcli.fod.mast-scan.start.usage.header = (PREVIEW) Start a new MAST scan. -fcli.fod.mast-scan.start.usage.description.0 = This command is not fully implemented and 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.mast-scan.start.usage.description.1 = The scan will need to have been previously setup using the FoD UI or the \ - '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 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 \ +fcli.fod.mast-scan.start.usage.header = Start a new MAST scan. +fcli.fod.mast-scan.start.usage.description.0 = To correctly start a scan you will need to provide the name of the \ + assessment type using the '--assessment-type=xxx' option. This will usually be "Mobile Assessment" but since assessment \ + types can potentially be configured differently for each tenant, you can find the correct name using the 'fod release lsat' \ + command for the release. +fcli.fod.mast-scan.start.usage.description.1 = 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.usage.description.2 = The scan will need to have been previously setup using the FoD UI or the \ + 'fod mast-scan setup' command. 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 'fod rest lookup AssessmentTypes' to find valid values. +fcli.fod.mast-scan.start.assessment-type = The type of MAST assessment to carry out. Use 'fod release lsat' 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} @@ -763,6 +761,26 @@ fcli.fod.mast-scan.start.file = Absolute path of the mobile application file to fcli.fod.mast-scan.start.framework = The Mobile Framework to use. Valid values: ${COMPLETION-CANDIDATES}. fcli.fod.mast-scan.start.platform = The Mobile Platform to use. Valid values: ${COMPLETION-CANDIDATES}. fcli.fod.mast-scan.start.timezone = The timezone to use for starting the scan - default is UTC. Use 'fod rest lookup TimeZones' to see the values. +fcli.fod.mast-scan.setup.usage.header = (PREVIEW) Configure MAST scan details for the release. +fcli.fod.mast-scan.setup.usage.description.0 = This command is not fully implemented and 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.mast-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 lsat' command. +fcli.fod.mast-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. +fcli.fod.mast-scan.setup.entitlement-frequency = The Entitlement Frequency to use. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.mast-scan.setup.entitlement-id = Entitlement Id to use. If not specified Frequency and Assessment Type will be used to find one. +fcli.fod.mast-scan.setup.validate-entitlement = Check if the entitlement assigned is still valid, e.g. it has not expired. +fcli.fod.mast-scan.setup.assessment-type = The type of Static assessment to carry out. Use 'fod release lsat' to find valid values. +fcli.fod.mast-scan.setup.framework = The Mobile Framework to use. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.mast-scan.setup.platform = The Mobile Platform to use. Valid values: ${COMPLETION-CANDIDATES}. +fcli.fod.mast-scan.setup.timezone = The timezone to use for starting the scan - default is UTC. Use 'fod rest lookup TimeZones' to see the values. +fcli.fod.mast-scan.setup.audit-preference = Audit preference, e.g. Manual or None. Default value: None. +fcli.fod.mast-scan.setup.skip-if-exists = Skip setup if a scan has already been set up. If not specified, any existing scan \ + setup will be replaced based on the given setup options. fcli.fod.mast-scan.import.usage.header = Import existing MAST scan results (from an FPR file). fcli.fod.mast-scan.import.usage.description = As FoD doesn't return a scan id for imported scans, the output of this command cannot be used with commands that expect a scan id, like the wait-for command. fcli.fod.mast-scan.import.file = FPR file containing existing MAST scan results to be imported.