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

chore: Updates for Fortify Aviator in SAST scan setup and Release Attributes #599

Merged
merged 2 commits into from
Sep 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 @@ -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