Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A number of small updates for implementation/fix of various outstanding Issues #661

Merged
merged 4 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ public static class NetworkAuthenticationType {
private Integer timeBoxInHours;
@Builder.Default
private Boolean requestFalsePositiveRemoval = false;

private String networkName; // FoDConnect Network Name
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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 :
Expand All @@ -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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand All @@ -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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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();
Expand All @@ -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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
FoDMastScanGetConfigCommand.class,
FoDMastScanImportCommand.class,
FoDMastScanListCommand.class,
//FoDMastScanSetupCommand.class,
FoDMastScanSetupCommand.class,
FoDMastScanStartCommand.class,
FoDMastScanWaitForCommand.class,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
Loading
Loading