Skip to content

Commit

Permalink
Merge pull request #599 from kadraman/fod-2403-updates
Browse files Browse the repository at this point in the history
Updates for Fortify Aviator in SAST scan setup and Release Attributes
  • Loading branch information
rsenden authored Sep 17, 2024
2 parents 21ddf53 + 3727329 commit 312323e
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ public static final Map<String, String> getRequiredAttributesDefaultValues(Unire
Iterator<FoDAttributeDescriptor> lookupIterator = lookupList.iterator();
while (lookupIterator.hasNext()) {
FoDAttributeDescriptor currentLookup = lookupIterator.next();
// currentLookup.getAttributeTypeId() == 1 is "Application" - filter above does not support querying on this yet!
if (currentLookup.getIsRequired() && currentLookup.getAttributeTypeId() == 1) {
// currentLookup.getAttributeTypeId() == 1 is "Application", 4 is "Release" - filter above does not support querying on this yet!
if (currentLookup.getIsRequired() && (currentLookup.getAttributeTypeId() == 1 || currentLookup.getAttributeTypeId() == 4)) {
switch (currentLookup.getAttributeDataType()) {
case "Text":
reqAttrs.put(currentLookup.getName(), "autofilled by fcli");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import com.fortify.cli.common.util.StringUtils;
import com.fortify.cli.fod._common.cli.mixin.FoDDelimiterMixin;
import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDJsonNodeOutputCommand;
import com.fortify.cli.fod.app.attr.cli.mixin.FoDAttributeUpdateOptions;
import com.fortify.cli.fod.app.attr.helper.FoDAttributeHelper;
import com.fortify.cli.fod.app.cli.mixin.FoDSdlcStatusTypeOptions;
import com.fortify.cli.fod.release.cli.mixin.FoDReleaseByQualifiedNameOrIdResolverMixin;
import com.fortify.cli.fod.release.cli.mixin.FoDReleaseByQualifiedNameResolverMixin;
Expand All @@ -43,9 +45,13 @@ public class FoDReleaseCreateCommand extends AbstractFoDJsonNodeOutputCommand im
private String description;
@Option(names={"--skip-if-exists"})
private boolean skipIfExists = false;
@Option(names={"--auto-required-attrs"}, required = false)
protected boolean autoRequiredAttrs = false;

@Mixin
private FoDSdlcStatusTypeOptions.RequiredOption sdlcStatus;
@Mixin
protected FoDAttributeUpdateOptions.OptionalAttrOption relAttrs;

// TODO Consider splitting method
@Override
Expand All @@ -72,7 +78,8 @@ public JsonNode getJsonNode(UnirestInstance unirest) {
.applicationId(Integer.valueOf(appDescriptor.getApplicationId()))
.releaseName(simpleReleaseName)
.releaseDescription(description)
.sdlcStatusType(sdlcStatus.getSdlcStatusType().name());
.sdlcStatusType(sdlcStatus.getSdlcStatusType().name())
.attributes(FoDAttributeHelper.getAttributesNode(unirest, relAttrs.getAttributes(), autoRequiredAttrs));
if ( microserviceDescriptor!=null ) {
requestBuilder = requestBuilder.microserviceId(Integer.valueOf(microserviceDescriptor.getMicroserviceId()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@

package com.fortify.cli.fod.release.cli.cmd;

import java.util.ArrayList;
import java.util.Map;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
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.util.StringUtils;
import com.fortify.cli.fod._common.cli.mixin.FoDDelimiterMixin;
import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDJsonNodeOutputCommand;
import com.fortify.cli.fod.app.attr.cli.mixin.FoDAttributeUpdateOptions;
import com.fortify.cli.fod.app.attr.helper.FoDAttributeDescriptor;
import com.fortify.cli.fod.app.attr.helper.FoDAttributeHelper;
import com.fortify.cli.fod.app.cli.mixin.FoDSdlcStatusTypeOptions;
import com.fortify.cli.fod.release.cli.mixin.FoDReleaseByQualifiedNameOrIdResolverMixin;
import com.fortify.cli.fod.release.helper.FoDReleaseDescriptor;
Expand All @@ -36,6 +43,7 @@
@Command(name = OutputHelperMixins.Update.CMD_NAME)
public class FoDReleaseUpdateCommand extends AbstractFoDJsonNodeOutputCommand implements IRecordTransformer, IActionCommandResultSupplier {
@Getter @Mixin private OutputHelperMixins.Update outputHelper;
private final ObjectMapper objectMapper = new ObjectMapper();
@Mixin private FoDDelimiterMixin delimiterMixin; // Is automatically injected in resolver mixins
@Mixin private FoDReleaseByQualifiedNameOrIdResolverMixin.PositionalParameter releaseResolver;
@Option(names = {"--name", "-n"})
Expand All @@ -49,18 +57,28 @@ public class FoDReleaseUpdateCommand extends AbstractFoDJsonNodeOutputCommand im

@Mixin
private FoDSdlcStatusTypeOptions.OptionalOption sdlcStatus;
@Mixin
private FoDAttributeUpdateOptions.OptionalAttrOption appAttrsUpdate;

@Override
public JsonNode getJsonNode(UnirestInstance unirest) {
FoDReleaseDescriptor releaseDescriptor = releaseResolver.getReleaseDescriptor(unirest);
ArrayList<FoDAttributeDescriptor> releaseAttrsCurrent = releaseDescriptor.getAttributes();
FoDSdlcStatusTypeOptions.FoDSdlcStatusType sdlcStatusTypeNew = sdlcStatus.getSdlcStatusType();

Map<String, String> attributeUpdates = appAttrsUpdate.getAttributes();
JsonNode jsonAttrs = objectMapper.createArrayNode();
if (attributeUpdates != null && !attributeUpdates.isEmpty()) {
jsonAttrs = FoDAttributeHelper.mergeAttributesNode(unirest, releaseAttrsCurrent, attributeUpdates);
} else {
jsonAttrs = FoDAttributeHelper.getAttributesNode(releaseAttrsCurrent);
}
FoDReleaseUpdateRequest appRelUpdateRequest = FoDReleaseUpdateRequest.builder()
.releaseName(StringUtils.isNotBlank(releaseName) ? getUnqualifiedReleaseName(releaseName, releaseDescriptor) : releaseDescriptor.getReleaseName())
.releaseDescription(StringUtils.isNotBlank(description) ? description : releaseDescriptor.getReleaseDescription())
.ownerId(StringUtils.isNotBlank(releaseOwner) ? Integer.valueOf(releaseOwner) : releaseDescriptor.getOwnerId())
.microserviceId(releaseDescriptor.getMicroserviceId())
.sdlcStatusType(sdlcStatusTypeNew != null ? String.valueOf(sdlcStatusTypeNew) : releaseDescriptor.getSdlcStatusType()).build();
.sdlcStatusType(sdlcStatusTypeNew != null ? String.valueOf(sdlcStatusTypeNew) : releaseDescriptor.getSdlcStatusType())
.attributes(jsonAttrs).build();

return FoDReleaseHelper.updateRelease(unirest, releaseDescriptor.getReleaseId(), appRelUpdateRequest).asJsonNode();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.JsonNode;
import com.formkiq.graalvm.annotations.Reflectable;

import lombok.AllArgsConstructor;
Expand All @@ -35,4 +36,6 @@ public class FoDReleaseCreateRequest {
private Integer copyStateReleaseId;
private String sdlcStatusType;
private Integer microserviceId;
private JsonNode attributes;
private Boolean autoRequiredAttrs;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@
package com.fortify.cli.fod.release.helper;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.formkiq.graalvm.annotations.Reflectable;
import com.fortify.cli.common.json.JsonNodeHolder;
import com.fortify.cli.common.util.StringUtils;
import com.fortify.cli.fod.app.attr.helper.FoDAttributeDescriptor;

import lombok.Data;
import lombok.EqualsAndHashCode;
Expand Down Expand Up @@ -54,7 +58,8 @@ public class FoDReleaseDescriptor extends JsonNodeHolder {
private LocalDateTime staticScanDate;
private LocalDateTime dynamicScanDate;
private LocalDateTime mobileScanDate;

private ArrayList<FoDAttributeDescriptor> attributes;

@JsonIgnore public String getQualifiedName() {
return StringUtils.isBlank(microserviceName)
? String.format("%s:%s", applicationName, releaseName)
Expand All @@ -66,4 +71,12 @@ public String getQualifierPrefix(String delimiter) {
var msQualifierPrefix = StringUtils.isBlank(microserviceName) ? "" : (microserviceName+delimiter);
return applicationName+delimiter+msQualifierPrefix;
}

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 @@ -12,6 +12,7 @@
*******************************************************************************/
package com.fortify.cli.fod.release.helper;

import com.fasterxml.jackson.databind.JsonNode;
import com.formkiq.graalvm.annotations.Reflectable;

import lombok.AllArgsConstructor;
Expand All @@ -28,4 +29,5 @@ public class FoDReleaseUpdateRequest {
private String sdlcStatusType;
private Integer ownerId;
private String microserviceId;
private JsonNode attributes;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
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;
Expand Down Expand Up @@ -52,7 +53,7 @@
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;

@Command(name = OutputHelperMixins.Setup.CMD_NAME, hidden = false)
@Command(name = OutputHelperMixins.Setup.CMD_NAME, hidden = false) @CommandGroup("*-scan-setup")
@DisableTest(TestType.CMD_DEFAULT_TABLE_OPTIONS_PRESENT)
public class FoDSastScanSetupCommand extends AbstractFoDJsonNodeOutputCommand implements IRecordTransformer, IActionCommandResultSupplier {
private static final Log LOG = LogFactory.getLog(FoDSastScanSetupCommand.class);
Expand Down Expand Up @@ -82,7 +83,9 @@ public class FoDSastScanSetupCommand extends AbstractFoDJsonNodeOutputCommand im
@Option(names = {"--use-source-control"})
private final Boolean useSourceControl = false;
@Option(names={"--skip-if-exists"})
private boolean skipIfExists = false;
private Boolean skipIfExists = false;
@Option(names={"--use-aviator"})
private Boolean useAviator = false;

// TODO We don't actually use a progress writer, but for now we can't
// remove the --progress option to maintain backward compatibility.
Expand Down Expand Up @@ -128,7 +131,8 @@ private FoDScanConfigSastDescriptor setup(UnirestInstance unirest, FoDReleaseDes
.performOpenSourceAnalysis(performOpenSourceAnalysis)
.auditPreferenceType(auditPreferenceType.name())
.includeThirdPartyLibraries(includeThirdPartyLibraries)
.useSourceControl(useSourceControl).build();
.useSourceControl(useSourceControl)
.includeFortifyAviator(useAviator).build();

return FoDScanConfigSastHelper.setupScan(unirest, releaseDescriptor, setupSastScanRequest);
}
Expand Down Expand Up @@ -194,6 +198,10 @@ private FoDReleaseAssessmentTypeDescriptor getAssessmentTypeDescriptor(UnirestIn
public JsonNode transformRecord(JsonNode record) {
FoDReleaseDescriptor releaseDescriptor = releaseResolver.getReleaseDescriptor(getUnirestInstance());
return ((ObjectNode)record)
// Start partial fix for (#598)
.put("scanType", staticAssessmentType)
.put("setupType", auditPreferenceType.name())
// End
.put("applicationName", releaseDescriptor.getApplicationName())
.put("releaseName", releaseDescriptor.getReleaseName())
.put("microserviceName", releaseDescriptor.getMicroserviceName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ public class FoDScanConfigSastSetupRequest {
private Boolean includeThirdPartyLibraries;
private Boolean useSourceControl;
private Boolean scanBinary;
private Boolean includeFortifyAviator;
}
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ fcli.fod.app.create.owner = The owner of the application/release who will receiv
fcli.fod.app.create.groups = User group ids or names to give access of the application to.
fcli.fod.app.create.criticality = The business criticality of the application. Valid values: ${COMPLETION-CANDIDATES}.
fcli.fod.app.create.status = The SDLC lifecycle status of the release. Valid values: ${COMPLETION-CANDIDATES}
fcli.fod.app.create.attr = Attribute id or name and its value to set on the application.
fcli.fod.app.create.attr = Attribute id or name and its value to set on the application. For User attributes only userId is currently supported.
fcli.fod.app.create.skip-if-exists = Check to see if application already exists before creating.
fcli.fod.app.create.auto-required-attrs = Automatically set a default value for required attributes.
fcli.fod.app.create.microservice = The name of the first microservice to create for the application.
Expand All @@ -319,7 +319,7 @@ fcli.fod.app.update.name = The updated name for the application.
fcli.fod.app.update.description = The updated description for the application.
fcli.fod.app.update.notify = Email address of user(s) to send notifications to (Please note, any existing entries will be replaced).
fcli.fod.app.update.criticality = The business criticality of the application.
fcli.fod.app.update.attr = Attribute id or name and its value to set on the application.
fcli.fod.app.update.attr = Attribute id or name and its value to set on the application. For User attributes only userId is currently supported.
fcli.fod.app.list-scans.usage.header = List scans for a given application.

# fcli fod microservice
Expand Down Expand Up @@ -352,14 +352,18 @@ fcli.fod.release.output.header.applicationName = Application
fcli.fod.release.output.header.releaseDescription = Description
fcli.fod.release.output.header.sdlcStatusType = SDLC Status

fcli.fod.release.create.usage.header = Create a new application release.
fcli.fod.release.create.usage.header = Create a new application release. \
Please note some attributes might be mandatory depending on the configuration of your tenant. Please check the \
Fortify on Demand web portal first.
fcli.fod.release.create.application-name = The id or name of the application to create the release on.
fcli.fod.release.create.release-name = The name of the release to create for the application.
fcli.fod.release.create.description = Description of the release.
fcli.fod.release.create.copy-from = The id or name of a release to copy existing state from.
fcli.fod.release.create.microservice = The id or name of the microservice to create the release on.
fcli.fod.release.create.status = SDLC lifecycle status of the release. Valid values: ${COMPLETION-CANDIDATES}.
fcli.fod.release.create.attr = Attribute id or name and its value to set on the release. For User attributes only userId is currently supported.
fcli.fod.release.create.skip-if-exists = Check to see if release already exists before creating.
fcli.fod.release.create.auto-required-attrs = Automatically set a default value for required attributes.
fcli.fod.release.delete.usage.header = Delete an application release.
fcli.fod.release.list.usage.header = List application releases.
fcli.fod.release.get.usage.header = Get application release details.
Expand All @@ -372,6 +376,7 @@ fcli.fod.release.update.description = Updated description for the release.
fcli.fod.release.update.owner = Updated id or username for the owner of the release.
fcli.fod.release.update.microservice = The updated microservice id or name to create the release on.
fcli.fod.release.update.status = SDLC lifecycle status of the release. Valid values: ${COMPLETION-CANDIDATES}.
fcli.fod.release.update.attr = Attribute id or name and its value to set on the application. For User attributes only userId is currently supported.
fcli.fod.release.list-assessment-types.usage.header = List assessment types for a given release.
fcli.fod.release.list-assessment-types.scan-types = Comma-separated list of scan types for which to list assessment types. Default value: ${DEFAULT-VALUE}. Valid values: ${COMPLETION-CANDIDATES}.
fcli.fod.release.list-scans.usage.header = List scans for a given release.
Expand Down Expand Up @@ -491,10 +496,11 @@ fcli.fod.sast-scan.setup.technology-stack = The technology stack of the applicat
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.
fcli.fod.sast-scan.setup.audit-preference = Audit preference, e.g. Manual or Automated
fcli.fod.sast-scan.setup.include-third-party-libs = Indicates if third party libraries should be included.
fcli.fod.sast-scan.setup.use-source-control = Indicates if source control should be used.
fcli.fod.sast-scan.setup.include-third-party-libs = (LEGACY) Indicates if third party libraries should be included.
fcli.fod.sast-scan.setup.use-source-control = (LEGACY) Indicates if source control should be used.
fcli.fod.sast-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.sast-scan.setup.use-aviator = Use Fortify Aviator to audit results and provide enhanced remediation guidance.
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.
Expand Down

0 comments on commit 312323e

Please sign in to comment.