diff --git a/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/cmd/SCSastControllerScanStartCommand.java b/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/cmd/SCSastControllerScanStartCommand.java index 8fb896a763..5552206930 100644 --- a/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/cmd/SCSastControllerScanStartCommand.java +++ b/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/cmd/SCSastControllerScanStartCommand.java @@ -48,7 +48,9 @@ public final class SCSastControllerScanStartCommand extends AbstractSCSastContro @Option(names = "--notify") private String email; // TODO Add email address validation @Mixin private PublishToAppVersionResolverMixin sscAppVersionResolver; @Option(names = "--ssc-ci-token") private String ciToken; - + @Getter @Option(names = {"--sargs","--scan-args"}) + private String scaRuntimeArgs = ""; + // TODO Add options for specifying (custom) rules file(s), filter file(s) and project template // TODO Add options for pool selection @@ -61,7 +63,7 @@ public final JsonNode getJsonNode(UnirestInstance unirest) { .field("username", userName, "text/plain") .field("scaVersion", sensorVersion, "text/plain") .field("clientVersion", sensorVersion, "text/plain") - .field("scaRuntimeArgs", optionsProvider.getScanStartOptions().getScaRuntimeArgs(), "text/plain") + .field("scaRuntimeArgs", scaRuntimeArgs, "text/plain") .field("jobType", optionsProvider.getScanStartOptions().getJobType().name(), "text/plain"); body = updateBody(body, "email", email); body = updateBody(body, "buildId", optionsProvider.getScanStartOptions().getBuildId()); diff --git a/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/ISCSastScanStartOptions.java b/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/ISCSastScanStartOptions.java index 060e8f5127..2bdd47fd39 100644 --- a/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/ISCSastScanStartOptions.java +++ b/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/ISCSastScanStartOptions.java @@ -18,7 +18,6 @@ public interface ISCSastScanStartOptions { String getBuildId(); - String getScaRuntimeArgs(); boolean isDotNetRequired(); String getDotNetVersion(); File getPayloadFile(); diff --git a/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/SCSastScanStartMbsOptions.java b/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/SCSastScanStartMbsOptions.java index 5a56359393..dc0580f287 100644 --- a/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/SCSastScanStartMbsOptions.java +++ b/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/SCSastScanStartMbsOptions.java @@ -32,7 +32,6 @@ public class SCSastScanStartMbsOptions implements ISCSastScanStartOptions { @Getter private String buildId; @Getter private final boolean dotNetRequired = false; @Getter private final String dotNetVersion = null; - @Getter private final String scaRuntimeArgs = ""; // TODO Provide options @Getter private SCSastControllerJobType jobType = SCSastControllerJobType.SCAN_JOB; @Option(names = {"-m", "--mbs-file"}, required= true) diff --git a/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/SCSastScanStartOptionsArgGroup.java b/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/SCSastScanStartOptionsArgGroup.java index b89125e78b..7e0b777f23 100644 --- a/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/SCSastScanStartOptionsArgGroup.java +++ b/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/SCSastScanStartOptionsArgGroup.java @@ -12,6 +12,8 @@ *******************************************************************************/ package com.fortify.cli.sc_sast.scan.cli.mixin; +import lombok.Getter; +import picocli.CommandLine.Option; import picocli.CommandLine.ArgGroup; public class SCSastScanStartOptionsArgGroup { diff --git a/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/SCSastScanStartPackageOptions.java b/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/SCSastScanStartPackageOptions.java index ceb9314517..19dcf43923 100644 --- a/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/SCSastScanStartPackageOptions.java +++ b/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/mixin/SCSastScanStartPackageOptions.java @@ -33,7 +33,6 @@ public class SCSastScanStartPackageOptions implements ISCSastScanStartOptions { @Getter private final String buildId = null; // TODO ScanCentral Client doesn't allow for specifying build id; should we provide a CLI option for this? @Getter private boolean dotNetRequired; @Getter private String dotNetVersion; - @Getter private final String scaRuntimeArgs = ""; @Getter private SCSastControllerJobType jobType = SCSastControllerJobType.TRANSLATION_AND_SCAN_JOB; @Option(names = {"-p", "--package-file"}, required = true) diff --git a/fcli-core/fcli-sc-sast/src/main/resources/com/fortify/cli/sc_sast/i18n/SCSastMessages.properties b/fcli-core/fcli-sc-sast/src/main/resources/com/fortify/cli/sc_sast/i18n/SCSastMessages.properties index 9c79d702ee..980253e258 100644 --- a/fcli-core/fcli-sc-sast/src/main/resources/com/fortify/cli/sc_sast/i18n/SCSastMessages.properties +++ b/fcli-core/fcli-sc-sast/src/main/resources/com/fortify/cli/sc_sast/i18n/SCSastMessages.properties @@ -112,6 +112,7 @@ fcli.sc-sast.scan.start.package-file = Package file to scan. fcli.sc-sast.scan.start.notify = Email address to which to send a scan completion notification. fcli.sc-sast.scan.start.sensor-version = Version of the sensor on which the package should be scanned. Officially, you should select the same sensor version as the version of the ScanCentral Client used to create the package. fcli.sc-sast.scan.start.publish-to = Publish scan results to the given SSC application version once the scan has completed. +fcli.sc-sast.scan.start.sargs = Fortify SCA scan arguments. fcli.sc-sast.scan.status.usage.header = Get status for a previously submitted scan request. fcli.sc-sast.scan.wait-for.usage.header = Wait for one or more scans to reach or exit specified scan statuses. fcli.sc-sast.scan.wait-for.usage.description.0 = Although this command offers a lot of options to cover many \ diff --git a/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDAccessControlRoleSpec.groovy b/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDAccessControlRoleSpec.groovy new file mode 100644 index 0000000000..b42755578e --- /dev/null +++ b/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDAccessControlRoleSpec.groovy @@ -0,0 +1,59 @@ +package com.fortify.cli.ftest.fod; + +import static com.fortify.cli.ftest._common.spec.FcliSessionType.FOD + +import com.fortify.cli.ftest._common.Fcli +import com.fortify.cli.ftest._common.spec.FcliBaseSpec +import com.fortify.cli.ftest._common.spec.FcliSession +import com.fortify.cli.ftest._common.spec.Prefix +import com.fortify.cli.ftest.fod._common.FoDWebAppSupplier +import com.fortify.cli.ftest.fod._common.FoDUserSupplier +import com.fortify.cli.ftest.fod._common.FoDUserGroupSupplier + +import spock.lang.AutoCleanup +import spock.lang.Shared +import spock.lang.Stepwise +import spock.lang.Unroll + +@Prefix("fod.role") @FcliSession(FOD) @Stepwise +class FoDAccessControlRoleSpec extends FcliBaseSpec { + @Shared @AutoCleanup FoDUserSupplier user = new FoDUserSupplier() + @Shared @AutoCleanup FoDUserGroupSupplier group = new FoDUserGroupSupplier() + @Shared @AutoCleanup FoDWebAppSupplier app = new FoDWebAppSupplier() + + def "list"() { + def args = "fod ac list-roles --store roles" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it[0].replace(' ', '').equals("IdName") + } + } + + def "updateUserRole"() { + def args = "fod ac update-user ${user.get().userName} --lastname updatedLastname --firstname updatedFirstname --phone 5678 --role=Developer" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()==2 + } + } + + def "verifyUpdated"() { + + def args = "fod ac get-user ${user.get().userName}" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>2 + it[9].equals("roleName: \"Developer\"") + } + } + + +} + diff --git a/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDAppSpec.groovy b/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDAppSpec.groovy index cb36d47b48..38b679c663 100644 --- a/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDAppSpec.groovy +++ b/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDAppSpec.groovy @@ -15,13 +15,14 @@ import spock.lang.Stepwise @Prefix("fod.app") @FcliSession(FOD) @Stepwise class FoDAppSpec extends FcliBaseSpec { - /* - @Shared FoDWebAppSupplier webAppSupplier = null; - @Shared FoDMobileAppSupplier mobileAppSupplier = null; - @Shared FoDMicroservicesAppSupplier microservicesAppSupplier = null; + + @Shared FoDWebAppSupplier webApp = new FoDWebAppSupplier(); + @Shared FoDMobileAppSupplier mobileApp = new FoDMobileAppSupplier(); + @Shared FoDMicroservicesAppSupplier microservicesApp = new FoDMicroservicesAppSupplier(); + @Shared FoDWebApp def "list"() { - def args = "fod app list" + def args = "fod app list --store=apps" when: def result = Fcli.run(args) then: @@ -35,96 +36,111 @@ class FoDAppSpec extends FcliBaseSpec { } } + def "list-scans"() { + def args = "fod app list-scans --app=::apps::get(0).applicationId" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=0 + if(size()>1) { + it[0].replace(' ', '').equals("IdTypeAnalysisStatusNameMicroserviceReleaseStartedCompletedScanMethod") + } else { + it[0].equals("No data") + } + } + } + def "createWebApp"() { when: - webApp = new FoDWebAppSupplier().createWebApp(); + webApp.get(); then: noExceptionThrown() } def "createMicroserviceApp"() { when: - microservicesApp = new FoDWebAppSupplier().createMicroservicesApp(); + microservicesApp.get(); then: noExceptionThrown() } def "createMobileApp"() { when: - mobileApp = new FoDWebAppSupplier().createMobileApp(); + mobileApp.get(); then: noExceptionThrown() } def "get.byIdWebApp"() { - def args = "fod app get " + webApp.get("applicationId") + def args = "fod app get " + webApp.get().get("applicationId") when: def result = Fcli.run(args) then: verifyAll(result.stdout) { size()>2 - it[2].equals("applicationName: \"" + webApp.appName + ":" + webApp.versionName +"\"") + it[2].equals("applicationName: \"" + webApp.get().appName + "\"") } } def "get.byIdMobileApp"() { - def args = "fod app get " + mobileApp.get("applicationId") + def args = "fod app get " + mobileApp.get().get("applicationId") when: def result = Fcli.run(args) then: verifyAll(result.stdout) { size()>2 - it[2].equals("applicationName: \"" + mobileApp.appName + ":" + mobileApp.versionName +"\"") + it[2].equals("applicationName: \"" + mobileApp.get().appName + "\"") } } def "get.byIdMicroservicesApp"() { - def args = "fod app get " + microservicesApp.get("applicationId") + def args = "fod app get " + microservicesApp.get().get("applicationId") when: def result = Fcli.run(args) then: verifyAll(result.stdout) { size()>2 - it[2].equals("applicationName: \"" + microservicesApp.appName + ":" + microservicesApp.versionName +"\"") + it[2].equals("applicationName: \"" + microservicesApp.get().appName + "\"") } } def "get.byNameWebApp"() { - def args = "fod app get " + webApp.appName + def args = "fod app get " + webApp.get().appName when: def result = Fcli.run(args) then: verifyAll(result.stdout) { size()>2 - it[1].startsWith("applicationId: " + webApp.get("applicationId")) + it[1].startsWith("applicationId: " + webApp.get().get("applicationId")) } } def "get.byNameMobileApp"() { - def args = "fod app get " + mobileApp.appName + def args = "fod app get " + mobileApp.get().appName when: def result = Fcli.run(args) then: verifyAll(result.stdout) { size()>2 - it[1].startsWith("applicationId: " + mobileApp.get("applicationId")) + it[1].startsWith("applicationId: " + mobileApp.get().get("applicationId")) } } def "get.byNameMicroservicesApp"() { - def args = "fod app get " + microservicesApp.appName + def args = "fod app get " + microservicesApp.get().appName when: def result = Fcli.run(args) then: verifyAll(result.stdout) { size()>2 - it[1].startsWith("applicationId: " + microservicesApp.get("applicationId")) + it[1].startsWith("applicationId: " + microservicesApp.get().get("applicationId")) } } def "update"() { - def args = "fod app update " + webApp.appName + " --business-criticality High" + def args = "fod app update " + webApp.get().appName + " --business-criticality High" when: def result = Fcli.run(args) then: @@ -134,7 +150,7 @@ class FoDAppSpec extends FcliBaseSpec { } def "verifyUpdated"() { - def args = "fod app get " + webApp.get("applicationId") + def args = "fod app get " + webApp.get().get("applicationId") when: def result = Fcli.run(args) then: @@ -170,12 +186,12 @@ class FoDAppSpec extends FcliBaseSpec { def result = Fcli.run(args) then: verifyAll(result.stdout) { - !it.any { it.contains(webApp.appName) } - !it.any { it.contains(microservicesApp.appName) } - !it.any { it.contains(mobileApp.appName) } + !it.any { it.contains(webApp.get().appName) } + !it.any { it.contains(microservicesApp.get().appName) } + !it.any { it.contains(mobileApp.get().appName) } } } - */ + } diff --git a/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDReleaseSpec.groovy b/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDReleaseSpec.groovy index 622a6c8f30..9c826d8708 100644 --- a/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDReleaseSpec.groovy +++ b/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDReleaseSpec.groovy @@ -17,7 +17,7 @@ class FoDReleaseSpec extends FcliBaseSpec { @Shared @AutoCleanup FoDMicroservicesAppSupplier app = new FoDMicroservicesAppSupplier() def "list"() { - def args = "fod release list" + def args = "fod release list --store=releases" when: def result = Fcli.run(args) then: @@ -26,6 +26,36 @@ class FoDReleaseSpec extends FcliBaseSpec { it[0].replace(' ', '').equals("IdNameMicroserviceApplicationSDLCStatus") } } + + def "list-scans"() { + def args = "fod release list-scans --rel=::releases::get(0).releaseId" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=0 + if(size()>1) { + it[0].replace(' ', '').equals("IdTypeAnalysisStatusApplicationMicroserviceNameStartedCompletedScanMethod") + } else { + it[0].equals("No data") + } + } + } + + def "list-assessment-types"() { + def args = "fod release lsat --rel=::releases::get(0).releaseId" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=0 + if(size()>1) { + it[0].replace(' ', '').equals("IdNameScantypeFrequencytypeUnitsEntitlementidEntitlementdescription") + } else { + it[0].equals("No data") + } + } + } def "create"() { def args = "fod release create ${app.get().qualifiedMicroserviceName}:testrel --sdlc-status=Development --store testrel" diff --git a/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDScanSpec.groovy b/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDScanSpec.groovy index cad4b9ad12..9081726115 100644 --- a/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDScanSpec.groovy +++ b/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/FoDScanSpec.groovy @@ -2,36 +2,34 @@ package com.fortify.cli.ftest.fod; import static com.fortify.cli.ftest._common.spec.FcliSessionType.FOD -import com.fortify.cli.ftest._common.Fcli import com.fortify.cli.ftest._common.spec.FcliBaseSpec import com.fortify.cli.ftest._common.spec.FcliSession import com.fortify.cli.ftest._common.spec.Prefix import com.fortify.cli.ftest._common.spec.TestResource -import com.fortify.cli.ftest.fod._common.FoDWebAppSupplier -import com.fortify.cli.ftest.fod._common.FoDUserSupplier import com.fortify.cli.ftest.fod._common.FoDMobileAppSupplier -import com.fortify.cli.ftest.fod._common.FoDUserGroupSupplier +import com.fortify.cli.ftest.fod._common.FoDWebAppSupplier import spock.lang.AutoCleanup import spock.lang.Shared import spock.lang.Stepwise -import spock.lang.Unroll @Prefix("fod.scan") @FcliSession(FOD) @Stepwise class FoDScanSpec extends FcliBaseSpec { - /* + @Shared @TestResource("runtime/shared/EightBall-22.1.0.fpr") String sastResults @Shared @TestResource("runtime/shared/iwa_net_scandata.fpr") String dastResults @Shared @TestResource("runtime/shared/iwa_net_cyclonedx.json") String ossResults @Shared @TestResource("runtime/shared/iwa_mobile.fpr") String mobileResults - @Shared @TestResource("runtime/shared/EightBall-package.zip") String sastpackage + @Shared @TestResource("runtime/shared/EightBall-package.zip") String sastPackage + @Shared @TestResource("runtime/shared/HelloWorld.apk") String mastPackage + @Shared @TestResource("runtime/shared/oss_package.zip") String ossPackage @Shared @AutoCleanup FoDWebAppSupplier webApp = new FoDWebAppSupplier() @Shared @AutoCleanup FoDMobileAppSupplier mobileApp = new FoDMobileAppSupplier() - + /* def "import-sast"() { - def args = "fod sast-scan import --release=${webApp.get().qualifiedRelease} --file=$sastResults --store uploadsast" + def args = "fod sast-scan import --release=${webApp.get().qualifiedRelease} --file=$tar --store uploadsast" when: def result = Fcli.run(args) then: @@ -39,9 +37,11 @@ class FoDScanSpec extends FcliBaseSpec { size()>2 it.last().contains("IMPORT_REQUESTED") } + cleanup: + Files.delete(tar); } - - def "import-mobile"() { + /* + def "import-mast"() { def args = "fod mast-scan import --release=${mobileApp.get().qualifiedRelease} --file=$mobileResults --store uploadmast" when: def result = Fcli.run(args) @@ -74,7 +74,6 @@ class FoDScanSpec extends FcliBaseSpec { } } - def "waitForScans"() { when: def relScanurl = Fcli.run("fod release get ${webApp.get().qualifiedRelease} -o expr=/api/v3/releases/{releaseId}/scans --store relId").stdout[0] @@ -83,7 +82,8 @@ class FoDScanSpec extends FcliBaseSpec { def success = true; while(true){ def result = Fcli.run("fod rest call ${relScanurl}") - if(result.stdout.findAll{element -> element.contains("analysisStatusType: \"Completed\"")}.size()==3) { + if(result.stdout.findAll{ + element -> element.contains("analysisStatusType: \"Completed\"")}.size()==4) { success=true; break; } else if(System.currentTimeMillis()-start > timeoutMs) { @@ -97,7 +97,7 @@ class FoDScanSpec extends FcliBaseSpec { def "list.sast-scans"() { - def args = "fod sast-scan list --release=fcli-1698140484524:v1698140484524 --store sastscans" + def args = "fod sast-scan list --release=${webApp.get().qualifiedRelease} --store sastscans" when: def result = Fcli.run(args) then: @@ -118,17 +118,27 @@ class FoDScanSpec extends FcliBaseSpec { } } + def "setup.sast-scan"() { + def args = "fod sast-scan setup --assessment-type=Static\\ Assessment --audit-preference=Automated --frequency=SingleScan --technology-stack=Go --release=${webApp.get().qualifiedRelease}" + when: + def result = Fcli.run(args) + then: + def e = thrown(UnexpectedFcliResultException) + e.result.stderr.any { it.contains("the entitlement has expired") } + e.result.stdout.first().replace(" ", "").equals("AssessmenttypeidEntitlementidEntitlementfrequencytypeReleaseidTechnologystackidTechnologystackLanguagelevelidLanguagelevelOSSAnalysisAuditpreferencetypeIncludethirdpartylibrariesUsesourcecontrolScanbinaryBsitokenApplicationReleaseMicroserviceAction") + } + def "get-config.sast-scan"() { - def args = "fod sast-scan get-config --release=fcli-1698140484524:v1698140484524" + def args = "fod sast-scan get-config --release=${webApp.get().qualifiedRelease}" when: def result = Fcli.run(args) then: verifyAll(result.stdout) { size()>=2 - it.last().contains("state: \"Not configured\"") + it.last().contains("state: \"Configured\"") } } - + /* def "download.sast-scan-byId"() { def args = "fod sast-scan download ::sastscans::get(0).scanId -f=byId.fpr" when: @@ -141,7 +151,7 @@ class FoDScanSpec extends FcliBaseSpec { } def "download-latest.sast-scan"() { - def args = "fod sast-scan download-latest --release=fcli-1698140484524:v1698140484524 -f=latest.fpr" + def args = "fod sast-scan download-latest --release=${webApp.get().qualifiedRelease} -f=latest.fpr" when: def result = Fcli.run(args) then: @@ -151,8 +161,41 @@ class FoDScanSpec extends FcliBaseSpec { } } - def "start.sast-scan"() { - def args = "fod sast-scan download-latest --release=fcli-1698140484524:v1698140484524 -f=latest.fpr" + def "list.dast-scans"() { + def args = "fod dast-scan list --release=${webApp.get().qualifiedRelease} --store dastscans" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it[1].contains("FPRImport") + } + } + + def "get.dast-scan"() { + def args = "fod dast-scan get ::dastscans::get(0).scanId" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + //it.any {it.contains("applicationName: \"${webApp.get().appName}\"")} + } + } + + def "get-config.dast-scan"() { + def args = "fod dast-scan get-config --release=${webApp.get().qualifiedRelease}" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it.last().contains("state: \"Not configured\"") + } + } + + def "download.dast-scan-byId"() { + def args = "fod dast-scan download ::dastscans::get(0).scanId -f=byId.fpr" when: def result = Fcli.run(args) then: @@ -161,42 +204,218 @@ class FoDScanSpec extends FcliBaseSpec { it[1].contains("SCAN_DOWNLOADED") } } - /* - def "import-sast"() { - //get release id - def appRelId = Fcli.run("fod release get " + app.appName + ":" + app.versionName + " --store release") - def args = "fod scan import-sast ::release::releaseId -f " + sastResults + " --store upload" + + def "download-latest.dast-scan"() { + def args = "fod dast-scan download-latest --release=${webApp.get().qualifiedRelease} -f=latest.fpr" when: def result = Fcli.run(args) then: verifyAll(result.stdout) { - size()>2 - it[1].startsWith("startedByUserId: ") + size()>=2 + it[1].contains("SCAN_DOWNLOADED") + } + } + + def "list.mast-scans"() { + def args = "fod mast-scan list --release=${mobileApp.get().qualifiedRelease} --store mastscans" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it[1].contains("FPRImport") + } + } + + def "get.mast-scan"() { + def args = "fod mast-scan get ::mastscans::get(0).scanId" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + //it.any {it.contains("applicationName: \"${webApp.get().appName}\"")} + } + } + + def "get-config.mast-scan"() { + def args = "fod mast-scan get-config --release=${mobileApp.get().qualifiedRelease}" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it.last().contains("state: \"Not configured\"") + } + } + + def "download.mast-scan-byId"() { + def args = "fod mast-scan download ::mastscans::get(0).scanId -f=byId.fpr" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it[1].contains("SCAN_DOWNLOADED") + } + } + + def "download-latest.mast-scan"() { + def args = "fod mast-scan download-latest --release=${mobileApp.get().qualifiedRelease} -f=latest.fpr" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it[1].contains("SCAN_DOWNLOADED") + } + } + + def "list.oss-scans"() { + def args = "fod oss-scan list --release=${webApp.get().qualifiedRelease} --store ossscans" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it[1].contains("FPRImport") + } + } + + def "get.oss-scan"() { + def args = "fod oss-scan get ::ossscans::get(0).scanId" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + //it.any {it.contains("applicationName: \"${webApp.get().appName}\"")} + } + } + + def "get-config.oss-scan"() { + def args = "fod oss-scan get-config --release=${webApp.get().qualifiedRelease}" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it.last().contains("state: \"Not configured\"") + } + } + + def "download.oss-scan-byId"() { + def args = "fod oss-scan download ::ossscans::get(0).scanId -f=byId.fpr" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it[1].contains("SCAN_DOWNLOADED") + } + } + + def "download-latest.oss-scan"() { + def args = "fod oss-scan download-latest --release=${webApp.get().qualifiedRelease} -f=latest.fpr" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it[1].contains("SCAN_DOWNLOADED") + } + } + + def "start.sast-scan"() { + def args = "fod sast-scan start --release=fcli-1698140484524:v2 --file=$sastPackage --store sastScan" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it.last().contains("STARTED") } } - def "wait-for-import-sast"() { - def args = "fod scan wait-for ::upload:: -i 2s --until=all-match --any-scan-state=COMPLETED,CANCELLED,FAILED,RUNNING" + def "wait-for-sast"() { + def args = "fod sast-scan wait-for ::sastScan:: -i 2s --until=all-match --any-state=Completed,In_Progress,Queued" when: def result = Fcli.run(args) then: verifyAll(result.stdout) { // } - }*/ + } + + def "start.oss-scan"() { + def args = "fod oss-scan start --release=fcli-1698140484524:v2 --file=$ossPackage --store ossScan" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it.last().contains("STARTED") + } + } - /*the manpages description of scan-id is "Scan id(s)" implying the posibility - of providing multiple ids, this does not seem to work - def "get.byIdMultiple"() { - def scanId1= Fcli.run("util var contents scans -q scanId==#var('scans').get(0).scanId -o expr={scanId}"); - def scanId2= Fcli.run("util var contents scans -q scanId==#var('scans').get(1).scanId -o expr={scanId}"); - def args = "fod scan get " + scanId1.stdout[0] + "," + scanId2.stdout[0] + def "wait-for-oss"() { + def args = "fod oss-scan wait-for ::ossScan:: -i 2s --until=all-match --any-state=Completed,In_Progress,Queued" when: def result = Fcli.run(args) then: verifyAll(result.stdout) { - size()>2 - it[1].startsWith("userId: ") + // + } + } + + def "start.mast-scan"() { + def args = "fod mast-scan start --release=fcli-mobile:m1 --file=$mastPackage --assessment-type=Mobile\\ Assessment --framework=Android --frequency=Subscription --store mastScan" + when: + def result=null; + try { + result = Fcli.run(args) + } catch(UnexpectedFcliResultException e) { + if(e.result.stderr.any { it.contains("the entitlement has expired") }) { + result = e.result; + } else { + throw e; + } + } + then: + verifyAll(result.stdout) { + size()>=2 + it.last().contains("STARTED") + } + } + + def "wait-for-mast"() { + def args = "fod mast-scan wait-for ::mastScan:: -i 2s --until=all-match --any-state=Completed,In_Progress,Queued" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + // + } + } + /* currently not implemented, awaiting availability of automated dast scan on fod + def "start.dast-scan"() { + def args = "fod dast-scan start --release=fcli-1698140484524:v2 --store dastScan" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + size()>=2 + it.last().contains("STARTED") + } + } + + def "wait-for-dast"() { + def args = "fod dast-scan wait-for ::dastScan:: -i 2s --until=all-match --any-state=Completed,In_Progress,Queued" + when: + def result = Fcli.run(args) + then: + verifyAll(result.stdout) { + // } }*/ diff --git a/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/_common/FoDUserSupplier.groovy b/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/_common/FoDUserSupplier.groovy index fa625828a2..2e982fe565 100644 --- a/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/_common/FoDUserSupplier.groovy +++ b/fcli-other/fcli-functional-test/src/ftest/groovy/com/fortify/cli/ftest/fod/_common/FoDUserSupplier.groovy @@ -29,7 +29,7 @@ public class FoDUserSupplier extends AbstractCloseableEntitySupplier { public FoDUser create() { Fcli.run("fod rest lookup Roles --store roles") - Fcli.run("fod ac create-user $userName --email=test@test.test --firstname=test --lastname=user --phone=1234 --role=::roles::get(0).value " + + Fcli.run("fod ac create-user $userName --email=$random@test.test --firstname=test --lastname=user --phone=1234 --role=::roles::get(0).value " + "--store $variableName", {it.expectSuccess(true, "Unable to create user")}) return this diff --git a/fcli-other/fcli-functional-test/src/ftest/resources/runtime/shared/HelloWorld.apk b/fcli-other/fcli-functional-test/src/ftest/resources/runtime/shared/HelloWorld.apk new file mode 100644 index 0000000000..2cdf053915 Binary files /dev/null and b/fcli-other/fcli-functional-test/src/ftest/resources/runtime/shared/HelloWorld.apk differ diff --git a/fcli-other/fcli-functional-test/src/ftest/resources/runtime/shared/oss_package.zip b/fcli-other/fcli-functional-test/src/ftest/resources/runtime/shared/oss_package.zip new file mode 100644 index 0000000000..477d7b69f8 Binary files /dev/null and b/fcli-other/fcli-functional-test/src/ftest/resources/runtime/shared/oss_package.zip differ