Skip to content
Closed
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 @@ -232,4 +232,8 @@ public static class RestCall extends DetailsWithQuery {
public static final String CMD_NAME = "call";
}

public static class ImportSarif extends TableNoQuery {
public static final String CMD_NAME = "import-sarif";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class FoDUrls {
public static final String RELEASE_SCANS = RELEASE + "/scans";
public static final String STATIC_SCANS = ApiBase + "/releases/{relId}/static-scans";
public static final String STATIC_SCANS_IMPORT = STATIC_SCANS + "/import-scan";
public static final String STATIC_SCANS_IMPORT_SARIF = STATIC_SCANS + "/import-sarif";
public static final String STATIC_SCAN_START = STATIC_SCANS + "/start-scan";
public static final String STATIC_SCAN_START_WITH_DEFAULTS = STATIC_SCANS + "/start-scan-with-defaults";
public static final String STATIC_SCAN_START_ADVANCED = STATIC_SCANS + "/start-scan-advanced";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@
*/
package com.fortify.cli.fod._common.scan.helper;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.formkiq.graalvm.annotations.Reflectable;
import com.fortify.cli.common.json.JsonNodeHolder;
import com.fortify.cli.fod.attribute.helper.FoDAttributeDescriptor;

import lombok.Data;
import lombok.EqualsAndHashCode;
Expand All @@ -35,6 +39,7 @@ public class FoDScanDescriptor extends JsonNodeHolder {
private String microserviceName;
private String analysisStatusType;
private String status;
private ArrayList<FoDAttributeDescriptor> attributes;

@JsonIgnore
public String getReleaseAndScanId() {
Expand All @@ -45,4 +50,12 @@ public String getReleaseAndScanId() {
private Date startedDateTime;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyy-MM-dd'T'hh:mm:ss")
private Date completedDateTime;

public Map<Integer, String> attributesAsMap() {
Map<Integer, String> attrMap = new HashMap<>();
for (FoDAttributeDescriptor attr : attributes) {
attrMap.put(attr.getId(), attr.getValue());
}
return attrMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public static FoDScanAssessmentTypeDescriptor getEntitlementToUse(UnirestInstanc
Integer assessmentTypeId = 0;
LOG.info("Finding/Validating entitlement to use.");

var atd = FoDReleaseAssessmentTypeHelper.getAssessmentTypeDescriptor(unirest, relId, scanType,
var atd = FoDReleaseAssessmentTypeHelper.getAssessmentTypeDescriptor(unirest, relId, scanType,
entitlementFrequencyType, assessmentType);
assessmentTypeId = atd.getAssessmentTypeId();
entitlementIdToUse = atd.getEntitlementId();
Expand Down Expand Up @@ -191,7 +191,7 @@ private static final FoDScanDescriptor getDescriptor(JsonNode node) {
return JsonHelper.treeToValue(node, FoDScanDescriptor.class);
}

private static final FoDScanDescriptor getEmptyDescriptor() {
public static final FoDScanDescriptor getEmptyDescriptor() {
return JsonHelper.treeToValue(getObjectMapper().createObjectNode(), FoDScanDescriptor.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -633,4 +633,28 @@ public static java.util.Optional<String> resolveValue(String input) {
}
}

public enum SBOMFormat implements IFoDEnumValueSupplier<String> {
CycloneDX("CycloneDX"),
SPDX("SPDX");

public final String value;

SBOMFormat(String value) {
this.value = value;
}

public String getValue() {
return this.value;
}

/**
* Resolve an input string which may be either the enum constant name (e.g. "CycloneDX")
* or the user-facing value (e.g. "CycloneDX") to the canonical user-facing value.
* Comparison for the enum name is case-insensitive. Returns an empty Optional when no match.
*/
public static java.util.Optional<String> resolveValue(String input) {
return IFoDEnumValueSupplier.resolveEnumValue(input, values());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import com.fortify.cli.fod._common.scan.cli.cmd.AbstractFoDScanStartCommand;
import com.fortify.cli.fod._common.scan.cli.mixin.FoDInProgressScanActionTypeMixins;
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.dast.FoDScanDastAutomatedHelper;
import com.fortify.cli.fod._common.util.FoDEnums;
import com.fortify.cli.fod.release.helper.FoDReleaseDescriptor;
Expand Down Expand Up @@ -50,15 +52,21 @@ protected FoDScanDescriptor startScan(UnirestInstance unirest, FoDReleaseDescrip
// get current setup to ensure the scan has been configured
FoDScanDastAutomatedHelper.getSetupDescriptor(unirest, relId);

// check if scan is already in progress
FoDScanDescriptor scan = FoDScanDastAutomatedHelper.handleInProgressScan(unirest, releaseDescriptor,
inProgressScanActionType.getInProgressScanActionType(), progressWriter, maxAttempts,
waitInterval);
// check if there have been any scans previously run for this release
if (!FoDScanDastAutomatedHelper.getLatestScanDescriptor(unirest, relId, FoDScanType.Dynamic, true)
.equals(FoDScanHelper.getEmptyDescriptor())) {

if (scan != null && scan.getAnalysisStatusType().equals("In_Progress")) {
if (inProgressScanActionType.getInProgressScanActionType() == FoDEnums.InProgressScanActionType.DoNotStartScan) {
scanAction = "NOT_STARTED_SCAN_IN_PROGRESS";
return scan;
// if there is an in progress scan, handle according to the specified action type
FoDScanDescriptor scan = FoDScanDastAutomatedHelper.handleInProgressScan(unirest, releaseDescriptor,
inProgressScanActionType.getInProgressScanActionType(), progressWriter, maxAttempts,
waitInterval);

// if the action was to not start a new scan, return the in progress scan descriptor
if (scan != null && scan.getAnalysisStatusType().equals("In_Progress")) {
if (inProgressScanActionType.getInProgressScanActionType() == FoDEnums.InProgressScanActionType.DoNotStartScan) {
scanAction = "NOT_STARTED_SCAN_IN_PROGRESS";
return scan;
}
}
}

Expand All @@ -70,4 +78,5 @@ protected FoDScanDescriptor startScan(UnirestInstance unirest, FoDReleaseDescrip
public final String getActionCommandResult() {
return scanAction;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public JsonNode getJsonNode(UnirestInstance unirest) {
}
FoDAppDescriptor appDescriptor = qualifiedMicroserviceNameResolver.getAppDescriptor(unirest, true);
FoDQualifiedMicroserviceNameDescriptor qualifiedMicroserviceNameDescriptor = qualifiedMicroserviceNameResolver.getQualifiedMicroserviceNameDescriptor();
// if the application is not microservice enabled, return the application descriptor with an additional field indicating that the microservice was not created due to the application not being microservice enabled
if (!appDescriptor.isHasMicroservices()) {
return appDescriptor.asObjectNode().put("__action__", "NOT_MICROSERVICE_ENABLED");
}
FoDMicroserviceUpdateRequest msCreateRequest = FoDMicroserviceUpdateRequest.builder()
.microserviceName(qualifiedMicroserviceNameDescriptor.getMicroserviceName())
.attributes(FoDAttributeHelper.getAttributesNode(unirest, FoDEnums.AttributeTypes.Microservice,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,32 @@
import com.fortify.cli.fod._common.scan.cli.cmd.AbstractFoDScanDownloadCommand;
import com.fortify.cli.fod._common.scan.helper.FoDScanDescriptor;
import com.fortify.cli.fod._common.scan.helper.FoDScanType;
import com.fortify.cli.fod._common.util.FoDEnums;

import kong.unirest.GetRequest;
import kong.unirest.UnirestInstance;
import lombok.Getter;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;

@Command(name = OutputHelperMixins.Download.CMD_NAME)
public class FoDOssScanDownloadCommand extends AbstractFoDScanDownloadCommand {
@Getter @Mixin private OutputHelperMixins.Download outputHelper;

@Option(names="--format", required = false)
private FoDEnums.SBOMFormat format;

@Override
protected GetRequest getDownloadRequest(UnirestInstance unirest, FoDScanDescriptor scanDescriptor) {
return unirest.get("/api/v3/open-source-scans/{scanId}/sbom")
.routeParam("scanId", scanDescriptor.getScanId())
.accept("application/octet-stream");
String path = "/api/v3/open-source-scans/{scanId}/sbom";
GetRequest req = unirest.get(path)
.routeParam("scanId", scanDescriptor.getScanId());
if ( format != null ) {
req = req.queryString("format", format.name());
}
return req.accept("application/octet-stream");
}

@Override
protected FoDScanType getScanType() {
return FoDScanType.OpenSource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,31 @@
import com.fortify.cli.fod._common.scan.cli.cmd.AbstractFoDScanDownloadLatestCommand;
import com.fortify.cli.fod._common.scan.helper.FoDScanDescriptor;
import com.fortify.cli.fod._common.scan.helper.FoDScanType;
import com.fortify.cli.fod._common.util.FoDEnums;
import com.fortify.cli.fod.release.helper.FoDReleaseDescriptor;

import kong.unirest.GetRequest;
import kong.unirest.UnirestInstance;
import lombok.Getter;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;

@Command(name = FoDOutputHelperMixins.DownloadLatest.CMD_NAME)
public class FoDOssScanDownloadLatestCommand extends AbstractFoDScanDownloadLatestCommand {
@Getter @Mixin private FoDOutputHelperMixins.DownloadLatest outputHelper;
@Option(names="--format", required = false)
private FoDEnums.SBOMFormat format;

@Override
protected GetRequest getDownloadRequest(UnirestInstance unirest, FoDReleaseDescriptor releaseDescriptor, FoDScanDescriptor scanDescriptor) {
return unirest.get("/api/v3/open-source-scans/{scanId}/sbom")
String path = "/api/v3/open-source-scans/{scanId}/sbom";
GetRequest req = unirest.get(path)
.routeParam("scanId", scanDescriptor.getScanId());
if ( format != null ) {
req = req.queryString("format", format.name());
}
return req.accept("application/octet-stream");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2021-2026 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.oss_scan.cli.cmd;

public class FoDScanDownloadOpenSourceType {

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@
FoDSastScanGetCommand.class,
FoDSastScanGetConfigCommand.class,
FoDSastScanImportCommand.class,
FoDSastScanImportSarifCommand.class,
FoDSastScanListCommand.class,
FoDSastScanSetupCommand.class,
FoDSastScanStartCommand.class,
FoDSastScanWaitForCommand.class,
}
}
)
@DefaultVariablePropertyName("releaseAndScanId")
public class FoDSastScanCommands extends AbstractContainerCommand {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2021-2026 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.sast_scan.cli.cmd;

import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins;
import com.fortify.cli.fod._common.rest.FoDUrls;
import com.fortify.cli.fod._common.scan.cli.cmd.AbstractFoDScanImportCommand;
import com.fortify.cli.fod._common.scan.helper.FoDScanType;

import kong.unirest.HttpRequest;
import kong.unirest.UnirestInstance;
import lombok.Getter;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;

@Command(name = OutputHelperMixins.ImportSarif.CMD_NAME)
public class FoDSastScanImportSarifCommand extends AbstractFoDScanImportCommand {
@Getter @Mixin private OutputHelperMixins.ImportSarif outputHelper;

@Override
protected HttpRequest<?> getBaseRequest(UnirestInstance unirest, String releaseId) {
return unirest.put(FoDUrls.STATIC_SCANS_IMPORT_SARIF).routeParam("relId", releaseId);
}

@Override
protected FoDScanType getScanType() {
return FoDScanType.Static;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,9 @@ fcli.fod.sast-scan.setup.use-aviator = Use Fortify Aviator to audit results and
fcli.fod.sast-scan.import.usage.header = Import existing SAST scan results (from an FPR file).
fcli.fod.sast-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.sast-scan.import.file = FPR file containing existing SAST scan results to be imported.
fcli.fod.sast-scan.import-sarif.usage.header = Import existing SAST scan results (from a SARIF file).
fcli.fod.sast-scan.import-sarif.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.sast-scan.import-sarif.file = SARIF file containing existing SAST scan results to be imported.
fcli.fod.sast-scan.download.usage.header = Download scan results.
fcli.fod.sast-scan.download.file = File path and name where to save the FPR file.
fcli.fod.sast-scan.download-latest.usage.header = Download latest scan results from release.
Expand Down Expand Up @@ -867,8 +870,10 @@ fcli.fod.oss-scan.wait-for.while = ${fcli.fod.scan.wait-for.while}
fcli.fod.oss-scan.wait-for.any-state = ${fcli.fod.scan.wait-for.any-state}
fcli.fod.oss-scan.download.usage.header = Download scan results.
fcli.fod.oss-scan.download.file = File path and name where to save the SBOM file.
fcli.fod.oss-scan.download.format = Open Source scan results file format. Valid values: ${COMPLETION-CANDIDATES} (default value is CycloneDX).
fcli.fod.oss-scan.download-latest.usage.header = Download latest scan results from release.
fcli.fod.oss-scan.download-latest.file = File path and name where to save the SBOM file.
fcli.fod.oss-scan.download-latest.format = Open Source scan results file format. Valid values: ${COMPLETION-CANDIDATES} (default value is CycloneDX).

# fcli fod issue
fcli.fod.issue.usage.header = Manage FoD issues (vulnerabilities) and related entities.
Expand Down
Loading