diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c638f67a..2472ae737 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: pull_request: env: - GO_VERSION: '1.21.8' + GO_VERSION: '1.21.5' jobs: unit-tests: @@ -68,10 +68,10 @@ jobs: PR_GITHUB_REPO_NAME: "ast-cli" PR_GITHUB_NUMBER: 418 PR_GITLAB_TOKEN : ${{ secrets.PR_GITLAB_TOKEN }} - PR_GITLAB_NAMESPACE: ${{ secrets.PR_GITLAB_NAMESPACE }} - PR_GITLAB_REPO_NAME: ${{ secrets.PR_GITLAB_REPO_NAME }} - PR_GITLAB_PROJECT_ID: ${{ secrets.PR_GITLAB_PROJECT_ID }} - PR_GITLAB_IID: ${{ secrets.PR_GITLAB_IID }} + PR_GITLAB_NAMESPACE: "tiagobcx" + PR_GITLAB_REPO_NAME: "testProject" + PR_GITLAB_PROJECT_ID: 40227565 + PR_GITLAB_IID: 19 AZURE_ORG: ${{ secrets.AZURE_ORG }} AZURE_PROJECT: ${{ secrets.AZURE_PROJECT }} AZURE_REPOS: ${{ secrets.AZURE_REPOS }} @@ -116,7 +116,7 @@ jobs: go-version: ${{ env.GO_VERSION }} - run: go version - name: golangci-lint - uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc #v3 + uses: golangci/golangci-lint-action@v3 with: skip-pkg-cache: true version: v1.54.2 @@ -127,7 +127,7 @@ jobs: name: govulncheck steps: - id: govulncheck - uses: golang/govulncheck-action@7da72f730e37eeaad891fcff0a532d27ed737cd4 #v1 + uses: golang/govulncheck-action@v1 with: go-version-input: ${{ env.GO_VERSION }} go-package: ./... \ No newline at end of file diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index 0c4850b98..c64d58ceb 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@bfac3fa29cc6834ca2e3fd659343da191a65d971 # v1.3.1 + uses: dependabot/fetch-metadata@v1.3.1 with: github-token: "${{ secrets.GH_TOKEN }}" - name: Enable auto-merge for Dependabot PRs @@ -20,6 +20,6 @@ jobs: GITHUB_TOKEN: ${{secrets.GH_TOKEN}} run: gh pr merge --auto --merge "$PR_URL" - name: Auto approve dependabot PRs - uses: hmarr/auto-approve-action@7782c7e2bdf62b4d79bdcded8332808fd2f179cd #v2 + uses: hmarr/auto-approve-action@v2 with: github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} diff --git a/.github/workflows/jira_notify.yml b/.github/workflows/jira_notify.yml index 6fcd9547a..89f3744ba 100644 --- a/.github/workflows/jira_notify.yml +++ b/.github/workflows/jira_notify.yml @@ -27,7 +27,7 @@ jobs: JIRA_URL: "https://checkmarx.atlassian.net/" steps: - name: Jira Login - uses: atlassian/gajira-login@ca13f8850ea309cf44a6e4e0c49d9aa48ac3ca4c #v3 + uses: atlassian/gajira-login@v3 env: JIRA_BASE_URL: ${{ env.JIRA_URL }} JIRA_USER_EMAIL: ${{ secrets.AST_JIRA_USER_EMAIL }} @@ -35,7 +35,7 @@ jobs: - name: Jira Create issue id: create_jira_issue - uses: atlassian/gajira-create@1ff0b6bd115a780592b47bfbb63fc4629132e6ec #v3 + uses: atlassian/gajira-create@v3 with: project: AST issuetype: Task @@ -55,7 +55,7 @@ jobs: }) - name: Send a teams notification - uses: thechetantalwar/teams-notify@8a78811f5e8f58cdd204efebd79158006428c46b #v2 + uses: thechetantalwar/teams-notify@v2 with: teams_webhook_url: ${{ secrets.TEAMS_WEBHOOK_URI }} message: "Github issue created ${{ github.repository }} - Link - ${{inputs.html_url}} - Jira Issue - ${{ env.JIRA_URL }}/browse/${{ steps.create_jira_issue.outputs.issue }}" diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index bb1990ecd..c1ace59c0 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Delete release - uses: dev-drprasad/delete-tag-and-release@5eafd8668311bf3e4d6c1e9898f32a317103de68 #v0.2.1 + uses: dev-drprasad/delete-tag-and-release@v0.2.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/pr-label.yml b/.github/workflows/pr-label.yml index 8c7862108..8a2d8ac41 100644 --- a/.github/workflows/pr-label.yml +++ b/.github/workflows/pr-label.yml @@ -12,7 +12,7 @@ jobs: pull-requests: write # for TimonVS/pr-labeler-action to add labels in PR runs-on: ubuntu-latest steps: - - uses: TimonVS/pr-labeler-action@8447391d87bc7648ce6bf97159c17b642576afb0 #v3 + - uses: TimonVS/pr-labeler-action@v3 with: configuration-path: .github/pr-labeler.yml # optional, .github/pr-labeler.yml is the default value env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 17e999861..2ae7ecb22 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -45,7 +45,7 @@ jobs: with: go-version: '^1.21.5' - name: Import Code-Signing Certificates - uses: Apple-Actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071 #v1 + uses: Apple-Actions/import-codesign-certs@v1 with: # The certificates in a PKCS12 file encoded as a base64 string p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }} @@ -61,7 +61,8 @@ jobs: brew --version - name: Install gon run: | - brew install Bearer/tap/gon + brew tap mitchellh/gon + brew install mitchellh/gon/gon - name: Install and start docker if: inputs.dev == false run: | @@ -75,12 +76,12 @@ jobs: docker info - name: Login to Docker Hub if: inputs.dev == false - uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7 #v1 + uses: docker/login-action@v1 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 #v2 + uses: aws-actions/configure-aws-credentials@v2 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ secrets.AWS_ASSUME_ROLE_REGION }} @@ -104,7 +105,7 @@ jobs: - name: Echo GoReleaser Args run: echo ${{ env.GR_ARGS }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@b508e2e3ef3b19d4e4146d4f8fb3ba9db644a757 #v3 + uses: goreleaser/goreleaser-action@v3 with: version: v1.18.2 args: ${{ env.GR_ARGS }} @@ -130,7 +131,7 @@ jobs: - name: Converts Markdown to HTML id: convert - uses: lifepal/markdown-to-html@71ed74a56602597c05dd7dd0e561631557158ed5 #v1.1 + uses: lifepal/markdown-to-html@v1.1 with: text: "${{ steps.release.outputs.body_release }}" @@ -143,7 +144,7 @@ jobs: - name: Send a Notification id: notify - uses: thechetantalwar/teams-notify@8a78811f5e8f58cdd204efebd79158006428c46b #v2 + uses: thechetantalwar/teams-notify@v2 with: teams_webhook_url: ${{ secrets.TEAMS_WEBHOOK_URI }} message: "${{ steps.clean.outputs.clean }}" diff --git a/.golangci.yml b/.golangci.yml index ba0a3c767..47ec9efd7 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -60,7 +60,7 @@ linters-settings: misspell: locale: US linters: - # please, do not use `enable-all`: it's deprecated and will be removed soon. + # please, do not use `enable-all`: it's deprecated and will be removed soon. # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint disable-all: true enable: diff --git a/Dockerfile b/Dockerfile index 768e430d3..98228ffca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ -FROM alpine:3.19.1 +FROM alpine:3.19.0 -RUN apk add bash +RUN apk add --no-cache bash RUN adduser --system --disabled-password cxuser USER cxuser diff --git a/cmd/main.go b/cmd/main.go index 8ce4a8aa5..03dd653ef 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -32,7 +32,6 @@ func main() { groups := viper.GetString(params.GroupsPathKey) logs := viper.GetString(params.LogsPathKey) projects := viper.GetString(params.ProjectsPathKey) - applications := viper.GetString(params.ApplicationsPathKey) results := viper.GetString(params.ResultsPathKey) scanSummary := viper.GetString(params.ScanSummaryPathKey) scaPackage := viper.GetString(params.ScaPackagePathKey) @@ -50,7 +49,6 @@ func main() { featureFlagsPath := viper.GetString(params.FeatureFlagsKey) policyEvaluationPath := viper.GetString(params.PolicyEvaluationPathKey) sastMetadataPath := viper.GetString(params.SastMetadataPathKey) - accessManagementPath := viper.GetString(params.AccessManagementPathKey) scansWrapper := wrappers.NewHTTPScansWrapper(scans) resultsPdfReportsWrapper := wrappers.NewResultsPdfReportsHTTPWrapper(resultsPdfPath) @@ -59,7 +57,6 @@ func main() { logsWrapper := wrappers.NewLogsWrapper(logs) uploadsWrapper := wrappers.NewUploadsHTTPWrapper(uploads) projectsWrapper := wrappers.NewHTTPProjectsWrapper(projects) - applicationsWrapper := wrappers.NewApplicationsHTTPWrapper(applications) risksOverviewWrapper := wrappers.NewHTTPRisksOverviewWrapper(risksOverview) resultsWrapper := wrappers.NewHTTPResultsWrapper(results, scaPackage, scanSummary) authWrapper := wrappers.NewAuthHTTPWrapper() @@ -80,10 +77,8 @@ func main() { featureFlagsWrapper := wrappers.NewFeatureFlagsHTTPWrapper(featureFlagsPath) policyWrapper := wrappers.NewHTTPPolicyWrapper(policyEvaluationPath) sastMetadataWrapper := wrappers.NewSastIncrementalHTTPWrapper(sastMetadataPath) - accessManagementWrapper := wrappers.NewAccessManagementHTTPWrapper(accessManagementPath) astCli := commands.NewAstCLI( - applicationsWrapper, scansWrapper, resultsSbomReportsWrapper, resultsPdfReportsWrapper, @@ -111,7 +106,6 @@ func main() { featureFlagsWrapper, policyWrapper, sastMetadataWrapper, - accessManagementWrapper, ) exitListener() err = astCli.Execute() diff --git a/go.mod b/go.mod index 4e16b4478..2d3f021b9 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/checkmarx/ast-cli -go 1.21.8 +go 1.21.5 require ( github.com/MakeNowJust/heredoc v1.0.0 @@ -8,14 +8,14 @@ require ( github.com/golang-jwt/jwt v3.2.2+incompatible github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 - github.com/google/uuid v1.6.0 + github.com/google/uuid v1.5.0 github.com/gookit/color v1.5.4 github.com/mssola/user_agent v0.6.0 github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 - golang.org/x/crypto v0.21.0 + golang.org/x/crypto v0.18.0 golang.org/x/text v0.14.0 gotest.tools v2.2.0+incompatible ) @@ -39,8 +39,7 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/sys v0.18.0 // indirect + golang.org/x/sys v0.16.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - -) \ No newline at end of file +) diff --git a/go.sum b/go.sum index 6f08f88e2..5dcb04082 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -83,20 +83,10 @@ go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= -golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= -golang.org/x/crypto v0.20.1-0.20240228204720-0d2316b26734 h1:HutZC8sRIg57ztz3rVaQYl4yxgM+UF0Jal0kAWUSeFU= -golang.org/x/crypto v0.20.1-0.20240228204720-0d2316b26734/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/gon b/gon index 5b5cac869..cca60664f 100755 Binary files a/gon and b/gon differ diff --git a/gonMac.hcl b/gonMac.hcl index f7707915b..4ce752ebf 100644 --- a/gonMac.hcl +++ b/gonMac.hcl @@ -4,7 +4,7 @@ bundle_id = "com.checkmarx.cli" apple_id { username = "tiago.baptista@checkmarx.com" - provider = "Z68SAQG5BR" + password = "@env:AC_PASSWORD" } sign { diff --git a/internal/commands/.scripts/integration_down.sh b/internal/commands/.scripts/integration_down.sh old mode 100755 new mode 100644 diff --git a/internal/commands/.scripts/integration_up.sh b/internal/commands/.scripts/integration_up.sh old mode 100755 new mode 100644 index 7b16af05d..c503ee3af --- a/internal/commands/.scripts/integration_up.sh +++ b/internal/commands/.scripts/integration_up.sh @@ -13,7 +13,7 @@ rm -rf ScaResolver-linux64.tar.gz go test \ -tags integration \ -v \ - -timeout 90m \ + -timeout 60m \ -coverpkg github.com/checkmarx/ast-cli/internal/commands,github.com/checkmarx/ast-cli/internal/wrappers \ -coverprofile cover.out \ github.com/checkmarx/ast-cli/test/integration diff --git a/internal/commands/chat-kics.go b/internal/commands/chat-kics.go index 25e2461af..34f9e8a3e 100644 --- a/internal/commands/chat-kics.go +++ b/internal/commands/chat-kics.go @@ -48,11 +48,10 @@ type OutputModel struct { func ChatKicsSubCommand(chatWrapper wrappers.ChatWrapper) *cobra.Command { chatKicsCmd := &cobra.Command{ - Use: "kics", - Short: "Chat about KICS result with OpenAI models", - Long: "Chat about KICS result with OpenAI models", - Hidden: true, - RunE: runChatKics(chatWrapper), + Use: "kics", + Short: "Chat about KICS result with OpenAI models", + Long: "Chat about KICS result with OpenAI models", + RunE: runChatKics(chatWrapper), } chatKicsCmd.Flags().String(params.ChatAPIKey, "", "OpenAI API key") diff --git a/internal/commands/chat-sast.go b/internal/commands/chat-sast.go index 88ceb623f..b37d6ad48 100644 --- a/internal/commands/chat-sast.go +++ b/internal/commands/chat-sast.go @@ -2,8 +2,8 @@ package commands import ( "fmt" - "strconv" + "github.com/checkmarx/ast-cli/internal/commands/chatsast" "github.com/checkmarx/ast-cli/internal/commands/util/printer" "github.com/checkmarx/ast-cli/internal/logger" "github.com/checkmarx/ast-cli/internal/params" @@ -20,15 +20,13 @@ import ( const ScanResultsFileErrorFormat = "Error reading and parsing scan results %s" const CreatePromptErrorFormat = "Error creating prompt for result ID %s" const UserInputRequiredErrorFormat = "%s is required when %s is provided" -const AiGuidedRemediationDisabledError = "The AI Guided Remediation is disabled in your tenant account" -func ChatSastSubCommand(chatWrapper wrappers.ChatWrapper, tenantWrapper wrappers.TenantConfigurationWrapper) *cobra.Command { +func ChatSastSubCommand(chatWrapper wrappers.ChatWrapper) *cobra.Command { chatSastCmd := &cobra.Command{ - Use: "sast", - Short: "OpenAI-based SAST results remediation", - Long: "Use OpenAI models to remediate SAST results and chat about them", - Hidden: true, - RunE: runChatSast(chatWrapper, tenantWrapper), + Use: "sast", + Short: "OpenAI-based SAST results remediation", + Long: "Use OpenAI models to remediate SAST results and chat about them", + RunE: runChatSast(chatWrapper), } chatSastCmd.Flags().String(params.ChatAPIKey, "", "OpenAI API key") @@ -47,11 +45,8 @@ func ChatSastSubCommand(chatWrapper wrappers.ChatWrapper, tenantWrapper wrappers return chatSastCmd } -func runChatSast(chatWrapper wrappers.ChatWrapper, tenantWrapper wrappers.TenantConfigurationWrapper) func(cmd *cobra.Command, args []string) error { +func runChatSast(chatWrapper wrappers.ChatWrapper) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { - if !isAiGuidedRemediationEnabled(tenantWrapper) { - return outputError(cmd, uuid.Nil, errors.Errorf(AiGuidedRemediationDisabledError)) - } chatAPIKey, _ := cmd.Flags().GetString(params.ChatAPIKey) chatConversationID, _ := cmd.Flags().GetString(params.ChatConversationID) chatModel, _ := cmd.Flags().GetString(params.ChatModel) @@ -109,8 +104,6 @@ func runChatSast(chatWrapper wrappers.ChatWrapper, tenantWrapper wrappers.Tenant responseContent := getMessageContents(response) - responseContent = addDescriptionForIdentifier(responseContent) - return printer.Print(cmd.OutOrStdout(), &OutputModel{ ConversationID: id.String(), Response: responseContent, @@ -118,27 +111,8 @@ func runChatSast(chatWrapper wrappers.ChatWrapper, tenantWrapper wrappers.Tenant } } -func isAiGuidedRemediationEnabled(tenantWrapper wrappers.TenantConfigurationWrapper) bool { - tenantConfigurationResponse, errorModel, err := tenantWrapper.GetTenantConfiguration() - if err != nil { - return false - } - if errorModel != nil { - return false - } - if tenantConfigurationResponse != nil { - for _, resp := range *tenantConfigurationResponse { - if resp.Key == AiGuidedRemediationEnabled { - isEnabled, _ := strconv.ParseBool(resp.Value) - return isEnabled - } - } - } - return false -} - func buildPrompt(scanResultsFile, sastResultID, sourceDir string) (systemPrompt, userPrompt string, err error) { - scanResults, err := ReadResultsSAST(scanResultsFile) + scanResults, err := chatsast.ReadResultsSAST(scanResultsFile) if err != nil { return "", "", fmt.Errorf("error in build-prompt: %s: %w", fmt.Sprintf(ScanResultsFileErrorFormat, scanResultsFile), err) } @@ -147,22 +121,22 @@ func buildPrompt(scanResultsFile, sastResultID, sourceDir string) (systemPrompt, return "", "", errors.Errorf(fmt.Sprintf("error in build-prompt: currently only --%s is supported", params.ChatSastResultID)) } - sastResult, err := GetResultByID(scanResults, sastResultID) + sastResult, err := chatsast.GetResultByID(scanResults, sastResultID) if err != nil { return "", "", fmt.Errorf("error in build-prompt: %w", err) } - sources, err := GetSourcesForResult(sastResult, sourceDir) + sources, err := chatsast.GetSourcesForResult(sastResult, sourceDir) if err != nil { return "", "", fmt.Errorf("error in build-prompt: %w", err) } - prompt, err := CreateUserPrompt(sastResult, sources) + prompt, err := chatsast.CreateUserPrompt(sastResult, sources) if err != nil { return "", "", fmt.Errorf("error in build-prompt: %s: %w", fmt.Sprintf(CreatePromptErrorFormat, sastResultID), err) } - return GetSystemPrompt(), prompt, nil + return chatsast.GetSystemPrompt(), prompt, nil } func getMessageContents(response []message.Message) []string { diff --git a/internal/commands/chat-sast_test.go b/internal/commands/chat-sast_test.go index 6673a8e34..fff40ff1e 100644 --- a/internal/commands/chat-sast_test.go +++ b/internal/commands/chat-sast_test.go @@ -6,8 +6,6 @@ import ( "strings" "testing" - "github.com/checkmarx/ast-cli/internal/wrappers" - "github.com/checkmarx/ast-cli/internal/wrappers/mock" "github.com/google/uuid" "gotest.tools/assert" ) @@ -71,30 +69,6 @@ func TestChatSastInvalideResultId(t *testing.T) { assert.Assert(t, strings.Contains(s, "result ID invalidResultId not found"), s) } -func TestChatSastAiGuidedRemediationDisabled(t *testing.T) { - mock.TenantConfiguration = []*wrappers.TenantConfigurationResponse{{ - Key: "scan.config.plugins.ideScans", - Value: "true", - }, - { - Key: "scan.config.plugins.aiGuidedRemediation", - Value: "false", - }, - } - - buffer, err := executeRedirectedTestCommand("chat", "sast", - "--chat-apikey", "apiKey", - "--scan-results-file", "./data/cx_result.json", - "--source-dir", "dir", - "--sast-result-id", "13588362") - assert.NilError(t, err) - output, err := io.ReadAll(buffer) - assert.NilError(t, err) - s := string(output) - assert.Assert(t, strings.Contains(s, AiGuidedRemediationDisabledError), s) - mock.TenantConfiguration = []*wrappers.TenantConfigurationResponse{} -} - func TestChatSastInvalidSourceDir(t *testing.T) { buffer, err := executeRedirectedTestCommand("chat", "sast", "--chat-apikey", "apiKey", diff --git a/internal/commands/chat.go b/internal/commands/chat.go index 28c205462..0a188b8cb 100644 --- a/internal/commands/chat.go +++ b/internal/commands/chat.go @@ -5,20 +5,16 @@ import ( "github.com/spf13/cobra" ) -const ( - ConversationIDErrorFormat = "Invalid conversation ID %s" - AiGuidedRemediationEnabled = "scan.config.plugins.aiGuidedRemediation" -) +const ConversationIDErrorFormat = "Invalid conversation ID %s" -func NewChatCommand(chatWrapper wrappers.ChatWrapper, tenantWrapper wrappers.TenantConfigurationWrapper) *cobra.Command { +func NewChatCommand(chatWrapper wrappers.ChatWrapper) *cobra.Command { chatCmd := &cobra.Command{ - Use: "chat", - Short: "Chat with OpenAI models", - Long: "Chat with OpenAI models regarding KICS or SAST results", - Hidden: true, + Use: "chat", + Short: "Chat with OpenAI models", + Long: "Chat with OpenAI models regarding KICS or SAST results", } chatKicsCmd := ChatKicsSubCommand(chatWrapper) - chatSastCmd := ChatSastSubCommand(chatWrapper, tenantWrapper) + chatSastCmd := ChatSastSubCommand(chatWrapper) chatCmd.AddCommand(chatKicsCmd, chatSastCmd) return chatCmd diff --git a/internal/commands/sast-prompt.go b/internal/commands/chatsast/sast-prompt.go similarity index 70% rename from internal/commands/sast-prompt.go rename to internal/commands/chatsast/sast-prompt.go index f6f85dd55..bc2e1bdaa 100644 --- a/internal/commands/sast-prompt.go +++ b/internal/commands/chatsast/sast-prompt.go @@ -1,4 +1,4 @@ -package commands +package chatsast import ( "fmt" @@ -11,29 +11,13 @@ about the results. You should also be capable of delivering clear, concise, and If a question irrelevant to the mentioned source code or SAST result is asked, answer 'I am the AI Guided Remediation assistant and can answer only on questions related to source code or SAST results or SAST Queries'.` -const ( - confidence = "**CONFIDENCE:**" - explanation = "**EXPLANATION:**" - fix = "**PROPOSED REMEDIATION:**" - code = "```" -) - -const ( - confidenceDescription = " A score between 0 (low) and 100 (high) indicating the degree of confidence in the exploitability of this vulnerability in the context of your code.
" - explanationDescription = " An OpenAI generated description of the vulnerability.
" - fixDescription = " A customized snippet, generated by OpenAI, that can be used to remediate the vulnerability in your code.
" -) - -// This constant is used to format the identifiers (confidence, explanation, fix) and their descriptions with HTML tags -const identifierTitleForamt = "%s%s" - const userPromptTemplate = `Checkmarx Static Application Security Testing (SAST) detected the %s vulnerability within the provided %s code snippet. The attack vector is presented by code snippets annotated by comments in the form ` + "`//SAST Node #X: element (element-type)`" + ` where X is the node index in the result, ` + "`element`" + ` is the name of the element through which the data flows, and the ` + "`element-type`" + ` is it's type. The first and last nodes are indicated by ` + "`(input ...)` and `(output ...)`" + ` respectively: -` + code + ` +` + "```" + ` %s -` + code + ` +` + "```" + ` Please review the code above and provide a confidence score ranging from 0 to 100. A score of 0 means you believe the result is completely incorrect, unexploitable, and a false positive. A score of 100 means you believe the result is completely correct, exploitable, and a true positive. @@ -51,15 +35,12 @@ or it's a false positive. Please provide a brief explanation for your confidence score, don't mention all the instruction above. -Next, please provide code that remediates the vulnerability so that a developer can copy paste instead of the snippet above. +Next, please provide code that fixes the vulnerability so that a developer can copy paste instead of the snippet above. -Your analysis MUST be presented in the following format: -` + confidence + - `number -` + "\n" + explanation + - `short_text -` + "\n" + fix + ":" + - `fixed_snippet` +Your analysis should be presented in the following format: + CONFIDENCE: num + EXPLANATION: short_text + FIX: fixed_snippet` func GetSystemPrompt() string { return systemPrompt @@ -102,17 +83,7 @@ func createSourceForPrompt(result *Result, sources map[string][]string) (string, } else { edge = "" } - - // change UnknownReference to something more informational like VariableReference or TypeNameReference - nodeType := node.DomType - if node.DomType == "UnknownReference" { - if node.TypeName == "" { - nodeType = "VariableReference" - } else { - nodeType = node.TypeName + "Reference" - } - } - methodLines[lineInMethod] += fmt.Sprintf("//SAST Node #%d%s: %s (%s)", i, edge, node.Name, nodeType) + methodLines[lineInMethod] += fmt.Sprintf("//SAST Node #%d%s: %s (%s)", i, edge, node.Name, node.DomType) methodsInPrompt[sourceFilename+":"+node.Method] = methodLines } @@ -146,23 +117,3 @@ func GetMethodByMethodLine(filename string, lines []string, methodLineNumber, no } return methodLines, nil } - -func addDescriptionForIdentifier(responseContent []string) []string { - identifiersDescription := map[string]string{ - confidence: confidenceDescription, - explanation: explanationDescription, - fix: fixDescription, - } - if len(responseContent) > 0 { - for i := 0; i < len(responseContent); i++ { - for identifier, description := range identifiersDescription { - responseContent[i] = replaceIdentifierTitleIfNeeded(responseContent[i], identifier, description) - } - } - } - return responseContent -} - -func replaceIdentifierTitleIfNeeded(input, identifier, identifierDescription string) string { - return strings.Replace(input, identifier, fmt.Sprintf(identifierTitleForamt, identifier, identifierDescription), 1) -} diff --git a/internal/commands/sast-results-json.go b/internal/commands/chatsast/sast-results-json.go similarity index 93% rename from internal/commands/sast-results-json.go rename to internal/commands/chatsast/sast-results-json.go index 8c8e64963..6b4959891 100644 --- a/internal/commands/sast-results-json.go +++ b/internal/commands/chatsast/sast-results-json.go @@ -1,4 +1,4 @@ -package commands +package chatsast import ( "encoding/json" @@ -87,6 +87,22 @@ type ScanResults struct { ScanID string `json:"scanID"` } +func ReadResultsAll(filename string) (*ScanResults, error) { + bytes, err := os.ReadFile(filename) + if err != nil { + return nil, err + } + + // Unmarshal the JSON data into the ScanResults struct + var scanResults ScanResults + err = json.Unmarshal(bytes, &scanResults) + if err != nil { + return nil, err + } + + return &scanResults, nil +} + func ReadResultsSAST(filename string) (*ScanResults, error) { bytes, err := os.ReadFile(filename) if err != nil { diff --git a/internal/commands/sast-sources.go b/internal/commands/chatsast/sast-sources.go similarity index 63% rename from internal/commands/sast-sources.go rename to internal/commands/chatsast/sast-sources.go index ece464391..4846b9852 100644 --- a/internal/commands/sast-sources.go +++ b/internal/commands/chatsast/sast-sources.go @@ -1,4 +1,4 @@ -package commands +package chatsast import ( "bufio" @@ -22,6 +22,26 @@ func GetSourcesForResult(scanResult *Result, sourceDir string) (map[string][]str return fileContents, nil } +func GetSourcesForQuery(scanResults *ScanResults, sourceDir, language, query string) (map[string][]string, error) { + sourceFilenames := make(map[string]bool) + for _, scanResult := range scanResults.Results { + if scanResult.Data.LanguageName != language || scanResult.Data.QueryName != query { + continue + } + for i := range scanResult.Data.Nodes { + sourceFilename := strings.ReplaceAll(scanResult.Data.Nodes[i].FileName, "\\", "/") + sourceFilenames[sourceFilename] = true + } + } + + fileContents, err := GetFileContents(sourceFilenames, sourceDir) + if err != nil { + return nil, err + } + + return fileContents, nil +} + func GetFileContents(filenames map[string]bool, sourceDir string) (map[string][]string, error) { fileContents := make(map[string][]string) diff --git a/internal/commands/groups.go b/internal/commands/groups.go deleted file mode 100644 index 67dfd24c0..000000000 --- a/internal/commands/groups.go +++ /dev/null @@ -1,111 +0,0 @@ -package commands - -import ( - "encoding/json" - "strings" - - commonParams "github.com/checkmarx/ast-cli/internal/params" - "github.com/checkmarx/ast-cli/internal/wrappers" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -const accessManagementEnabled = "ACCESS_MANAGEMENT_ENABLED" // feature flag - -func createGroupsMap(groupsStr string, groupsWrapper wrappers.GroupsWrapper) ([]*wrappers.Group, error) { - groups := strings.Split(groupsStr, ",") - var groupsMap []*wrappers.Group - var groupsNotFound []string - for _, group := range groups { - if len(group) > 0 { - groupsFromEnv, err := groupsWrapper.Get(group) - if err != nil { - groupsNotFound = append(groupsNotFound, group) - } else { - findGroup := findGroupByName(groupsFromEnv, group) - if findGroup != nil && findGroup.Name != "" { - groupsMap = append(groupsMap, findGroup) - } else { - groupsNotFound = append(groupsNotFound, group) - } - } - } - } - if len(groupsNotFound) > 0 { - return nil, errors.Errorf("%s: %v", failedFindingGroup, groupsNotFound) - } - return groupsMap, nil -} - -func findGroupByName(groups []wrappers.Group, name string) *wrappers.Group { - for i := 0; i < len(groups); i++ { - if groups[i].Name == name { - return &groups[i] - } - } - return nil -} - -func updateGroupValues(input *[]byte, cmd *cobra.Command, groupsWrapper wrappers.GroupsWrapper) ([]*wrappers.Group, error) { - groupListStr, _ := cmd.Flags().GetString(commonParams.GroupList) - groups, err := createGroupsMap(groupListStr, groupsWrapper) - if err != nil { - return groups, err - } - if !wrappers.FeatureFlags[accessManagementEnabled] { - var info map[string]interface{} - _ = json.Unmarshal(*input, &info) - info["groups"] = getGroupIds(groups) - *input, _ = json.Marshal(info) - } - return groups, nil -} -func getGroupsForRequest(groups []*wrappers.Group) []string { - if !wrappers.FeatureFlags[accessManagementEnabled] { - return getGroupIds(groups) - } - return nil -} -func getGroupIds(groups []*wrappers.Group) []string { - var groupIds []string - for _, group := range groups { - groupIds = append(groupIds, group.ID) - } - return groupIds -} - -func assignGroupsToProject(projectID string, projectName string, groups []*wrappers.Group, - accessManagement wrappers.AccessManagementWrapper) error { - if !wrappers.FeatureFlags[accessManagementEnabled] { - return nil - } - groupsAssignedToTheProject, err := accessManagement.GetGroups(projectID) - if err != nil { - return err - } - groupsToAssign := getGroupsToAssign(groups, groupsAssignedToTheProject) - if len(groupsToAssign) == 0 { - return nil - } - - err = accessManagement.CreateGroupsAssignment(projectID, projectName, groupsToAssign) - if err != nil { - return err - } - return nil -} - -func getGroupsToAssign(receivedGroups, existingGroups []*wrappers.Group) []*wrappers.Group { - var groupsToAssign []*wrappers.Group - var groupsMap = make(map[string]bool) - for _, existingGroup := range existingGroups { - groupsMap[existingGroup.ID] = true - } - for _, receivedGroup := range receivedGroups { - find := groupsMap[receivedGroup.ID] - if !find { - groupsToAssign = append(groupsToAssign, receivedGroup) - } - } - return groupsToAssign -} diff --git a/internal/commands/groups_test.go b/internal/commands/groups_test.go deleted file mode 100644 index 4b507908b..000000000 --- a/internal/commands/groups_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package commands - -import ( - "testing" - - "github.com/checkmarx/ast-cli/internal/wrappers" - "github.com/checkmarx/ast-cli/internal/wrappers/mock" -) - -func TestCreateScanAndProjectWithGroupFFTrue(t *testing.T) { - mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "ACCESS_MANAGEMENT_ENABLED", Status: true}} - execCmdNilAssertion( - t, - "scan", "create", "--project-name", "new-project", "-b", "dummy_branch", "-s", ".", "--project-groups", "group", - ) -} - -func TestCreateScanAndProjectWithGroupFFFalse(t *testing.T) { - mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "ACCESS_MANAGEMENT_ENABLED", Status: false}} - execCmdNilAssertion( - t, - "scan", "create", "--project-name", "new-project", "-b", "dummy_branch", "-s", ".", "--project-groups", "group", - ) -} -func TestCreateProjectWithGroupFFTrue(t *testing.T) { - mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "ACCESS_MANAGEMENT_ENABLED", Status: true}} - execCmdNilAssertion( - t, "project", "create", "--project-name", "new-project", "--groups", "group", - ) -} - -func TestCreateProjectWithGroupFFFalse(t *testing.T) { - mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "ACCESS_MANAGEMENT_ENABLED", Status: false}} - execCmdNilAssertion( - t, - "project", "create", "--project-name", "new-project", "--groups", "group", - ) -} - -func TestCreateScanForExistingProjectWithGroupFFTrue(t *testing.T) { - mock.Flags = wrappers.FeatureFlagsResponseModel{{Name: "ACCESS_MANAGEMENT_ENABLED", Status: true}} - execCmdNilAssertion( - t, - "scan", "create", "--project-name", "MOCK", "-b", "dummy_branch", "-s", ".", "--project-groups", "group", - ) -} diff --git a/internal/commands/policymanagement/policy.go b/internal/commands/policymanagement/policy.go deleted file mode 100644 index 9c9df3446..000000000 --- a/internal/commands/policymanagement/policy.go +++ /dev/null @@ -1,121 +0,0 @@ -package policymanagement - -import ( - "fmt" - "log" - "math" - "time" - - "github.com/checkmarx/ast-cli/internal/logger" - commonParams "github.com/checkmarx/ast-cli/internal/params" - "github.com/checkmarx/ast-cli/internal/wrappers" - "github.com/spf13/cobra" - "github.com/spf13/viper" -) - -const ( - failedGetting = "Failed showing a scan" - maxPollingWaitTime = 60 - completedPolicy = "COMPLETED" - nonePolicy = "NONE" - evaluatingPolicy = "EVALUATING" -) - -func HandlePolicyWait( - waitDelay, - timeoutMinutes int, - policyWrapper wrappers.PolicyWrapper, - scanID, - projectID string, - cmd *cobra.Command, -) (*wrappers.PolicyResponseModel, error) { - policyResponseModel, err := waitForPolicyCompletion( - waitDelay, - timeoutMinutes, - policyWrapper, - scanID, - projectID, - cmd) - if err != nil { - verboseFlag, _ := cmd.Flags().GetBool(commonParams.DebugFlag) - if verboseFlag { - logger.PrintIfVerbose("Policy evaluation failed") - } - return nil, err - } - return policyResponseModel, nil -} - -func waitForPolicyCompletion( - waitDelay int, - timeoutMinutes int, - policyWrapper wrappers.PolicyWrapper, - scanID, - projectID string, - cmd *cobra.Command, -) (*wrappers.PolicyResponseModel, error) { - logger.PrintIfVerbose("Waiting for policy evaluation to complete for scanID:" + scanID + " and projectID:" + projectID) - var policyResponseModel *wrappers.PolicyResponseModel - timeout := time.Now().Add(time.Duration(timeoutMinutes) * time.Minute) - fixedWait := time.Duration(waitDelay) * time.Second - i := uint64(0) - if !cmd.Flags().Changed(commonParams.RetryDelayFlag) { - viper.Set(commonParams.RetryDelayFlag, commonParams.RetryDelayPollingDefault) - } - for { - variableWait := time.Duration(math.Min(float64(i/uint64(waitDelay)), maxPollingWaitTime)) * time.Second - waitDuration := fixedWait + variableWait - logger.PrintfIfVerbose("Sleeping %v before polling", waitDuration) - time.Sleep(waitDuration) - evaluated := false - var err error - evaluated, policyResponseModel, err = isPolicyEvaluated(policyWrapper, scanID, projectID) - if err != nil { - return nil, err - } - if evaluated { - break - } - if timeoutMinutes > 0 && time.Now().After(timeout) { - logger.PrintfIfVerbose("Timeout of %d minute(s) for policy evaluation reached", timeoutMinutes) - return nil, nil - } - i++ - } - logger.PrintIfVerbose("Policy evaluation completed with status" + policyResponseModel.Status) - return policyResponseModel, nil -} - -func isPolicyEvaluated( - policyWrapper wrappers.PolicyWrapper, - scanID, - projectID string, -) (bool, *wrappers.PolicyResponseModel, error) { - var errorModel *wrappers.WebError - var err error - var policyResponseModel *wrappers.PolicyResponseModel - var params = make(map[string]string) - - params["scanId"] = scanID - params["astProjectId"] = projectID - - policyResponseModel, errorModel, err = policyWrapper.EvaluatePolicy(params) - if err != nil { - return false, nil, err - } - if errorModel != nil { - log.Fatalf(fmt.Sprintf("%s: CODE: %d, %s", failedGetting, errorModel.Code, errorModel.Message)) - } else if policyResponseModel != nil { - if policyResponseModel.Status == evaluatingPolicy { - log.Println("Policy status: ", policyResponseModel.Status) - return false, nil, nil - } - } - // Case the policy is evaluated or None - logger.PrintIfVerbose("Policy evaluation finished with status: " + policyResponseModel.Status) - if policyResponseModel.Status == completedPolicy || policyResponseModel.Status == nonePolicy { - logger.PrintIfVerbose("Policy status: " + policyResponseModel.Status) - return true, policyResponseModel, nil - } - return true, nil, nil -} diff --git a/internal/commands/project.go b/internal/commands/project.go index d95638499..79256295c 100644 --- a/internal/commands/project.go +++ b/internal/commands/project.go @@ -6,8 +6,6 @@ import ( "strings" "time" - applicationErrors "github.com/checkmarx/ast-cli/internal/errors" - "github.com/MakeNowJust/heredoc" "github.com/checkmarx/ast-cli/internal/commands/util" "github.com/checkmarx/ast-cli/internal/commands/util/printer" @@ -63,8 +61,7 @@ var ( ) ) -func NewProjectCommand(applicationsWrapper wrappers.ApplicationsWrapper, projectsWrapper wrappers.ProjectsWrapper, groupsWrapper wrappers.GroupsWrapper, - accessManagementWrapper wrappers.AccessManagementWrapper) *cobra.Command { +func NewProjectCommand(projectsWrapper wrappers.ProjectsWrapper, groupsWrapper wrappers.GroupsWrapper) *cobra.Command { projCmd := &cobra.Command{ Use: "project", Short: "Manage projects", @@ -94,7 +91,7 @@ func NewProjectCommand(applicationsWrapper wrappers.ApplicationsWrapper, project `, ), }, - RunE: runCreateProjectCommand(applicationsWrapper, projectsWrapper, groupsWrapper, accessManagementWrapper), + RunE: runCreateProjectCommand(projectsWrapper, groupsWrapper), } createProjCmd.PersistentFlags().String(commonParams.TagList, "", "List of tags, ex: (tagA,tagB:val,etc)") createProjCmd.PersistentFlags().String(commonParams.GroupList, "", "List of groups, ex: (PowerUsers,etc)") @@ -102,7 +99,6 @@ func NewProjectCommand(applicationsWrapper wrappers.ApplicationsWrapper, project createProjCmd.PersistentFlags().StringP(commonParams.MainBranchFlag, "", "", "Main branch") createProjCmd.PersistentFlags().String(commonParams.SSHKeyFlag, "", "Path to ssh private key") createProjCmd.PersistentFlags().String(commonParams.RepoURLFlag, "", "Repository URL") - createProjCmd.PersistentFlags().String(commonParams.ApplicationName, "", "Name of the application to assign with the project") listProjectsCmd := &cobra.Command{ Use: "list", @@ -226,37 +222,75 @@ func updateProjectRequestValues(input *[]byte, cmd *cobra.Command) error { return nil } -func runCreateProjectCommand( - applicationsWrapper wrappers.ApplicationsWrapper, - projectsWrapper wrappers.ProjectsWrapper, - groupsWrapper wrappers.GroupsWrapper, - accessManagementWrapper wrappers.AccessManagementWrapper, -) func(cmd *cobra.Command, args []string) error { - return func(cmd *cobra.Command, args []string) error { - applicationName, err := cmd.Flags().GetString(commonParams.ApplicationName) - if err != nil { - return err - } +func updateGroupValues(input *[]byte, cmd *cobra.Command, groupsWrapper wrappers.GroupsWrapper) error { + groupListStr, _ := cmd.Flags().GetString(commonParams.GroupList) + + var groupMap []string + var info map[string]interface{} + _ = json.Unmarshal(*input, &info) + if _, ok := info["groups"]; !ok { + _ = json.Unmarshal([]byte("[]"), &groupMap) + info["groups"] = groupMap + } + groups, err := createGroupsMap(groupListStr, groupsWrapper) + if err != nil { + return err + } + + info["groups"] = groups + *input, _ = json.Marshal(info) - var applicationID []string + return nil +} - if applicationName != "" { - application, getAppErr := getApplication(applicationName, applicationsWrapper) - if getAppErr != nil { - return getAppErr - } - if application == nil { - return errors.Errorf(applicationErrors.ApplicationDoesntExistOrNoPermission) +func createGroupsMap(groupsStr string, groupsWrapper wrappers.GroupsWrapper) ([]string, error) { + groups := strings.Split(groupsStr, ",") + var groupMap []string + var groupsNotFound []string + for _, group := range groups { + if len(group) > 0 { + groupIds, err := groupsWrapper.Get(group) + if err != nil { + groupsNotFound = append(groupsNotFound, group) + } else { + groupID := findGroupID(groupIds, group) + if groupID != "" { + groupMap = append(groupMap, groupID) + } else { + groupsNotFound = append(groupsNotFound, group) + } } - applicationID = []string{application.ID} } + } + + if len(groupsNotFound) > 0 { + return nil, errors.Errorf("%s: %v", failedFindingGroup, groupsNotFound) + } + + return groupMap, nil +} +func findGroupID(groups []wrappers.Group, name string) string { + for i := 0; i < len(groups); i++ { + if groups[i].Name == name { + return groups[i].ID + } + } + return "" +} + +func runCreateProjectCommand( + projectsWrapper wrappers.ProjectsWrapper, + groupsWrapper wrappers.GroupsWrapper, +) func(cmd *cobra.Command, args []string) error { + return func(cmd *cobra.Command, args []string) error { var input = []byte("{}") + var err error err = updateProjectRequestValues(&input, cmd) if err != nil { return err } - groups, err := updateGroupValues(&input, cmd, groupsWrapper) + err = updateGroupValues(&input, cmd, groupsWrapper) if err != nil { return err } @@ -266,7 +300,6 @@ func runCreateProjectCommand( return err } var projModel = wrappers.Project{} - projModel.ApplicationIds = applicationID var projResponseModel *wrappers.ProjectResponseModel var errorModel *wrappers.ErrorModel // Try to parse to a project model in order to manipulate the request payload @@ -291,10 +324,7 @@ func runCreateProjectCommand( return errors.Wrapf(err, "%s", failedCreatingProj) } } - err = assignGroupsToProject(projResponseModel.ID, projResponseModel.Name, groups, accessManagementWrapper) - if err != nil { - return err - } + err = updateProjectConfigurationIfNeeded(cmd, projectsWrapper, projResponseModel.ID) if err != nil { return err @@ -545,22 +575,20 @@ func toProjectViews(models []wrappers.ProjectResponseModel) []projectView { func toProjectView(model wrappers.ProjectResponseModel) projectView { //nolint:gocritic return projectView{ - ID: model.ID, - Name: model.Name, - CreatedAt: model.CreatedAt, - UpdatedAt: model.UpdatedAt, - Tags: model.Tags, - Groups: model.Groups, - ApplicationIds: model.ApplicationIds, + ID: model.ID, + Name: model.Name, + CreatedAt: model.CreatedAt, + UpdatedAt: model.UpdatedAt, + Tags: model.Tags, + Groups: model.Groups, } } type projectView struct { - ID string `format:"name:Project ID"` - Name string - CreatedAt time.Time `format:"name:Created at;time:01-02-06 15:04:05"` - UpdatedAt time.Time `format:"name:Updated at;time:01-02-06 15:04:05"` - Tags map[string]string - Groups []string - ApplicationIds []string + ID string `format:"name:Project ID"` + Name string + CreatedAt time.Time `format:"name:Created at;time:01-02-06 15:04:05"` + UpdatedAt time.Time `format:"name:Updated at;time:01-02-06 15:04:05"` + Tags map[string]string + Groups []string } diff --git a/internal/commands/project_test.go b/internal/commands/project_test.go index 347e5e937..133ce5f73 100644 --- a/internal/commands/project_test.go +++ b/internal/commands/project_test.go @@ -5,9 +5,6 @@ package commands import ( "testing" - applicationErrors "github.com/checkmarx/ast-cli/internal/errors" - "github.com/checkmarx/ast-cli/internal/wrappers/mock" - "gotest.tools/assert" "github.com/checkmarx/ast-cli/internal/commands/util" @@ -25,25 +22,6 @@ func TestRunCreateProjectCommandWithFile(t *testing.T) { execCmdNilAssertion(t, "project", "create", "--project-name", "test_project") } -func TestProjectCreate_ExistingApplication_CreateProjectUnderApplicationSuccessfully(t *testing.T) { - execCmdNilAssertion(t, "project", "create", "--project-name", "test_project", "--application-name", "MOCK") -} - -func TestProjectCreate_ExistingApplicationWithNoPermission_FailToCreateProject(t *testing.T) { - err := execCmdNotNilAssertion(t, "project", "create", "--project-name", "test_project", "--application-name", mock.NoPermissionApp) - assert.Assert(t, err.Error() == applicationErrors.ApplicationDoesntExistOrNoPermission) -} - -func TestProjectCreate_OnReceivingHttpBadRequestStatusCode_FailedToCreateScan(t *testing.T) { - err := execCmdNotNilAssertion(t, "project", "create", "--project-name", "test_project", "--application-name", mock.FakeHTTPStatusBadRequest) - assert.Assert(t, err.Error() == applicationErrors.FailedToGetApplication) -} - -func TestProjectCreate_OnReceivingHttpInternalServerErrorStatusCode_FailedToCreateScan(t *testing.T) { - err := execCmdNotNilAssertion(t, "project", "create", "--project-name", "test_project", "--application-name", mock.FakeHTTPStatusInternalServerError) - assert.Assert(t, err.Error() == applicationErrors.FailedToGetApplication) -} - func TestRunCreateProjectCommandWithNoInput(t *testing.T) { err := execCmdNotNilAssertion(t, "project", "create") assert.Assert(t, err.Error() == "Project name is required") diff --git a/internal/commands/result.go b/internal/commands/result.go index 56b8bdcc3..6fd361b61 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -14,7 +14,6 @@ import ( "time" "github.com/MakeNowJust/heredoc" - "github.com/checkmarx/ast-cli/internal/commands/policymanagement" "github.com/checkmarx/ast-cli/internal/commands/util" "github.com/checkmarx/ast-cli/internal/commands/util/printer" "github.com/checkmarx/ast-cli/internal/logger" @@ -57,15 +56,10 @@ const ( criticalCx = "CRITICAL" codeBashingKey = "cb-url" failedGettingBfl = "Failed getting BFL" - notAvailableString = "-" - scanFailedString = "Failed" - scanCanceledString = "Canceled" - scanSuccessString = "Completed" + notAvailableString = "N/A" notAvailableNumber = -1 - scanFailedNumber = -2 - scanCanceledNumber = -3 defaultPaddingSize = -13 - boldFormat = "\033[1m%s\033[0m" + defaultResultsPaddingSize = -15 scanPendingMessage = "Scan triggered in asynchronous mode or still running. Click more details to get the full status." directDependencyType = "Direct Dependency" indirectDependencyType = "Transitive Dependency" @@ -93,8 +87,6 @@ const ( summaryCreatedAtLayout = "2006-01-02, 15:04:05" glTimeFormat = "2006-01-02T15:04:05" sarifNodeFileLength = 2 - fixLabel = "fix" - redundantLabel = "redundant" ) var summaryFormats = []string{ @@ -230,8 +222,6 @@ func resultShowSubCommand( "Cancel the policy evaluation and fail after the timeout in minutes", ) resultShowCmd.PersistentFlags().Bool(commonParams.IgnorePolicyFlag, false, "Do not evaluate policies") - resultShowCmd.PersistentFlags().Bool(commonParams.SastRedundancyFlag, false, - "Populate SAST results 'data.redundancy' with values '"+fixLabel+"' (to fix) or '"+redundantLabel+"' (no need to fix)") return resultShowCmd } @@ -362,13 +352,6 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr sastIssues := 0 scaIssues := 0 kicsIssues := 0 - enginesStatusCode := map[string]int{ - commonParams.SastType: 0, - commonParams.ScaType: 0, - commonParams.KicsType: 0, - commonParams.APISecType: 0, - } - if len(scanInfo.StatusDetails) > 0 { for _, statusDetailItem := range scanInfo.StatusDetails { if statusDetailItem.Status == wrappers.ScanFailed || statusDetailItem.Status == wrappers.ScanCanceled { @@ -380,12 +363,6 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr kicsIssues = notAvailableNumber } } - switch statusDetailItem.Status { - case wrappers.ScanFailed: - handleScanStatus(statusDetailItem, enginesStatusCode, scanFailedNumber) - case wrappers.ScanCanceled: - handleScanStatus(statusDetailItem, enginesStatusCode, scanCanceledNumber) - } } } summary := &wrappers.ResultSummary{ @@ -407,12 +384,6 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr ProjectName: scanInfo.ProjectName, BranchName: scanInfo.Branch, EnginesEnabled: scanInfo.Engines, - EnginesResult: map[string]*wrappers.EngineResultSummary{ - commonParams.SastType: {StatusCode: enginesStatusCode[commonParams.SastType]}, - commonParams.ScaType: {StatusCode: enginesStatusCode[commonParams.ScaType]}, - commonParams.KicsType: {StatusCode: enginesStatusCode[commonParams.KicsType]}, - commonParams.APISecType: {StatusCode: enginesStatusCode[commonParams.APISecType]}, - }, } baseURI, err := resultsWrapper.GetResultsURL(summary.ProjectID) @@ -429,12 +400,6 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr return summary, nil } -func handleScanStatus(statusDetailItem wrappers.StatusInfo, targetTypes map[string]int, statusCode int) { - if _, ok := targetTypes[statusDetailItem.Name]; ok { - targetTypes[statusDetailItem.Name] = statusCode - } -} - func summaryReport( summary *wrappers.ResultSummary, policies *wrappers.PolicyResponseModel, @@ -459,14 +424,13 @@ func summaryReport( setNotAvailableNumberIfZero(summary, &summary.ScaIssues, commonParams.ScaType) setNotAvailableNumberIfZero(summary, &summary.KicsIssues, commonParams.KicsType) setRiskMsgAndStyle(summary) - setNotAvailableEnginesStatusCode(summary) return summary, nil } -func setNotAvailableEnginesStatusCode(summary *wrappers.ResultSummary) { - for engineName, engineResult := range summary.EnginesResult { - setNotAvailableNumberIfZero(summary, &engineResult.StatusCode, engineName) +func setNotAvailableNumberIfZero(summary *wrappers.ResultSummary, counter *int, engineType string) { + if *counter == 0 && !contains(summary.EnginesEnabled, engineType) { + *counter = notAvailableNumber } } @@ -488,22 +452,11 @@ func setRiskMsgAndStyle(summary *wrappers.ResultSummary) { } } -func setNotAvailableNumberIfZero(summary *wrappers.ResultSummary, counter *int, engineType string) { - if *counter == 0 && !contains(summary.EnginesEnabled, engineType) { - *counter = notAvailableNumber - } -} - func enhanceWithScanSummary(summary *wrappers.ResultSummary, results *wrappers.ScanResultsCollection) { for _, result := range results.Results { countResult(summary, result) } - if summary.HasAPISecurity() { - summary.EnginesResult[commonParams.APISecType].Low = summary.APISecurity.Risks[3] - summary.EnginesResult[commonParams.APISecType].Medium = summary.APISecurity.Risks[2] - summary.EnginesResult[commonParams.APISecType].High = summary.APISecurity.Risks[1] - } - summary.TotalIssues = summary.SastIssues + summary.ScaIssues + summary.KicsIssues + summary.GetAPISecurityDocumentationTotal() + summary.TotalIssues = summary.SastIssues + summary.ScaIssues + summary.KicsIssues } func writeHTMLSummary(targetFile string, summary *wrappers.ResultSummary) error { @@ -550,16 +503,64 @@ func writeConsoleSummary(summary *wrappers.ResultSummary) error { " Risk Level: %s \n", summary.RiskMsg, ) + fmt.Printf(" -------------------------------------- \n") + if summary.HasAPISecurity() { + fmt.Printf( + " API Security - Total Detected APIs: %d \n", + summary.APISecurity.APICount) + } if summary.Policies != nil && !strings.EqualFold(summary.Policies.Status, policeManagementNoneStatus) { - printPoliciesSummary(summary) + fmt.Printf(" -------------------------------------- \n\n") + if summary.Policies.BreakBuild { + fmt.Printf(" Policy Management Violation - Break Build Enabled: \n") + } else { + fmt.Printf(" Policy Management Violation: \n") + } + if len(summary.Policies.Polices) > 0 { + for _, police := range summary.Policies.Polices { + if len(police.RulesViolated) > 0 { + fmt.Printf(" Policy: %s | Break Build: %t | Violated Rules: ", police.Name, police.BreakBuild) + for _, violatedRule := range police.RulesViolated { + fmt.Printf("%s;", violatedRule) + } + } + fmt.Printf("\n") + } + } + fmt.Printf("\n") } - printResultsSummaryTable(summary) - - if summary.HasAPISecurity() { - printAPIsSecuritySummary(summary) + fmt.Printf(" Total Results: %d \n", summary.TotalIssues) + fmt.Printf(" ----------------------------------- \n") + fmt.Printf(" | Critical: %*d| \n", defaultPaddingSize, summary.CriticalIssues) + fmt.Printf(" | High: %*d| \n", defaultPaddingSize, summary.HighIssues) + fmt.Printf(" | Medium: %*d| \n", defaultPaddingSize, summary.MediumIssues) + fmt.Printf(" | Low: %*d| \n", defaultPaddingSize, summary.LowIssues) + fmt.Printf(" | Info: %*d| \n", defaultPaddingSize, summary.InfoIssues) + fmt.Printf(" ----------------------------------- \n") + + if summary.KicsIssues == notAvailableNumber { + fmt.Printf(" | IAC-SECURITY: %*s| \n", defaultPaddingSize, notAvailableString) + } else { + fmt.Printf(" | IAC-SECURITY: %*d| \n", defaultPaddingSize, summary.KicsIssues) } - + if summary.SastIssues == notAvailableNumber { + fmt.Printf(" | SAST: %*s| \n", defaultPaddingSize, notAvailableString) + } else { + fmt.Printf(" | SAST: %*d| \n", defaultPaddingSize, summary.SastIssues) + if summary.HasAPISecurity() { + fmt.Printf(" | APIS WITH RISK: %*d| \n", defaultPaddingSize, summary.APISecurity.TotalRisksCount) + if summary.HasAPISecurityDocumentation() { + fmt.Printf(" | APIS DOCUMENTATION: %*d| \n", defaultPaddingSize, summary.GetAPISecurityDocumentationTotal()) + } + } + } + if summary.ScaIssues == notAvailableNumber { + fmt.Printf(" | SCA: %*s| \n", defaultPaddingSize, notAvailableString) + } else { + fmt.Printf(" | SCA: %*d| \n", defaultPaddingSize, summary.ScaIssues) + } + fmt.Printf(" -------------------------------------- \n\n") fmt.Printf(" Checkmarx One - Scan Summary & Details: %s\n", summary.BaseURI) } else { fmt.Printf("Scan executed in asynchronous mode or still running. Hence, no results generated.\n") @@ -568,74 +569,6 @@ func writeConsoleSummary(summary *wrappers.ResultSummary) error { return nil } -func printPoliciesSummary(summary *wrappers.ResultSummary) { - fmt.Printf(" -------------------------------------- \n") - if summary.Policies.BreakBuild { - fmt.Printf(" Policy Management Violation - Break Build Enabled: \n") - } else { - fmt.Printf(" Policy Management Violation: \n") - } - if len(summary.Policies.Policies) > 0 { - for _, police := range summary.Policies.Policies { - if len(police.RulesViolated) > 0 { - fmt.Printf(" Policy: %s | Break Build: %t | Violated Rules: ", police.Name, police.BreakBuild) - for _, violatedRule := range police.RulesViolated { - fmt.Printf("%s;", violatedRule) - } - } - fmt.Printf("\n") - } - } - fmt.Printf("\n") -} - -func printAPIsSecuritySummary(summary *wrappers.ResultSummary) { - fmt.Printf(" API Security - Total Detected APIs: %d \n", summary.APISecurity.APICount) - fmt.Printf(" APIS WITH RISK: %*d \n", defaultPaddingSize, summary.APISecurity.TotalRisksCount) - if summary.HasAPISecurityDocumentation() { - fmt.Printf(" APIS DOCUMENTATION: %*d \n", defaultPaddingSize, summary.GetAPISecurityDocumentationTotal()) - } - fmt.Printf(" ---------------------------------------------------------------- \n\n") -} - -func printTableRow(title string, counts *wrappers.EngineResultSummary, statusNumber int) { - formatString := " | %-4s %4d %4d %6d %4d %4d %-9s |\n" - notAvailableFormatString := " | %-4s %4s %4s %6s %4s %4s %5s |\n" - - switch statusNumber { - case notAvailableNumber: - fmt.Printf(notAvailableFormatString, title, notAvailableString, notAvailableString, notAvailableString, notAvailableString, notAvailableString, notAvailableString) - case scanFailedNumber: - fmt.Printf(formatString, title, counts.Critical, counts.High, counts.Medium, counts.Low, counts.Info, scanFailedString) - case scanCanceledNumber: - fmt.Printf(formatString, title, counts.Critical, counts.High, counts.Medium, counts.Low, counts.Info, scanCanceledString) - default: - fmt.Printf(formatString, title, counts.Critical, counts.High, counts.Medium, counts.Low, counts.Info, scanSuccessString) - } -} - -func printResultsSummaryTable(summary *wrappers.ResultSummary) { - totalCriticalIssues := summary.EnginesResult.GetCriticalIssues() - totalHighIssues := summary.EnginesResult.GetHighIssues() - totalMediumIssues := summary.EnginesResult.GetMediumIssues() - totalLowIssues := summary.EnginesResult.GetLowIssues() - totalInfoIssues := summary.EnginesResult.GetInfoIssues() - fmt.Printf(" ---------------------------------------------------------------- \n\n") - fmt.Printf(" Total Results: %d \n", summary.TotalIssues) - fmt.Println(" ---------------------------------------------------------------- ") - fmt.Println(" | Critical High Medium Low Info Status |") - - printTableRow("APIs", summary.EnginesResult[commonParams.APISecType], summary.EnginesResult[commonParams.APISecType].StatusCode) - printTableRow("IAC", summary.EnginesResult[commonParams.KicsType], summary.EnginesResult[commonParams.KicsType].StatusCode) - printTableRow("SAST", summary.EnginesResult[commonParams.SastType], summary.EnginesResult[commonParams.SastType].StatusCode) - printTableRow("SCA", summary.EnginesResult[commonParams.ScaType], summary.EnginesResult[commonParams.ScaType].StatusCode) - - fmt.Println(" ---------------------------------------------------------------- ") - fmt.Printf(" | %-4s %4d %4d %6d %4d %4d %-9s |\n", - fmt.Sprintf(boldFormat, "TOTAL"), totalCriticalIssues, totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status) - fmt.Printf(" ---------------------------------------------------------------- \n\n") -} - func generateScanSummaryURL(summary *wrappers.ResultSummary) string { summaryURL := fmt.Sprintf( strings.Replace(summary.BaseURI, "overview", "scans?id=%s&branch=%s", 1), @@ -661,7 +594,6 @@ func runGetResultCommand( formatSbomOptions, _ := cmd.Flags().GetString(commonParams.ReportSbomFormatFlag) useSCALocalFlow, _ := cmd.Flags().GetBool(commonParams.ReportSbomFormatLocalFlowFlag) retrySBOM, _ := cmd.Flags().GetInt(commonParams.RetrySBOMFlag) - sastRedundancy, _ := cmd.Flags().GetBool(commonParams.SastRedundancyFlag) scanID, _ := cmd.Flags().GetString(commonParams.ScanIDFlag) if scanID == "" { @@ -687,18 +619,13 @@ func runGetResultCommand( if policyTimeout < 0 { return errors.Errorf("--%s should be equal or higher than 0", commonParams.PolicyTimeoutFlag) } - policyResponseModel, err = policymanagement.HandlePolicyWait(waitDelay, policyTimeout, policyWrapper, scan.ID, scan.ProjectID, cmd) + policyResponseModel, err = handlePolicyWait(waitDelay, policyTimeout, policyWrapper, scan, cmd) if err != nil { return err } } else { logger.PrintIfVerbose("Skipping policy evaluation") } - - if sastRedundancy { - params[commonParams.SastRedundancyFlag] = "" - } - return CreateScanReport( resultsWrapper, risksOverviewWrapper, @@ -814,7 +741,6 @@ func CreateScanReport( func countResult(summary *wrappers.ResultSummary, result *wrappers.ScanResult) { engineType := strings.TrimSpace(result.Type) - severity := strings.ToLower(result.Severity) if contains(summary.EnginesEnabled, engineType) && isExploitable(result.State) { if engineType == commonParams.SastType { summary.SastIssues++ @@ -826,9 +752,8 @@ func countResult(summary *wrappers.ResultSummary, result *wrappers.ScanResult) { summary.KicsIssues++ summary.TotalIssues++ } - if severity == criticalLabel { - summary.CriticalIssues++ - } else if severity == highLabel { + severity := strings.ToLower(result.Severity) + if severity == highLabel { summary.HighIssues++ } else if severity == lowLabel { summary.LowIssues++ @@ -837,7 +762,6 @@ func countResult(summary *wrappers.ResultSummary, result *wrappers.ScanResult) { } else if severity == infoLabel { summary.InfoIssues++ } - summary.UpdateEngineResultSummary(engineType, severity) } } @@ -1047,12 +971,6 @@ func enrichScaResults( resultsModel = addPackageInformation(resultsModel, scaPackageModel, scaTypeModel) } } - _, sastRedundancy := params[commonParams.SastRedundancyFlag] - - if util.Contains(scan.Engines, commonParams.SastType) && sastRedundancy { - // Compute SAST results redundancy - resultsModel = ComputeRedundantSastResults(resultsModel) - } return resultsModel, nil } @@ -1425,8 +1343,8 @@ func createSarifRun(results *wrappers.ScanResultsCollection) wrappers.SarifRun { } func parseResults(results *wrappers.ScanResultsCollection) ([]wrappers.SarifDriverRule, []wrappers.SarifScanResult) { - var sarifRules = make([]wrappers.SarifDriverRule, 0) - var sarifResults = make([]wrappers.SarifScanResult, 0) + var sarifRules []wrappers.SarifDriverRule + var sarifResults []wrappers.SarifScanResult if results != nil { ruleIds := map[interface{}]bool{} for _, result := range results.Results { @@ -1811,11 +1729,11 @@ func addPackageInformation( head.SupportsQuickFix = head.SupportsQuickFix && util.IsPackageFileSupported(*location) } currentPackage.SupportsQuickFix = currentPackage.SupportsQuickFix || head.SupportsQuickFix - if result.ID != "" { - currentPackage.FixLink = "https://devhub.checkmarx.com/cve-details/" + result.ID - } else { - currentPackage.FixLink = "" - } + } + if result.VulnerabilityDetails.CveName != "" { + currentPackage.FixLink = "https://devhub.checkmarx.com/cve-details/" + result.VulnerabilityDetails.CveName + } else { + currentPackage.FixLink = "" } if currentPackage.IsDirectDependency { currentPackage.TypeOfDependency = directDependencyType @@ -1833,12 +1751,12 @@ func addPackageInformation( func filterViolatedRules(policyModel wrappers.PolicyResponseModel) *wrappers.PolicyResponseModel { i := 0 - for _, policy := range policyModel.Policies { + for _, policy := range policyModel.Polices { if len(policy.RulesViolated) > 0 { - policyModel.Policies[i] = policy + policyModel.Polices[i] = policy i++ } } - policyModel.Policies = policyModel.Policies[:i] + policyModel.Polices = policyModel.Polices[:i] return &policyModel } diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index 525c759bd..d27d70422 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -62,13 +62,6 @@ func TestRunGetResultsByScanIdJsonFormat(t *testing.T) { os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatJSON)) } -func TestRunGetResultsByScanIdJsonFormatWithSastRedundancy(t *testing.T) { - execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "json", "--sast-redundancy") - - // Remove generated json file - os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatJSON)) -} - func TestRunGetResultsByScanIdSummaryJsonFormat(t *testing.T) { execCmdNilAssertion(t, "results", "show", "--scan-id", "MOCK", "--report-format", "summaryJSON") @@ -332,124 +325,3 @@ func TestRunGetResultsByScanIdGLFormat(t *testing.T) { // Run test for gl-sast report type os.Remove(fmt.Sprintf("%s.%s", fileName, printer.FormatGL)) } - -func Test_addPackageInformation(t *testing.T) { - var dependencyPath = wrappers.DependencyPath{ID: "test-1"} - var dependencyArray = [][]wrappers.DependencyPath{{dependencyPath}} - resultsModel := &wrappers.ScanResultsCollection{ - Results: []*wrappers.ScanResult{ - { - Type: "sca", // Assuming this matches commonParams.ScaType - ScanResultData: wrappers.ScanResultData{ - PackageIdentifier: "pkg-123", - }, - ID: "CVE-2021-23-424", - VulnerabilityDetails: wrappers.VulnerabilityDetails{ - CvssScore: 5.0, - CveName: "cwe-789", - }, - }, - }, - } - scaPackageModel := &[]wrappers.ScaPackageCollection{ - { - ID: "pkg-123", - FixLink: "", - DependencyPathArray: dependencyArray, - }, - } - scaTypeModel := &[]wrappers.ScaTypeCollection{ - {}} - - resultsModel = addPackageInformation(resultsModel, scaPackageModel, scaTypeModel) - - expectedFixLink := "https://devhub.checkmarx.com/cve-details/CVE-2021-23-424" - actualFixLink := resultsModel.Results[0].ScanResultData.ScaPackageCollection.FixLink - assert.Equal(t, expectedFixLink, actualFixLink, "FixLink should match the result ID") -} - -func Test_setRiskMsgAndStyle_critical(t *testing.T) { - var summary wrappers.ResultSummary - summary.CriticalIssues = 1 - setRiskMsgAndStyle(&summary) - assert.Equal(t, criticalLabel, summary.RiskStyle, "Incorrect Risk Style for critical issues.") - assert.Equal(t, "Critical Risk", summary.RiskMsg, "Incorrect Risk Message for critical issues.") -} -func Test_setRiskMsgAndStyle_high(t *testing.T) { - var summary wrappers.ResultSummary - summary.CriticalIssues = 0 - summary.HighIssues = 1 - setRiskMsgAndStyle(&summary) - assert.Equal(t, highLabel, summary.RiskStyle, "Incorrect Risk Style for high issues.") - assert.Equal(t, "High Risk", summary.RiskMsg, "Incorrect Risk Message for high issues.") -} -func Test_setRiskMsgAndStyle_criticalAndHigh(t *testing.T) { - var summary wrappers.ResultSummary - summary.CriticalIssues = 1 - summary.HighIssues = 1 - setRiskMsgAndStyle(&summary) - assert.Equal(t, criticalLabel, summary.RiskStyle, "Incorrect Risk Style for critical issues.") - assert.Equal(t, "Critical Risk", summary.RiskMsg, "Incorrect Risk Message for critical issues.") -} -func Test_countResult(t *testing.T) { - var result wrappers.ScanResult - result.Type = params.SastType - result.Severity = criticalLabel - result.State = "EXPLOITABLE" - - var summary wrappers.ResultSummary - engineEnabled := []string{params.SastType} - summary.EnginesEnabled = engineEnabled - summary.SastIssues = 100 - summary.TotalIssues = 1000 - summary.CriticalIssues = 10 - var engineResultSummary wrappers.EngineResultSummary - engineResultSummary.Critical = 0 - var engineResult = make(map[string]*wrappers.EngineResultSummary) - engineResult[params.SastType] = &engineResultSummary - summary.EnginesResult = engineResult - - countResult(&summary, &result) - - assert.Equal(t, 101, summary.SastIssues, "Critical issues in summary SAST issues are not counted properly") - assert.Equal(t, 1001, summary.TotalIssues, "Critical issues in summary total issues are not counted properly") - assert.Equal(t, 11, summary.CriticalIssues, "Critical issues in summary are not counted properly") - assert.Equal(t, 1, summary.EnginesResult[params.SastType].Critical, "Critical issues in summary for SAST are not counted properly") -} -func Test_countResult_high(t *testing.T) { - var result wrappers.ScanResult - result.Type = params.ScaType - result.Severity = highLabel - result.State = "EXPLOITABLE" - - var summary wrappers.ResultSummary - engineEnabled := []string{params.ScaType} - summary.EnginesEnabled = engineEnabled - summary.ScaIssues = 100 - summary.TotalIssues = 1000 - summary.HighIssues = 10 - var engineResultSummary wrappers.EngineResultSummary - engineResultSummary.High = 0 - var engineResult = make(map[string]*wrappers.EngineResultSummary) - engineResult[params.ScaType] = &engineResultSummary - summary.EnginesResult = engineResult - - countResult(&summary, &result) - - assert.Equal(t, 101, summary.ScaIssues, "High issues in summary SCA issues are not counted properly") - assert.Equal(t, 1001, summary.TotalIssues, "High issues in summary total issues are not counted properly") - assert.Equal(t, 11, summary.HighIssues, "High issues in summary are not counted properly") - assert.Equal(t, 1, summary.EnginesResult[params.ScaType].High, "High issues in summary for SCA are not counted properly") -} -func Test_findSarifLevel_critical(t *testing.T) { - var result wrappers.ScanResult - result.Severity = criticalCx - var sarifLevel = findSarifLevel(&result) - assert.Equal(t, highSarif, sarifLevel, "Incorrect sarif level for critical issues.") -} -func Test_findSarifLevel_high(t *testing.T) { - var result wrappers.ScanResult - result.Severity = highCx - var sarifLevel = findSarifLevel(&result) - assert.Equal(t, highSarif, sarifLevel, "Incorrect sarif level for high issues.") -} diff --git a/internal/commands/results-redundancy.go b/internal/commands/results-redundancy.go deleted file mode 100644 index 4d57aaa2e..000000000 --- a/internal/commands/results-redundancy.go +++ /dev/null @@ -1,279 +0,0 @@ -package commands - -import ( - "crypto/sha1" - "encoding/hex" - "fmt" - "math" - "sort" - "strings" - - "github.com/checkmarx/ast-cli/internal/wrappers" -) - -const ( - precision = 2 - ten = 10 - half = 0.5 -) - -func ComputeRedundantSastResults(resultsModel *wrappers.ScanResultsCollection) *wrappers.ScanResultsCollection { - languages := GetLanguages(resultsModel) - queriesByLanguage := GetQueries(resultsModel, languages) - - for language := range queriesByLanguage { - for query := range queriesByLanguage[language] { - resultsModel = ComputeRedundantSastResultsForQuery(resultsModel, language, query) - } - } - return resultsModel -} - -func GetLanguages(resultsModel *wrappers.ScanResultsCollection) map[string]bool { - languages := make(map[string]bool) - for _, result := range resultsModel.Results { - if result.ScanResultData.LanguageName != "" { - languages[result.ScanResultData.LanguageName] = true - } - } - return languages -} - -func GetQueries(resultsModel *wrappers.ScanResultsCollection, languages map[string]bool) map[string]map[string]bool { - queriesByLanguage := make(map[string]map[string]bool) - for _, result := range resultsModel.Results { - if _, exist := languages[result.ScanResultData.LanguageName]; !exist { - continue - } - if _, exist := queriesByLanguage[result.ScanResultData.LanguageName]; !exist { - queriesByLanguage[result.ScanResultData.LanguageName] = make(map[string]bool) - } - queriesByLanguage[result.ScanResultData.LanguageName][result.ScanResultData.QueryName] = true - } - return queriesByLanguage -} - -func ComputeRedundantSastResultsForQuery(resultsModel *wrappers.ScanResultsCollection, language, query string) *wrappers.ScanResultsCollection { - queryResults := GetResultsForQuery(resultsModel, language, query) - if len(queryResults) == 0 { - return resultsModel - } - - flows := buildFlows(queryResults) - - subFlows := compareFlows(flows) - - redundantResults := computeRedundantResults(subFlows, queryResults) - - labelRedundantResults(queryResults, redundantResults) - return resultsModel -} - -func GetResultsForQuery(resultsModel *wrappers.ScanResultsCollection, language, query string) []*wrappers.ScanResult { - var queryResults []*wrappers.ScanResult - for _, result := range resultsModel.Results { - if result.ScanResultData.LanguageName != language || result.ScanResultData.QueryName != query { - continue - } - queryResults = append(queryResults, result) - } - - sort.Slice(queryResults, func(i, j int) bool { - return queryResults[i].ID < queryResults[j].ID - }) - - return queryResults -} - -func labelRedundantResults(queryResults []*wrappers.ScanResult, redundantResults map[string]map[string]bool) { - resultsByID := make(map[string]*wrappers.ScanResult) - for _, result := range queryResults { - resultsByID[result.ID] = result - } - - for resultID, redundantResult := range redundantResults { - if len(redundantResult) == 0 { - resultsByID[resultID].ScanResultData.Redundancy = fixLabel - } else { - resultsByID[resultID].ScanResultData.Redundancy = redundantLabel - } - } -} - -func computeRedundantResults(subFlows map[string]*SubFlow, queryResults []*wrappers.ScanResult) map[string]map[string]bool { - redundantResults := make(map[string]map[string]bool) - for _, result := range queryResults { - redundantResults[result.ID] = make(map[string]bool) - } - - sortedSubFlowIDs := sortSubFlowIDs(subFlows) - for _, key := range sortedSubFlowIDs { - sortedResults := sortSubFlowResultIDs(subFlows[key]) - coverage := make(map[string]float64) - for _, resultID := range sortedResults { - result := getResultForID(queryResults, resultID) - coverage[resultID] = roundFloat(float64(len(subFlows[key].Flow))/float64(len(result.ScanResultData.Nodes)), precision) - } - maxCoverageResultID, maxCoverage := getMaxCoverage(coverage) - - if maxCoverage < half { - continue - } - for resultID := range coverage { - if resultID == maxCoverageResultID { - continue - } - redundantResults[resultID][maxCoverageResultID] = true - } - } - return redundantResults -} - -func getMaxCoverage(coverage map[string]float64) (maxCoverageResultID string, maxCoverage float64) { - var sortedResultsIDs []string - for resultID := range coverage { - sortedResultsIDs = append(sortedResultsIDs, resultID) - } - sort.Strings(sortedResultsIDs) - - maxCoverageResultID = "" - maxCoverage = 0.0 - for _, resultID := range sortedResultsIDs { - c := coverage[resultID] - if c > maxCoverage { - maxCoverage = c - maxCoverageResultID = resultID - } - } - return maxCoverageResultID, maxCoverage -} - -func roundFloat(val float64, precision uint) float64 { - ratio := math.Pow(ten, float64(precision)) - return math.Round(val*ratio) / ratio -} - -func getResultForID(queryResults []*wrappers.ScanResult, resultID string) *wrappers.ScanResult { - for _, result := range queryResults { - if result.ID == resultID { - return result - } - } - return nil -} - -func sortSubFlowIDs(subFlows map[string]*SubFlow) []string { - var subFlowIDs []string - for key := range subFlows { - subFlowIDs = append(subFlowIDs, key) - } - sort.Strings(subFlowIDs) - return subFlowIDs -} - -func sortSubFlowResultIDs(subFlow *SubFlow) []string { - var results []string - for result := range subFlow.Results { - results = append(results, result) - } - sort.Strings(results) - return results -} - -func buildFlows(queryResults []*wrappers.ScanResult) map[string][]string { - flowsByResult := make(map[string][]string) - for _, result := range queryResults { - var resultNodes []string - for _, node := range result.ScanResultData.Nodes { - nodeStr := fmt.Sprintf("%s:%d:%d", node.FileName, node.Line, node.Column) - resultNodes = append(resultNodes, nodeStr) - } - flowsByResult[result.ID] = resultNodes - } - return flowsByResult -} - -type SubFlow struct { - ShaOne string - Flow []string - Results map[string]bool -} - -func compareFlows(flows map[string][]string) map[string]*SubFlow { - subFlows := make(map[string]*SubFlow) - comparedFlows := make(map[string]bool) - for r1, f1 := range flows { - for r2, f2 := range flows { - if r1 == r2 { - continue - } - key := GetKey(r1, r2) - if _, exist := comparedFlows[key]; exist { - continue - } - comparedFlows[key] = true - - // compute the subflow of f1 and f2 - exist, sf := computeSubFlow(f1, f2) - if !exist { - continue - } - if _, exist := subFlows[sf.ShaOne]; !exist { - sf.Results = make(map[string]bool) - subFlows[sf.ShaOne] = sf - } - subFlows[sf.ShaOne].Results[r1] = true - subFlows[sf.ShaOne].Results[r2] = true - } - } - return subFlows -} - -func GetKey(r1, r2 string) string { - if r1 <= r2 { - return r1 + "," + r2 - } - return r2 + "," + r1 -} - -func computeSubFlow(f1, f2 []string) (bool, *SubFlow) { - var subFlow []string - for i1 := 0; i1 < len(f1); { - for i2 := 0; i2 < len(f2) && i1 < len(f1); { - if f1[i1] == f2[i2] { - subFlow = append(subFlow, f1[i1]) - i1++ - i2++ - } else { - if len(subFlow) > 0 { - break - } - i2++ - } - } - if len(subFlow) > 0 { - break - } - i1++ - } - if len(subFlow) == 0 { - return false, nil - } - sha1String := getSha1String(subFlow) - return true, &SubFlow{sha1String, subFlow, nil} -} - -func getSha1String(lines []string) string { - h := sha1.New() - - // Write the bytes of the input string into the hash - h.Write([]byte(strings.Join(lines, ""))) - - // Get the final hash result as a byte slice - bs := h.Sum(nil) - - // Convert the byte slice to a hexadecimal string - sha1String := hex.EncodeToString(bs) - - return sha1String -} diff --git a/internal/commands/root.go b/internal/commands/root.go index ed879366f..86dc1e615 100644 --- a/internal/commands/root.go +++ b/internal/commands/root.go @@ -23,7 +23,6 @@ const ErrorCodeFormat = "%s: CODE: %d, %s\n" // NewAstCLI Return a Checkmarx One CLI root command to execute func NewAstCLI( - applicationsWrapper wrappers.ApplicationsWrapper, scansWrapper wrappers.ScansWrapper, resultsSbomWrapper wrappers.ResultsSbomWrapper, resultsPdfReportsWrapper wrappers.ResultsPdfWrapper, @@ -51,7 +50,6 @@ func NewAstCLI( featureFlagsWrapper wrappers.FeatureFlagsWrapper, policyWrapper wrappers.PolicyWrapper, sastMetadataWrapper wrappers.SastMetadataWrapper, - accessManagementWrapper wrappers.AccessManagementWrapper, ) *cobra.Command { // Create the root rootCmd := &cobra.Command{ @@ -145,7 +143,6 @@ func NewAstCLI( // Create the CLI command structure scanCmd := NewScanCommand( - applicationsWrapper, scansWrapper, resultsSbomWrapper, resultsPdfReportsWrapper, @@ -159,9 +156,8 @@ func NewAstCLI( scaRealTimeWrapper, policyWrapper, sastMetadataWrapper, - accessManagementWrapper, ) - projectCmd := NewProjectCommand(applicationsWrapper, projectsWrapper, groupsWrapper, accessManagementWrapper) + projectCmd := NewProjectCommand(projectsWrapper, groupsWrapper) resultsCmd := NewResultsCommand( resultsWrapper, scansWrapper, @@ -185,13 +181,11 @@ func NewAstCLI( learnMoreWrapper, tenantWrapper, chatWrapper, - policyWrapper, - scansWrapper, ) configCmd := util.NewConfigCommand() triageCmd := NewResultsPredicatesCommand(resultsPredicatesWrapper) - chatCmd := NewChatCommand(chatWrapper, tenantWrapper) + chatCmd := NewChatCommand(chatWrapper) rootCmd.AddCommand( scanCmd, diff --git a/internal/commands/root_test.go b/internal/commands/root_test.go index e301c4676..c7394f2e7 100644 --- a/internal/commands/root_test.go +++ b/internal/commands/root_test.go @@ -30,7 +30,6 @@ func TestMain(m *testing.M) { } func createASTTestCommand() *cobra.Command { - applicationWrapper := &mock.ApplicationsMockWrapper{} scansMockWrapper := &mock.ScansMockWrapper{} resultsSbomWrapper := &mock.ResultsSbomWrapper{} resultsPdfWrapper := &mock.ResultsPdfWrapper{} @@ -58,10 +57,8 @@ func createASTTestCommand() *cobra.Command { featureFlagsMockWrapper := &mock.FeatureFlagsMockWrapper{} policyWrapper := &mock.PolicyMockWrapper{} sastMetadataWrapper := &mock.SastMetadataMockWrapper{} - accessManagementWrapper := &mock.AccessManagementMockWrapper{} return NewAstCLI( - applicationWrapper, scansMockWrapper, resultsSbomWrapper, resultsPdfWrapper, @@ -89,7 +86,6 @@ func createASTTestCommand() *cobra.Command { featureFlagsMockWrapper, policyWrapper, sastMetadataWrapper, - accessManagementWrapper, ) } diff --git a/internal/commands/sast-prompt_test.go b/internal/commands/sast-prompt_test.go deleted file mode 100644 index 9af903994..000000000 --- a/internal/commands/sast-prompt_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package commands - -import ( - "fmt" - "testing" -) - -const expectedOutputFormat = "**CONFIDENCE:** " + - "A score between 0 (low) and 100 (high) indicating the degree of confidence in the exploitability of this vulnerability in the context of your code. " + - "
%s**EXPLANATION:** " + - "An OpenAI generated description of the vulnerability.
%s**PROPOSED REMEDIATION:** " + - "A customized snippet, generated by OpenAI, that can be used to remediate the vulnerability in your code.
%s" - -func getExpectedOutput(confidenceNumber, explanationText, fixText string) string { - return fmt.Sprintf(expectedOutputFormat, confidenceNumber, explanationText, fixText) -} - -func TestAddDescriptionForIdentifiers(t *testing.T) { - input := confidence + " 35 " + explanation + " this is a short explanation." + fix + " a fixed snippet" - expected := getExpectedOutput(" 35 ", " this is a short explanation.", " a fixed snippet") - output := getActual(input, t) - - if output[len(output)-1] != expected { - t.Errorf("Expected %q, but got %q", expected, output) - } -} - -func TestAddNewlinesIfNecessarySomeNewlines(t *testing.T) { - input := confidence + " 35 " + explanation + " this is a short explanation.\n" + fix + " a fixed snippet" - expected := getExpectedOutput(" 35 ", " this is a short explanation.\n", " a fixed snippet") - - output := getActual(input, t) - - if output[len(output)-1] != expected { - t.Errorf("Expected %q, but got %q", expected, output) - } -} - -func TestAddNewlinesIfNecessaryAllNewlines(t *testing.T) { - input := confidence + " 35\n " + explanation + " this is a short explanation.\n" + fix + " a fixed snippet" - expected := getExpectedOutput(" 35\n ", " this is a short explanation.\n", " a fixed snippet") - - output := getActual(input, t) - - if output[len(output)-1] != expected { - t.Errorf("Expected %q, but got %q", expected, output) - } -} - -func getActual(input string, t *testing.T) []string { - someText := "some text" - response := []string{someText, someText, input} - output := addDescriptionForIdentifier(response) - for i := 0; i < len(output)-1; i++ { - if output[i] != response[i] { - t.Errorf("All strings except last expected to stay the same") - } - } - return output -} diff --git a/internal/commands/scan.go b/internal/commands/scan.go index f3b7b098a..c7bbda601 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -18,8 +18,6 @@ import ( "strings" "time" - applicationErrors "github.com/checkmarx/ast-cli/internal/errors" - "github.com/checkmarx/ast-cli/internal/commands/scarealtime" "github.com/checkmarx/ast-cli/internal/commands/util" "github.com/checkmarx/ast-cli/internal/commands/util/printer" @@ -29,7 +27,6 @@ import ( "github.com/pkg/errors" "github.com/MakeNowJust/heredoc" - "github.com/checkmarx/ast-cli/internal/commands/policymanagement" commonParams "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" "github.com/mssola/user_agent" @@ -124,7 +121,6 @@ var ( ) func NewScanCommand( - applicationsWrapper wrappers.ApplicationsWrapper, scansWrapper wrappers.ScansWrapper, resultsSbomWrapper wrappers.ResultsSbomWrapper, resultsPdfReportsWrapper wrappers.ResultsPdfWrapper, @@ -138,7 +134,6 @@ func NewScanCommand( scaRealTimeWrapper wrappers.ScaRealTimeWrapper, policyWrapper wrappers.PolicyWrapper, sastMetadataWrapper wrappers.SastMetadataWrapper, - accessManagementWrapper wrappers.AccessManagementWrapper, ) *cobra.Command { scanCmd := &cobra.Command{ Use: "scan", @@ -164,8 +159,6 @@ func NewScanCommand( riskOverviewWrapper, jwtWrapper, policyWrapper, - accessManagementWrapper, - applicationsWrapper, ) listScansCmd := scanListSubCommand(scansWrapper, sastMetadataWrapper) @@ -253,16 +246,16 @@ func scanLogsSubCommand(logsWrapper wrappers.LogsWrapper) *cobra.Command { logsCmd := &cobra.Command{ Use: "logs", Short: "Download scan log for selected scan type", - Long: "Accepts a scan-id and scan type (sast, iac-security) and downloads the related scan log", + Long: "Accepts a scan-id and scan type (sast, iac-security or sca) and downloads the related scan log", Example: heredoc.Doc( ` - $ cx scan logs --scan-id --scan-type + $ cx scan logs --scan-id --scan-type `, ), RunE: runDownloadLogs(logsWrapper), } logsCmd.PersistentFlags().String(commonParams.ScanIDFlag, "", "Scan ID to retrieve log for.") - logsCmd.PersistentFlags().String(commonParams.ScanTypeFlag, "", "Scan type to pull log for, ex: sast, iac-security.") + logsCmd.PersistentFlags().String(commonParams.ScanTypeFlag, "", "Scan type to pull log for, ex: sast, iac-security or sca.") markFlagAsRequired(logsCmd, commonParams.ScanIDFlag) markFlagAsRequired(logsCmd, commonParams.ScanTypeFlag) @@ -416,8 +409,6 @@ func scanCreateSubCommand( risksOverviewWrapper wrappers.RisksOverviewWrapper, jwtWrapper wrappers.JWTWrapper, policyWrapper wrappers.PolicyWrapper, - accessManagementWrapper wrappers.AccessManagementWrapper, - applicationsWrapper wrappers.ApplicationsWrapper, ) *cobra.Command { createScanCmd := &cobra.Command{ Use: "create", @@ -446,8 +437,6 @@ func scanCreateSubCommand( risksOverviewWrapper, jwtWrapper, policyWrapper, - accessManagementWrapper, - applicationsWrapper, ), } createScanCmd.PersistentFlags().Bool(commonParams.AsyncFlag, false, "Do not wait for scan completion") @@ -572,8 +561,6 @@ func scanCreateSubCommand( "Cancel the policy evaluation and fail after the timeout in minutes", ) createScanCmd.PersistentFlags().Bool(commonParams.IgnorePolicyFlag, false, "Do not evaluate policies") - - createScanCmd.PersistentFlags().String(commonParams.ApplicationName, "", "Name of the application to assign with the project") // Link the environment variables to the CLI argument(s). err = viper.BindPFlag(commonParams.BranchKey, createScanCmd.PersistentFlags().Lookup(commonParams.BranchFlag)) if err != nil { @@ -591,12 +578,10 @@ func scanCreateSubCommand( } func findProject( - applicationID []string, projectName string, cmd *cobra.Command, projectsWrapper wrappers.ProjectsWrapper, groupsWrapper wrappers.GroupsWrapper, - accessManagementWrapper wrappers.AccessManagementWrapper, ) (string, error) { params := make(map[string]string) params["names"] = projectName @@ -607,10 +592,10 @@ func findProject( for i := 0; i < len(resp.Projects); i++ { if resp.Projects[i].Name == projectName { - return updateProject(resp, cmd, projectsWrapper, groupsWrapper, accessManagementWrapper, projectName, applicationID) + return updateProject(resp, cmd, projectsWrapper, groupsWrapper, projectName) } } - projectID, err := createProject(projectName, cmd, projectsWrapper, groupsWrapper, accessManagementWrapper, applicationID) + projectID, err := createProject(projectName, cmd, projectsWrapper, groupsWrapper) if err != nil { return "", err } @@ -622,8 +607,6 @@ func createProject( cmd *cobra.Command, projectsWrapper wrappers.ProjectsWrapper, groupsWrapper wrappers.GroupsWrapper, - accessManagementWrapper wrappers.AccessManagementWrapper, - applicationID []string, ) (string, error) { projectGroups, _ := cmd.Flags().GetString(commonParams.ProjectGroupList) projectTags, _ := cmd.Flags().GetString(commonParams.ProjectTagList) @@ -634,9 +617,7 @@ func createProject( } var projModel = wrappers.Project{} projModel.Name = projectName - projModel.Groups = getGroupsForRequest(groupsMap) - projModel.ApplicationIds = applicationID - + projModel.Groups = groupsMap if projectPrivatePackage != "" { projModel.PrivatePackage, _ = strconv.ParseBool(projectPrivatePackage) } @@ -648,7 +629,6 @@ func createProject( } if err == nil { projectID = resp.ID - err = assignGroupsToProject(projectID, projectName, groupsMap, accessManagementWrapper) } return projectID, err } @@ -658,9 +638,7 @@ func updateProject( cmd *cobra.Command, projectsWrapper wrappers.ProjectsWrapper, groupsWrapper wrappers.GroupsWrapper, - accessManagementWrapper wrappers.AccessManagementWrapper, projectName string, - applicationID []string, ) (string, error) { var projectID string @@ -679,8 +657,8 @@ func updateProject( projModel.RepoURL = resp.Projects[i].RepoURL } } - if projectGroups == "" && projectTags == "" && projectPrivatePackage == "" && len(applicationID) == 0 { - logger.PrintIfVerbose("No groups, applicationId or tags to update. Skipping project update.") + if projectGroups == "" && projectTags == "" && projectPrivatePackage == "" { + logger.PrintIfVerbose("No groups or tags to update. Skipping project update.") return projectID, nil } if projectPrivatePackage != "" { @@ -696,27 +674,18 @@ func updateProject( projModel.Name = projModelResp.Name projModel.Groups = projModelResp.Groups projModel.Tags = projModelResp.Tags - projModel.ApplicationIds = projModelResp.ApplicationIds if projectGroups != "" { groupsMap, groupErr := createGroupsMap(projectGroups, groupsWrapper) if groupErr != nil { return "", errors.Errorf("%s: %v", failedUpdatingProj, groupErr) } logger.PrintIfVerbose("Updating project groups") - projModel.Groups = getGroupsForRequest(groupsMap) - err = assignGroupsToProject(projectID, projectName, groupsMap, accessManagementWrapper) - if err != nil { - return "", err - } + projModel.Groups = groupsMap } if projectTags != "" { logger.PrintIfVerbose("Updating project tags") projModel.Tags = createTagMap(projectTags) } - if len(applicationID) > 0 { - logger.PrintIfVerbose("Updating project applicationIds") - projModel.ApplicationIds = createApplicationIds(applicationID, projModelResp.ApplicationIds) - } err = projectsWrapper.Update(projectID, &projModel) if err != nil { return "", errors.Errorf("%s: %v", failedUpdatingProj, err) @@ -724,15 +693,6 @@ func updateProject( return projectID, nil } -func createApplicationIds(applicationID, existingApplicationIds []string) []string { - for _, id := range applicationID { - if !util.Contains(existingApplicationIds, id) { - existingApplicationIds = append(existingApplicationIds, id) - } - } - return existingApplicationIds -} - func setupScanTags(input *[]byte, cmd *cobra.Command) { tagListStr, _ := cmd.Flags().GetString(commonParams.TagList) tags := strings.Split(tagListStr, ",") @@ -778,8 +738,6 @@ func setupScanTypeProjectAndConfig( projectsWrapper wrappers.ProjectsWrapper, groupsWrapper wrappers.GroupsWrapper, scansWrapper wrappers.ScansWrapper, - applicationsWrapper wrappers.ApplicationsWrapper, - accessManagementWrapper wrappers.AccessManagementWrapper, ) error { var info map[string]interface{} newProjectName, _ := cmd.Flags().GetString(commonParams.ProjectName) @@ -796,35 +754,15 @@ func setupScanTypeProjectAndConfig( } else { return errors.Errorf("Project name is required") } - - applicationName, err := cmd.Flags().GetString(commonParams.ApplicationName) - if err != nil { - return err - } - - var applicationID []string - if applicationName != "" { - application, getAppErr := getApplication(applicationName, applicationsWrapper) - if getAppErr != nil { - return getAppErr - } - if application == nil { - return errors.Errorf(applicationErrors.ApplicationDoesntExistOrNoPermission) - } - applicationID = []string{application.ID} - } - // We need to convert the project name into an ID - projectID, findProjectErr := findProject( - applicationID, + projectID, err := findProject( info["project"].(map[string]interface{})["id"].(string), cmd, projectsWrapper, groupsWrapper, - accessManagementWrapper, ) - if findProjectErr != nil { - return findProjectErr + if err != nil { + return err } info["project"].(map[string]interface{})["id"] = projectID // Handle the scan configuration @@ -872,35 +810,6 @@ func setupScanTypeProjectAndConfig( return err } -func getApplication(applicationName string, applicationsWrapper wrappers.ApplicationsWrapper) (*wrappers.Application, error) { - if applicationName != "" { - params := make(map[string]string) - params["name"] = applicationName - resp, err := applicationsWrapper.Get(params) - if err != nil { - - return nil, err - } - if resp.Applications != nil && len(resp.Applications) > 0 { - application := verifyApplicationNameExactMatch(applicationName, resp) - - return application, nil - } - } - return nil, nil -} - -func verifyApplicationNameExactMatch(applicationName string, resp *wrappers.ApplicationsResponseModel) *wrappers.Application { - var application *wrappers.Application - for i := range resp.Applications { - if resp.Applications[i].Name == applicationName { - application = &resp.Applications[i] - break - } - } - return application -} - func getResubmitConfiguration(scansWrapper wrappers.ScansWrapper, projectID, userScanTypes string) ( []wrappers.Config, error, @@ -1418,6 +1327,7 @@ func UnzipFile(f string) (string, error) { defer func() { _ = archive.Close() }() + for _, f := range archive.File { filePath := filepath.Join(tempDir, f.Name) logger.PrintIfVerbose("unzipping file " + filePath + "...") @@ -1501,8 +1411,6 @@ func runCreateScanCommand( risksOverviewWrapper wrappers.RisksOverviewWrapper, jwtWrapper wrappers.JWTWrapper, policyWrapper wrappers.PolicyWrapper, - accessManagementWrapper wrappers.AccessManagementWrapper, - applicationsWrapper wrappers.ApplicationsWrapper, ) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { err := validateScanTypes(cmd, jwtWrapper) @@ -1523,8 +1431,6 @@ func runCreateScanCommand( projectsWrapper, groupsWrapper, scansWrapper, - accessManagementWrapper, - applicationsWrapper, ) if err != nil { return errors.Errorf("%s", err) @@ -1568,7 +1474,7 @@ func runCreateScanCommand( if policyTimeout < 0 { return errors.Errorf("--%s should be equal or higher than 0", commonParams.PolicyTimeoutFlag) } - policyResponseModel, err = policymanagement.HandlePolicyWait(waitDelay, policyTimeout, policyWrapper, scanResponseModel.ID, scanResponseModel.ProjectID, cmd) + policyResponseModel, err = handlePolicyWait(waitDelay, policyTimeout, policyWrapper, scanResponseModel, cmd) if err != nil { return err } @@ -1593,7 +1499,7 @@ func runCreateScanCommand( cleanUpTempZip(zipFilePath) // verify break build from policy - if policyResponseModel != nil && len(policyResponseModel.Policies) > 0 && policyResponseModel.BreakBuild { + if policyResponseModel != nil && len(policyResponseModel.Polices) > 0 && policyResponseModel.BreakBuild { logger.PrintIfVerbose("Breaking the build due to policy violation") return errors.Errorf("Policy Violation - Break Build Enabled. To bypass the policy evaluation and continue with the build, you can use the `--ignore-policy` flag.") } @@ -1618,13 +1524,11 @@ func createScanModel( projectsWrapper wrappers.ProjectsWrapper, groupsWrapper wrappers.GroupsWrapper, scansWrapper wrappers.ScansWrapper, - accessManagementWrapper wrappers.AccessManagementWrapper, - applicationsWrapper wrappers.ApplicationsWrapper, ) (*wrappers.Scan, string, error) { var input = []byte("{}") // Define type, project and config in scan model - err := setupScanTypeProjectAndConfig(&input, cmd, projectsWrapper, groupsWrapper, scansWrapper, applicationsWrapper, accessManagementWrapper) + err := setupScanTypeProjectAndConfig(&input, cmd, projectsWrapper, groupsWrapper, scansWrapper) if err != nil { return nil, "", err } @@ -1765,6 +1669,29 @@ func handleWait( return nil } +func handlePolicyWait( + waitDelay, + timeoutMinutes int, + policyWrapper wrappers.PolicyWrapper, + scanResponseModel *wrappers.ScanResponseModel, + cmd *cobra.Command, +) (*wrappers.PolicyResponseModel, error) { + policyResponseModel, err := waitForPolicyCompletion( + waitDelay, + timeoutMinutes, + policyWrapper, + scanResponseModel, + cmd) + if err != nil { + verboseFlag, _ := cmd.Flags().GetBool(commonParams.DebugFlag) + if verboseFlag { + logger.PrintIfVerbose("Policy evaluation failed") + } + return nil, err + } + return policyResponseModel, nil +} + func createReportsAfterScan( cmd *cobra.Command, scanID string, @@ -1954,6 +1881,45 @@ func waitForScanCompletion( return nil } +func waitForPolicyCompletion( + waitDelay int, + timeoutMinutes int, + policyWrapper wrappers.PolicyWrapper, + scanResponseModel *wrappers.ScanResponseModel, + cmd *cobra.Command, +) (*wrappers.PolicyResponseModel, error) { + logger.PrintIfVerbose("Waiting for policy evaluation to complete for scanID:" + scanResponseModel.ID + " and projectID:" + scanResponseModel.ProjectID) + var policyResponseModel *wrappers.PolicyResponseModel + timeout := time.Now().Add(time.Duration(timeoutMinutes) * time.Minute) + fixedWait := time.Duration(waitDelay) * time.Second + i := uint64(0) + if !cmd.Flags().Changed(commonParams.RetryDelayFlag) { + viper.Set(commonParams.RetryDelayFlag, commonParams.RetryDelayPollingDefault) + } + for { + variableWait := time.Duration(math.Min(float64(i/uint64(waitDelay)), maxPollingWaitTime)) * time.Second + waitDuration := fixedWait + variableWait + logger.PrintfIfVerbose("Sleeping %v before polling", waitDuration) + time.Sleep(waitDuration) + evaluated := false + var err error + evaluated, policyResponseModel, err = isPolicyEvaluated(policyWrapper, scanResponseModel.ID, scanResponseModel.ProjectID) + if err != nil { + return nil, err + } + if evaluated { + break + } + if timeoutMinutes > 0 && time.Now().After(timeout) { + logger.PrintfIfVerbose("Timeout of %d minute(s) for policy evaluation reached", timeoutMinutes) + return nil, nil + } + i++ + } + logger.PrintIfVerbose("Policy evaluation completed with status" + policyResponseModel.Status) + return policyResponseModel, nil +} + func isScanRunning( scansWrapper wrappers.ScansWrapper, resultsSbomWrapper wrappers.ResultsSbomWrapper, @@ -1999,6 +1965,40 @@ func isScanRunning( return false, nil } +func isPolicyEvaluated( + policyWrapper wrappers.PolicyWrapper, + scanID, + projectID string, +) (bool, *wrappers.PolicyResponseModel, error) { + var errorModel *wrappers.WebError + var err error + var policyResponseModel *wrappers.PolicyResponseModel + var params = make(map[string]string) + + params["scanId"] = scanID + params["astProjectId"] = projectID + + policyResponseModel, errorModel, err = policyWrapper.EvaluatePolicy(params) + if err != nil { + return false, nil, err + } + if errorModel != nil { + log.Fatalf(fmt.Sprintf("%s: CODE: %d, %s", failedGetting, errorModel.Code, errorModel.Message)) + } else if policyResponseModel != nil { + if policyResponseModel.Status == evaluatingPolicy { + log.Println("Policy status: ", policyResponseModel.Status) + return false, nil, nil + } + } + // Case the policy is evaluated or None + logger.PrintIfVerbose("Policy evaluation finished with status: " + policyResponseModel.Status) + if policyResponseModel.Status == completedPolicy || policyResponseModel.Status == nonePolicy { + logger.PrintIfVerbose("Policy status: " + policyResponseModel.Status) + return true, policyResponseModel, nil + } + return true, nil, nil +} + func runListScansCommand(scansWrapper wrappers.ScansWrapper, sastMetadataWrapper wrappers.SastMetadataWrapper) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { var allScansModel *wrappers.ScansCollectionResponseModel @@ -2017,11 +2017,7 @@ func runListScansCommand(scansWrapper wrappers.ScansWrapper, sastMetadataWrapper if errorModel != nil { return errors.Errorf(ErrorCodeFormat, failedGettingAll, errorModel.Code, errorModel.Message) } else if allScansModel != nil && allScansModel.Scans != nil { - views, err := toScanViews(allScansModel.Scans, sastMetadataWrapper) - if err != nil { - return err - } - err = printByFormat(cmd, views) + err = printByFormat(cmd, toScanViews(allScansModel.Scans, sastMetadataWrapper)) if err != nil { return err } @@ -2199,7 +2195,7 @@ type scanView struct { Engines []string } -func toScanViews(scans []wrappers.ScanResponseModel, sastMetadataWrapper wrappers.SastMetadataWrapper) ([]*scanView, error) { +func toScanViews(scans []wrappers.ScanResponseModel, sastMetadataWrapper wrappers.SastMetadataWrapper) []*scanView { scanIDs := make([]string, len(scans)) for i := range scans { scanIDs[i] = scans[i].ID @@ -2210,7 +2206,7 @@ func toScanViews(scans []wrappers.ScanResponseModel, sastMetadataWrapper wrapper sastMetadata, err := sastMetadataWrapper.GetSastMetadataByIDs(paramsToSast) if err != nil { logger.Printf("error getting sast metadata: %v", err) - return nil, err + return nil } metadataMap := make(map[string]bool) @@ -2224,7 +2220,7 @@ func toScanViews(scans []wrappers.ScanResponseModel, sastMetadataWrapper wrapper scans[i].SastIncremental = strconv.FormatBool(metadataMap[scans[i].ID]) views[i] = toScanView(&scans[i]) } - return views, nil + return views } func toScanView(scan *wrappers.ScanResponseModel) *scanView { diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 658661460..5c2d7c80d 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -7,10 +7,8 @@ import ( "strings" "testing" - applicationErrors "github.com/checkmarx/ast-cli/internal/errors" commonParams "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" - "github.com/checkmarx/ast-cli/internal/wrappers/mock" "gotest.tools/assert" "github.com/checkmarx/ast-cli/internal/commands/util" @@ -124,44 +122,6 @@ func TestCreateScan(t *testing.T) { execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") } -func TestScanCreate_ExistingApplicationAndProject_CreateProjectUnderApplicationSuccessfully(t *testing.T) { - execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") -} - -func TestScanCreate_ApplicationNameIsNotExactMatch_FailedToCreateScan(t *testing.T) { - err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", "MOC", "-s", dummyRepo, "-b", "dummy_branch") - assert.Assert(t, err.Error() == applicationErrors.ApplicationDoesntExistOrNoPermission) -} - -func TestScanCreate_ExistingProjectAndApplicationWithNoPermission_FailedToCreateScan(t *testing.T) { - err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", mock.ApplicationDoesntExist, "-s", dummyRepo, "-b", "dummy_branch") - assert.Assert(t, err.Error() == applicationErrors.ApplicationDoesntExistOrNoPermission) -} - -func TestScanCreate_ExistingApplication_CreateNewProjectUnderApplicationSuccessfully(t *testing.T) { - execCmdNilAssertion(t, "scan", "create", "--project-name", "NewProject", "--application-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch") -} - -func TestScanCreate_ExistingApplicationWithNoPermission_FailedToCreateScan(t *testing.T) { - err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "NewProject", "--application-name", mock.NoPermissionApp, "-s", dummyRepo, "-b", "dummy_branch") - assert.Assert(t, err.Error() == applicationErrors.ApplicationDoesntExistOrNoPermission) -} - -func TestScanCreate_OnReceivingHttpBadRequestStatusCode_FailedToCreateScan(t *testing.T) { - err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", mock.FakeHTTPStatusBadRequest, "-s", dummyRepo, "-b", "dummy_branch") - assert.Assert(t, err.Error() == applicationErrors.FailedToGetApplication) -} - -func TestScanCreate_OnReceivingHttpInternalServerErrorStatusCode_FailedToCreateScan(t *testing.T) { - err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", mock.FakeHTTPStatusInternalServerError, "-s", dummyRepo, "-b", "dummy_branch") - assert.Assert(t, err.Error() == applicationErrors.FailedToGetApplication) -} - -func TestCreateScanInsideApplicationProjectExistNoPermissions(t *testing.T) { - err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", mock.NoPermissionApp, "-s", dummyRepo, "-b", "dummy_branch") - assert.Assert(t, err.Error() == applicationErrors.ApplicationDoesntExistOrNoPermission) -} - func TestCreateScanSourceDirectory(t *testing.T) { baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch"} execCmdNilAssertion(t, append(baseArgs, "-s", "data", "--file-filter", "!.java")...) @@ -284,7 +244,7 @@ func TestCreateScanWithProjectGroup(t *testing.T) { t, "scan", "create", "--project-name", "invalidGroup", "-s", ".", "--project-groups", "invalidGroup", ) - assert.Assert(t, err.Error() == "Failed finding groups: [invalidGroup]", "\n the received error is:", err.Error()) + assert.Assert(t, err.Error() == "Failed finding groups: [invalidGroup]") } func TestScanWorkflowMissingID(t *testing.T) { diff --git a/internal/commands/scarealtime/sca-realtime-utils.go b/internal/commands/scarealtime/sca-realtime-utils.go index dd0d8336f..02d119c66 100644 --- a/internal/commands/scarealtime/sca-realtime-utils.go +++ b/internal/commands/scarealtime/sca-realtime-utils.go @@ -22,7 +22,6 @@ var GetPackageManagerFromResolvingModuleType = map[string]string{ "composer": "Php", "gomodules": "Go", "pip": "Python", - "poetry": "Python", "rubygems": "Ruby", "npm": "Npm", "yarn": "Npm", @@ -35,8 +34,6 @@ var GetPackageManagerFromResolvingModuleType = map[string]string{ "swiftpm": "Ios", "carthage": "Ios", "cocoapods": "Ios", - "nuget": "Nuget", - "cpp": "Cpp", } // downloadSCAResolverAndHashFileIfNeeded Downloads SCA Realtime if it is not downloaded yet diff --git a/internal/commands/scarealtime/sca-realtime.go b/internal/commands/scarealtime/sca-realtime.go index feed5b429..677d9d960 100644 --- a/internal/commands/scarealtime/sca-realtime.go +++ b/internal/commands/scarealtime/sca-realtime.go @@ -2,8 +2,8 @@ package scarealtime import ( "encoding/json" + "io/ioutil" "log" - "os" "strconv" "strings" @@ -129,9 +129,34 @@ func GetSCAVulnerabilities(scaRealTimeWrapper wrappers.ScaRealTimeWrapper) error var modelResults []wrappers.ScaVulnerabilitiesResponseModel var scaRealtimeScanErrors []wrappers.ScaRealtimeScanError - for i, dependencyResolutionResult := range scaResolverResults.DependencyResolutionResults { + for _, dependencyResolutionResult := range scaResolverResults.DependencyResolutionResults { // We're using a map to avoid adding repeated packages in request body - dependencyMap := createDependencyMapFromDependencyResolution(&scaResolverResults.DependencyResolutionResults[i]) + dependencyMap := make(map[string]wrappers.ScaDependencyBodyRequest) + + for i := range dependencyResolutionResult.Dependencies { + var dependency = dependencyResolutionResult.Dependencies[i] + var packageManager = GetPackageManagerFromResolvingModuleType[strings.ToLower(dependency.ResolvingModuleType)] + + // if no package manager is found uses the resolving module type + if packageManager == "" { + packageManager = strings.ToLower(dependency.ResolvingModuleType) + } + + dependencyMap[dependency.ID.NodeID] = wrappers.ScaDependencyBodyRequest{ + PackageName: dependency.ID.Name, + Version: dependency.ID.Version, + PackageManager: packageManager, + } + if len(dependency.Children) > 0 { + for _, dependencyChildren := range dependency.Children { + dependencyMap[dependencyChildren.NodeID] = wrappers.ScaDependencyBodyRequest{ + PackageName: dependencyChildren.Name, + Version: dependencyChildren.Version, + PackageManager: packageManager, + } + } + } + } // Get all ScaDependencyBodyRequest from the map to call SCA API var bodyRequest []wrappers.ScaDependencyBodyRequest @@ -186,37 +211,6 @@ func GetSCAVulnerabilities(scaRealTimeWrapper wrappers.ScaRealTimeWrapper) error return nil } -func createDependencyMapFromDependencyResolution(dependencyResolutionResult *DependencyResolution) map[string]wrappers.ScaDependencyBodyRequest { - // We're using a map to avoid adding repeated packages in request body - dependencyMap := make(map[string]wrappers.ScaDependencyBodyRequest) - - for i := range dependencyResolutionResult.Dependencies { - var dependency = dependencyResolutionResult.Dependencies[i] - var packageManager = GetPackageManagerFromResolvingModuleType[strings.ToLower(dependency.ResolvingModuleType)] - - // if no package manager is found uses the resolving module type - if packageManager == "" { - packageManager = strings.ToLower(dependency.ResolvingModuleType) - } - - dependencyMap[dependency.ID.NodeID] = wrappers.ScaDependencyBodyRequest{ - PackageName: dependency.ID.Name, - Version: dependency.ID.Version, - PackageManager: packageManager, - } - if len(dependency.Children) > 0 { - for _, dependencyChildren := range dependency.Children { - dependencyMap[dependencyChildren.NodeID] = wrappers.ScaDependencyBodyRequest{ - PackageName: dependencyChildren.Name, - Version: dependencyChildren.Version, - PackageManager: packageManager, - } - } - } - } - return dependencyMap -} - func GetScaVulnerabilitiesPackages(scaRealTimeWrapper wrappers.ScaRealTimeWrapper, bodyRequest []wrappers.ScaDependencyBodyRequest) (vulnerabilities []wrappers.ScaVulnerabilitiesResponseModel, err, err1 error) { //nolint:lll // We need to call the SCA API for each DependencyResolution so that we can save the file name vulnerabilitiesResponseModel, errorModel, errVulnerabilities := scaRealTimeWrapper.GetScaVulnerabilitiesPackages(bodyRequest) @@ -307,10 +301,11 @@ func validateProvidedProjectDirectory(cmd *cobra.Command) (string, error) { // readSCAResolverResultsFromFile Get SCA Resolver results from file to build SCA API request body func readSCAResolverResultsFromFile() (ScaResultsFile, error) { - file, err := os.ReadFile(ScaResolverResultsFileNameDir) + file, err := ioutil.ReadFile(ScaResolverResultsFileNameDir) if err != nil { return ScaResultsFile{}, err } + data := ScaResultsFile{} _ = json.Unmarshal(file, &data) diff --git a/internal/commands/scarealtime/sca-realtime_test.go b/internal/commands/scarealtime/sca-realtime_test.go index 891b5fd8b..90d8f9c98 100644 --- a/internal/commands/scarealtime/sca-realtime_test.go +++ b/internal/commands/scarealtime/sca-realtime_test.go @@ -57,38 +57,3 @@ func TestRequiredProjectDir(t *testing.T) { err := cmd.Execute() assert.Error(t, err, "Provided path does not exist: "+invalidProjectPath, err.Error()) } - -func TestCreateDependencyMapFromDependencyResolution_NugetDependencies_Success(t *testing.T) { - dependecyResolutionResult := DependencyResolution{ - Dependencies: []Dependency{ - NewDependency("8ce2d33f-5783-4fe1-b9a7-3ce2c9a3aae9", "Microsoft. NETCore. Platforms", - "1.1.0", "Nuget", []interface{}{"NetStandard20"}), - NewDependency("60b40261-18b2-4cf6-bdf5-e23ad408de3b", "NETStandard.Library", - "2.0.3", "Nuget", []interface{}{"NetStandard20"}), - }, - } - dependencyMap := createDependencyMapFromDependencyResolution(&dependecyResolutionResult) - assert.Equal(t, len(dependencyMap), 2) - assert.Equal(t, dependencyMap["60b40261-18b2-4cf6-bdf5-e23ad408de3b"].PackageManager, "Nuget") - assert.Equal(t, dependencyMap["60b40261-18b2-4cf6-bdf5-e23ad408de3b"].Version, "2.0.3") - assert.Equal(t, dependencyMap["60b40261-18b2-4cf6-bdf5-e23ad408de3b"].PackageName, "NETStandard.Library") - assert.Equal(t, dependencyMap["8ce2d33f-5783-4fe1-b9a7-3ce2c9a3aae9"].PackageManager, "Nuget") - assert.Equal(t, dependencyMap["8ce2d33f-5783-4fe1-b9a7-3ce2c9a3aae9"].Version, "1.1.0") - assert.Equal(t, dependencyMap["8ce2d33f-5783-4fe1-b9a7-3ce2c9a3aae9"].PackageName, "Microsoft. NETCore. Platforms") -} - -func NewDependency(nodeID, name, version, resolvingModuleType string, targetFrameworks []interface{}) Dependency { - return Dependency{ - ID: NewID(nodeID, name, version), - ResolvingModuleType: resolvingModuleType, - TargetFrameworks: targetFrameworks, - } -} - -func NewID(nodeID, name, version string) ID { - return ID{ - NodeID: nodeID, - Name: name, - Version: version, - } -} diff --git a/internal/commands/util/help.go b/internal/commands/util/help.go index f91412027..b1ca4b203 100644 --- a/internal/commands/util/help.go +++ b/internal/commands/util/help.go @@ -16,10 +16,8 @@ func RootHelpFunc(command *cobra.Command) { var commands []string for _, c := range command.Commands() { - if !c.Hidden { - s := rightPad(c.Name()+":", c.NamePadding()) + c.Short - commands = append(commands, s) - } + s := rightPad(c.Name()+":", c.NamePadding()) + c.Short + commands = append(commands, s) } type helpEntry struct { diff --git a/internal/commands/util/pr.go b/internal/commands/util/pr.go index 0eacdf9b3..aeaf1bc7b 100644 --- a/internal/commands/util/pr.go +++ b/internal/commands/util/pr.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/MakeNowJust/heredoc" - "github.com/checkmarx/ast-cli/internal/commands/policymanagement" "github.com/checkmarx/ast-cli/internal/logger" "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" @@ -17,12 +16,9 @@ const ( failedCreatingGithubPrDecoration = "Failed creating github PR Decoration" failedCreatingGitlabPrDecoration = "Failed creating gitlab MR Decoration" errorCodeFormat = "%s: CODE: %d, %s\n" - policyErrorFormat = "%s: Failed to get scanID policy information" - waitDelayDefault = 5 - resultPolicyDefaultTimeout = 1 ) -func NewPRDecorationCommand(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) *cobra.Command { +func NewPRDecorationCommand(prWrapper wrappers.PRWrapper) *cobra.Command { cmd := &cobra.Command{ Use: "pr", Short: "Posts the comment with scan results on the Pull Request", @@ -33,15 +29,15 @@ func NewPRDecorationCommand(prWrapper wrappers.PRWrapper, policyWrapper wrappers ), } - prDecorationGithub := PRDecorationGithub(prWrapper, policyWrapper, scansWrapper) - prDecorationGitlab := PRDecorationGitlab(prWrapper, policyWrapper, scansWrapper) + prDecorationGithub := PRDecorationGithub(prWrapper) + prDecorationGitlab := PRDecorationGitlab(prWrapper) cmd.AddCommand(prDecorationGithub) cmd.AddCommand(prDecorationGitlab) return cmd } -func PRDecorationGithub(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) *cobra.Command { +func PRDecorationGithub(prWrapper wrappers.PRWrapper) *cobra.Command { prDecorationGithub := &cobra.Command{ Use: "github", Short: "Decorate github PR with vulnerabilities", @@ -58,7 +54,7 @@ func PRDecorationGithub(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Pol `, ), }, - RunE: runPRDecoration(prWrapper, policyWrapper, scansWrapper), + RunE: runPRDecoration(prWrapper), } prDecorationGithub.Flags().String(params.ScanIDFlag, "", "Scan ID to retrieve results from") @@ -80,7 +76,7 @@ func PRDecorationGithub(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Pol return prDecorationGithub } -func PRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) *cobra.Command { +func PRDecorationGitlab(prWrapper wrappers.PRWrapper) *cobra.Command { prDecorationGitlab := &cobra.Command{ Use: "gitlab", Short: "Decorate gitlab PR with vulnerabilities", @@ -97,7 +93,7 @@ func PRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Pol `, ), }, - RunE: runPRDecorationGitlab(prWrapper, policyWrapper, scansWrapper), + RunE: runPRDecorationGitlab(prWrapper), } prDecorationGitlab.Flags().String(params.ScanIDFlag, "", "Scan ID to retrieve results from") @@ -121,7 +117,7 @@ func PRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Pol return prDecorationGitlab } -func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) func(cmd *cobra.Command, args []string) error { +func runPRDecoration(prWrapper wrappers.PRWrapper) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { scanID, _ := cmd.Flags().GetString(params.ScanIDFlag) scmTokenFlag, _ := cmd.Flags().GetString(params.SCMTokenFlag) @@ -129,22 +125,16 @@ func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Policy repoNameFlag, _ := cmd.Flags().GetString(params.RepoNameFlag) prNumberFlag, _ := cmd.Flags().GetInt(params.PRNumberFlag) - // Retrieve policies related to the scan and project to include in the PR decoration - policies, policyError := getScanViolatedPolicies(scansWrapper, policyWrapper, scanID, cmd) - if policyError != nil { - return errors.Errorf(policyErrorFormat, failedCreatingGithubPrDecoration) - } - - // Build and post the pr decoration prModel := &wrappers.PRModel{ ScanID: scanID, ScmToken: scmTokenFlag, Namespace: namespaceFlag, RepoName: repoNameFlag, PrNumber: prNumberFlag, - Policies: policies, } + prResponse, errorModel, err := prWrapper.PostPRDecoration(prModel) + if err != nil { return err } @@ -159,7 +149,7 @@ func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Policy } } -func runPRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) func(cmd *cobra.Command, args []string) error { +func runPRDecorationGitlab(prWrapper wrappers.PRWrapper) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { scanID, _ := cmd.Flags().GetString(params.ScanIDFlag) scmTokenFlag, _ := cmd.Flags().GetString(params.SCMTokenFlag) @@ -168,13 +158,6 @@ func runPRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers. iIDFlag, _ := cmd.Flags().GetInt(params.PRIidFlag) gitlabProjectIDFlag, _ := cmd.Flags().GetInt(params.PRGitlabProjectFlag) - // Retrieve policies related to the scan and project to include in the PR decoration - policies, policyError := getScanViolatedPolicies(scansWrapper, policyWrapper, scanID, cmd) - if policyError != nil { - return errors.Errorf(policyErrorFormat, failedCreatingGitlabPrDecoration) - } - - // Build and post the mr decoration prModel := &wrappers.GitlabPRModel{ ScanID: scanID, ScmToken: scmTokenFlag, @@ -182,7 +165,6 @@ func runPRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers. RepoName: repoNameFlag, IiD: iIDFlag, GitlabProjectID: gitlabProjectIDFlag, - Policies: policies, } prResponse, errorModel, err := prWrapper.PostGitlabPRDecoration(prModel) @@ -200,39 +182,3 @@ func runPRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers. return nil } } - -func getScanViolatedPolicies(scansWrapper wrappers.ScansWrapper, policyWrapper wrappers.PolicyWrapper, scanID string, cmd *cobra.Command) ([]wrappers.PrPolicy, error) { - // retrieve scan model to get the projectID - scanResponseModel, errorScanModel, err := scansWrapper.GetByID(scanID) - if err != nil { - return nil, err - } - if errorScanModel != nil { - return nil, err - } - // retrieve policy information to send to the PR service - policyResponseModel, err := policymanagement.HandlePolicyWait(waitDelayDefault, - resultPolicyDefaultTimeout, - policyWrapper, - scanID, - scanResponseModel.ProjectID, - cmd) - if err != nil { - return nil, err - } - // transform into the PR model for violated policies - violatedPolicies := policiesToPrPolicies(policyResponseModel.Policies) - return violatedPolicies, nil -} - -func policiesToPrPolicies(policies []wrappers.Policy) []wrappers.PrPolicy { - var prPolicies []wrappers.PrPolicy - for _, policy := range policies { - prPolicy := wrappers.PrPolicy{} - prPolicy.Name = policy.Name - prPolicy.BreakBuild = policy.BreakBuild - prPolicy.RulesNames = policy.RulesViolated - prPolicies = append(prPolicies, prPolicy) - } - return prPolicies -} diff --git a/internal/commands/util/pr_test.go b/internal/commands/util/pr_test.go index 1deca97b2..d731dd53c 100644 --- a/internal/commands/util/pr_test.go +++ b/internal/commands/util/pr_test.go @@ -7,7 +7,7 @@ import ( ) func TestNewPRDecorationCommandMustExist(t *testing.T) { - cmd := PRDecorationGithub(nil, nil, nil) + cmd := PRDecorationGithub(nil) assert.Assert(t, cmd != nil, "PR decoration command must exist") err := cmd.Execute() @@ -15,7 +15,7 @@ func TestNewPRDecorationCommandMustExist(t *testing.T) { } func TestNewMRDecorationCommandMustExist(t *testing.T) { - cmd := PRDecorationGitlab(nil, nil, nil) + cmd := PRDecorationGitlab(nil) assert.Assert(t, cmd != nil, "MR decoration command must exist") err := cmd.Execute() diff --git a/internal/commands/util/remediation.go b/internal/commands/util/remediation.go index 79081dd9f..24c6e780d 100644 --- a/internal/commands/util/remediation.go +++ b/internal/commands/util/remediation.go @@ -3,6 +3,7 @@ package util import ( "encoding/json" "fmt" + "io/ioutil" "os" "os/exec" "path/filepath" @@ -21,7 +22,6 @@ import ( const ( npmPackageFilename = "package.json" permission = 0644 - permission0666 = 0666 containerStarting = "Starting kics container" filesContainerLocation = "/files/" filesContainerVolume = ":/files" @@ -298,7 +298,7 @@ func runKicsRemediation(cmd *cobra.Command, volumeMap, tempDir string) error { } func createKicsRemediateEnv(cmd *cobra.Command) (volume, kicsDir string, err error) { - kicsDir, err = os.MkdirTemp("", "kics") + kicsDir, err = ioutil.TempDir("", "kics") if err != nil { return "", "", errors.New(directoryError) } @@ -307,7 +307,7 @@ func createKicsRemediateEnv(cmd *cobra.Command) (volume, kicsDir string, err err if file == "" { return "", "", errors.New(" No results file was provided") } - kicsFile, err := os.ReadFile(kicsResultsPath) + kicsFile, err := ioutil.ReadFile(kicsResultsPath) if err != nil { return "", "", err } @@ -317,7 +317,7 @@ func createKicsRemediateEnv(cmd *cobra.Command) (volume, kicsDir string, err err return "", "", err } destinationFile := fmt.Sprintf("%s/%s", kicsDir, file) - err = os.WriteFile(destinationFile, kicsFile, permission0666) + err = ioutil.WriteFile(destinationFile, kicsFile, 0666) if err != nil { return "", "", errors.New(containerWriteFolderError) } diff --git a/internal/commands/util/utils.go b/internal/commands/util/utils.go index 52e98a8f0..7284f8533 100644 --- a/internal/commands/util/utils.go +++ b/internal/commands/util/utils.go @@ -28,8 +28,6 @@ func NewUtilsCommand( learnMoreWrapper wrappers.LearnMoreWrapper, tenantWrapper wrappers.TenantConfigurationWrapper, chatWrapper wrappers.ChatWrapper, - policyWrapper wrappers.PolicyWrapper, - scansWrapper wrappers.ScansWrapper, ) *cobra.Command { utilsCmd := &cobra.Command{ Use: "utils", @@ -52,7 +50,7 @@ func NewUtilsCommand( completionCmd := NewCompletionCommand() - prDecorationCmd := NewPRDecorationCommand(prWrapper, policyWrapper, scansWrapper) + prDecorationCmd := NewPRDecorationCommand(prWrapper) remediationCmd := NewRemediationCommand() diff --git a/internal/commands/util/utils_test.go b/internal/commands/util/utils_test.go index 7e5a52c1c..4bbf5086a 100644 --- a/internal/commands/util/utils_test.go +++ b/internal/commands/util/utils_test.go @@ -9,7 +9,6 @@ import ( const mockFormatErrorMessage = "Invalid format MOCK" func TestNewUtilsCommand(t *testing.T) { - cmd := NewUtilsCommand(nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil) + cmd := NewUtilsCommand(nil, nil, nil, nil, nil, nil, nil, nil, nil) assert.Assert(t, cmd != nil, "Utils command must exist") } diff --git a/internal/errors/application-errors.go b/internal/errors/application-errors.go deleted file mode 100644 index 92aebb0c0..000000000 --- a/internal/errors/application-errors.go +++ /dev/null @@ -1,9 +0,0 @@ -package applicationerrors - -const ( - ApplicationDoesntExistOrNoPermission = "Provided application does not exist or user has no permission to the application" -) - -const ( - FailedToGetApplication = "Failed to get application" -) diff --git a/internal/params/binds.go b/internal/params/binds.go index f522daf70..6a790baff 100644 --- a/internal/params/binds.go +++ b/internal/params/binds.go @@ -15,7 +15,6 @@ var EnvVarsBinds = []struct { {CodeBashingPathKey, ScansPathEnv, "api/codebashing/lessons"}, {ScansPathKey, ScansPathEnv, "api/scans"}, {ProjectsPathKey, ProjectsPathEnv, "api/projects"}, - {ApplicationsPathKey, ApplicationsPathEnv, "api/applications"}, {GroupsPathKey, GroupsPathEnv, "auth/realms/organization/pip/groups"}, {ResultsPathKey, ResultsPathEnv, "api/results"}, {ScanSummaryPathKey, ScanSummaryPathEnv, "api/scan-summary"}, @@ -61,5 +60,4 @@ var EnvVarsBinds = []struct { {ResultsSbomReportProxyPathKey, ResultsSbomReportProxyPathEnv, "api/sca/risk-management/risk-reports"}, {FeatureFlagsKey, FeatureFlagsEnv, "api/flags"}, {PolicyEvaluationPathKey, PolicyEvaluationPathEnv, "api/policy_management_service_uri/evaluation"}, - {AccessManagementPathKey, AccessManagementPathEnv, "api/access-management"}, } diff --git a/internal/params/envs.go b/internal/params/envs.go index 0d1a426d7..2c55459fe 100644 --- a/internal/params/envs.go +++ b/internal/params/envs.go @@ -18,7 +18,6 @@ const ( GroupsPathEnv = "CX_GROUPS_PATH" AgentNameEnv = "CX_AGENT_NAME" ProjectsPathEnv = "CX_PROJECTS_PATH" - ApplicationsPathEnv = "CX_APPLICATIONS_PATH" ResultsPathEnv = "CX_RESULTS_PATH" ScanSummaryPathEnv = "CX_SCAN_SUMMARY_PATH" ScaPackagePathEnv = "CX_SCA_PACKAGE_PATH" @@ -59,6 +58,5 @@ const ( FeatureFlagsEnv = "CX_FEATURE_FLAGS_PATH" UploadURLEnv = "CX_UPLOAD_URL" PolicyEvaluationPathEnv = "CX_POLICY_EVALUATION_PATH" - AccessManagementPathEnv = "CX_ACCESS_MANAGEMENT_PATH" IgnoreProxyEnv = "CX_IGNORE_PROXY" ) diff --git a/internal/params/filters.go b/internal/params/filters.go index 656980b8d..2404e6305 100644 --- a/internal/params/filters.go +++ b/internal/params/filters.go @@ -130,8 +130,6 @@ var BaseFilters = []string{ "go.sum", "Podfile", "Podfile.lock", - "*.cmp", - "Directory.Packages.props", } var KicsBaseFilters = []string{ diff --git a/internal/params/flags.go b/internal/params/flags.go index 08d86331e..f5831069b 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -4,7 +4,6 @@ package params const ( AgentFlag = "agent" AgentFlagUsage = "Scan origin name" - ApplicationName = "application-name" DefaultAgent = "ASTCLI" DebugFlag = "debug" DebugUsage = "Debug mode with detailed logs" @@ -135,7 +134,6 @@ const ( ExploitablePathFlag = "sca-exploitable-path" LastSastScanTime = "sca-last-sast-scan-time" ProjecPrivatePackageFlag = "project-private-package" - SastRedundancyFlag = "sast-redundancy" ScaPrivatePackageVersionFlag = "sca-private-package-version" @@ -224,7 +222,6 @@ const ( SastType = "sast" KicsType = "kics" APISecurityType = "api-security" - ContainersType = "containers" APIDocumentationFlag = "apisec-swagger-filter" IacType = "iac-security" IacLabel = "IaC Security" diff --git a/internal/params/keys.go b/internal/params/keys.go index 0ed4b1f98..28c448a33 100644 --- a/internal/params/keys.go +++ b/internal/params/keys.go @@ -18,7 +18,6 @@ var ( IgnoreProxyKey = strings.ToLower(IgnoreProxyEnv) CodeBashingPathKey = strings.ToLower(CodeBashingPathEnv) ProjectsPathKey = strings.ToLower(ProjectsPathEnv) - ApplicationsPathKey = strings.ToLower(ApplicationsPathEnv) ResultsPathKey = strings.ToLower(ResultsPathEnv) ScanSummaryPathKey = strings.ToLower(ScanSummaryPathEnv) RisksOverviewPathKey = strings.ToLower(RisksOverviewPathEnv) @@ -60,5 +59,4 @@ var ( ResultsSbomReportProxyPathKey = strings.ToLower(ResultsSbomReportProxyPathEnv) FeatureFlagsKey = strings.ToLower(FeatureFlagsEnv) PolicyEvaluationPathKey = strings.ToLower(PolicyEvaluationPathEnv) - AccessManagementPathKey = strings.ToLower(AccessManagementPathEnv) ) diff --git a/internal/wrappers/access-management-http.go b/internal/wrappers/access-management-http.go deleted file mode 100644 index 2ea265826..000000000 --- a/internal/wrappers/access-management-http.go +++ /dev/null @@ -1,88 +0,0 @@ -package wrappers - -import ( - "bytes" - "encoding/json" - "fmt" - "net/http" - - "github.com/checkmarx/ast-cli/internal/logger" - commonParams "github.com/checkmarx/ast-cli/internal/params" - "github.com/pkg/errors" - "github.com/spf13/viper" -) - -const ( - // APIs - createAssignmentPath = "" - entitiesForPath = "entities-for" - // EntityTypes - groupEntityType = "group" - projectResourceType = "project" -) - -type AccessManagementHTTPWrapper struct { - path string - clientTimeout uint -} - -func NewAccessManagementHTTPWrapper(path string) AccessManagementWrapper { - return &AccessManagementHTTPWrapper{ - path: path, - clientTimeout: viper.GetUint(commonParams.ClientTimeoutKey), - } -} -func (a *AccessManagementHTTPWrapper) CreateGroupsAssignment(projectID, projectName string, groups []*Group) error { - var resp *http.Response - for _, group := range groups { - assignment := AssignmentPayload{ - EntityID: group.ID, - EntityType: groupEntityType, - //EntityRoles: nil, // be used in the access-management phase 2 - ResourceID: projectID, - ResourceType: projectResourceType, - } - params, err := json.Marshal(assignment) - if err != nil { - return errors.Wrapf(err, "Failed to parse request body") - } - path := fmt.Sprintf("%s/%s", a.path, createAssignmentPath) - resp, err = SendHTTPRequestWithJSONContentType(http.MethodPost, path, bytes.NewBuffer(params), true, a.clientTimeout) - if err != nil { - return errors.Wrapf(err, "Failed to create groups assignment") - } - logger.PrintfIfVerbose("group '%s' assignment for project %s created", group.Name, projectName) - resp.Body.Close() - } - logger.PrintIfVerbose("Groups assignment created successfully") - return nil -} - -func (a *AccessManagementHTTPWrapper) GetGroups(projectID string) ([]*Group, error) { - path := fmt.Sprintf("%s/%s?resource-id=%s&resource-type=project", a.path, entitiesForPath, projectID) - resp, err := SendHTTPRequest(http.MethodGet, path, nil, true, a.clientTimeout) - if err != nil { - return nil, errors.Wrapf(err, "Failed to get groups") - } - defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - return nil, errors.Errorf("Failed to get groups, status code: %d", resp.StatusCode) - } - var assignments []*AssignmentResponse - var groups []*Group - decoder := json.NewDecoder(resp.Body) - err = decoder.Decode(&assignments) - if err != nil { - return nil, errors.Wrapf(err, "Failed to parse response body") - } - for _, assignment := range assignments { - if assignment.EntityType == groupEntityType { - group := &Group{ - ID: assignment.EntityID, - Name: assignment.EntityName, - } - groups = append(groups, group) - } - } - return groups, nil -} diff --git a/internal/wrappers/access-management.go b/internal/wrappers/access-management.go deleted file mode 100644 index a578eaaf8..000000000 --- a/internal/wrappers/access-management.go +++ /dev/null @@ -1,24 +0,0 @@ -package wrappers - -type AssignmentResponse struct { - EntityID string `json:"entityID"` - EntityType string `json:"entityType"` - EntityName string `json:"entityName"` - EntityRoles []string `json:"entityRoles"` - ResourceID string `json:"resourceID"` - ResourceType string `json:"resourceType"` - ResourceName string `json:"resourceName"` -} - -type AccessManagementWrapper interface { - CreateGroupsAssignment(projectID, projectName string, groups []*Group) error - GetGroups(projectID string) ([]*Group, error) -} - -type AssignmentPayload struct { - EntityID string `json:"entityID"` - EntityType string `json:"entityType"` - EntityRoles []interface{} `json:"entityRoles"` - ResourceType string `json:"resourceType"` - ResourceID string `json:"resourceID"` -} diff --git a/internal/wrappers/application-http.go b/internal/wrappers/application-http.go deleted file mode 100644 index c53ffdf17..000000000 --- a/internal/wrappers/application-http.go +++ /dev/null @@ -1,60 +0,0 @@ -package wrappers - -import ( - "encoding/json" - "net/http" - - applicationErrors "github.com/checkmarx/ast-cli/internal/errors" - commonParams "github.com/checkmarx/ast-cli/internal/params" - "github.com/pkg/errors" - "github.com/spf13/viper" -) - -type ApplicationsHTTPWrapper struct { - path string -} - -func NewApplicationsHTTPWrapper(path string) ApplicationsWrapper { - return &ApplicationsHTTPWrapper{ - path: path, - } -} - -func (a *ApplicationsHTTPWrapper) Get(params map[string]string) (*ApplicationsResponseModel, error) { - if _, ok := params[limit]; !ok { - params[limit] = limitValue - } - - clientTimeout := viper.GetUint(commonParams.ClientTimeoutKey) - - resp, err := SendHTTPRequestWithQueryParams(http.MethodGet, a.path, params, nil, clientTimeout) - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() - - if err != nil { - return nil, err - } - decoder := json.NewDecoder(resp.Body) - - switch resp.StatusCode { - case http.StatusBadRequest, http.StatusInternalServerError: - if err != nil { - return nil, errors.Errorf(applicationErrors.FailedToGetApplication) - } - return nil, nil - case http.StatusForbidden: - return nil, errors.Errorf(applicationErrors.ApplicationDoesntExistOrNoPermission) - case http.StatusOK: - model := ApplicationsResponseModel{} - err = decoder.Decode(&model) - if err != nil { - return nil, errors.Errorf(applicationErrors.FailedToGetApplication) - } - return &model, nil - default: - return nil, errors.Errorf("response status code %d", resp.StatusCode) - } -} diff --git a/internal/wrappers/application.go b/internal/wrappers/application.go deleted file mode 100644 index 6bb30d62a..000000000 --- a/internal/wrappers/application.go +++ /dev/null @@ -1,36 +0,0 @@ -package wrappers - -import "time" - -type ApplicationsResponseModel struct { - TotalCount int `json:"totalCount"` - FilteredTotalCount int `json:"filteredTotalCount"` - Applications []Application `json:"applications"` -} - -type Application struct { - ID string `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Criticality int `json:"criticality"` - Rules []Rule `json:"rules"` - ProjectIds []string `json:"projectIds"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - Tags Tags `json:"tags"` -} - -type Rule struct { - ID string `json:"id"` - Type string `json:"type"` - Value string `json:"value"` -} - -type Tags struct { - Test string `json:"test"` - Priority string `json:"priority"` -} - -type ApplicationsWrapper interface { - Get(params map[string]string) (*ApplicationsResponseModel, error) -} diff --git a/internal/wrappers/azure-http.go b/internal/wrappers/azure-http.go index df8b98b52..735d26952 100644 --- a/internal/wrappers/azure-http.go +++ b/internal/wrappers/azure-http.go @@ -112,11 +112,7 @@ func (g *AzureHTTPWrapper) get( if err != nil { return false, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() logger.PrintResponse(resp, true) diff --git a/internal/wrappers/bfl-http.go b/internal/wrappers/bfl-http.go index c633fc684..b1c223b91 100644 --- a/internal/wrappers/bfl-http.go +++ b/internal/wrappers/bfl-http.go @@ -36,11 +36,7 @@ func (r *BflHTTPWrapper) GetBflByScanIDAndQueryID(params map[string]string) ( if err != nil { return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handleBflResponseWithBody(resp, err) } diff --git a/internal/wrappers/bitbucket-http.go b/internal/wrappers/bitbucket-http.go index 8be2abf34..f840f76c2 100644 --- a/internal/wrappers/bitbucket-http.go +++ b/internal/wrappers/bitbucket-http.go @@ -154,11 +154,7 @@ func (g *BitBucketHTTPWrapper) getFromBitBucket( if err != nil { return err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() switch resp.StatusCode { case http.StatusOK: err = json.NewDecoder(resp.Body).Decode(target) @@ -268,11 +264,7 @@ func getBitBucket(client *http.Client, token, url string, target interface{}, qu if err != nil { return err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() switch resp.StatusCode { case http.StatusOK: diff --git a/internal/wrappers/client.go b/internal/wrappers/client.go index 174b8f09f..27841f2b8 100644 --- a/internal/wrappers/client.go +++ b/internal/wrappers/client.go @@ -517,10 +517,7 @@ func getNewToken(credentialsPayload, authServerURI string) (string, error) { func getCredentialsPayload(accessKeyID, accessKeySecret string) string { logger.PrintIfVerbose("Using Client ID and secret credentials.") - // escape possible characters such as +,%, etc... - clientID := url.QueryEscape(accessKeyID) - clientSecret := url.QueryEscape(accessKeySecret) - return fmt.Sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s", clientID, clientSecret) + return fmt.Sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s", accessKeyID, accessKeySecret) } func getAPIKeyPayload(astToken string) string { @@ -530,14 +527,9 @@ func getAPIKeyPayload(astToken string) string { func getPasswordCredentialsPayload(username, password, adminClientID, adminClientSecret string) string { logger.PrintIfVerbose("Using username and password credentials.") - // escape possible characters such as +,%, etc... - encodedUsername := url.QueryEscape(username) - encodedAdminClientID := url.QueryEscape(adminClientID) - encodedPassword := url.QueryEscape(password) - encodedAdminClientSecret := url.QueryEscape(adminClientSecret) return fmt.Sprintf( "scope=openid&grant_type=password&username=%s&password=%s"+ - "&client_id=%s&client_secret=%s", encodedUsername, encodedPassword, encodedAdminClientID, encodedAdminClientSecret, + "&client_id=%s&client_secret=%s", username, password, adminClientID, adminClientSecret, ) } diff --git a/internal/wrappers/codebashing-http.go b/internal/wrappers/codebashing-http.go index 48ee8be20..f125e54b5 100644 --- a/internal/wrappers/codebashing-http.go +++ b/internal/wrappers/codebashing-http.go @@ -16,6 +16,7 @@ import ( const ( failedToParseCodeBashing = "Failed to parse list results" failedGettingCodeBashingURL = "Authentication failed, not able to retrieve codebashing base link" + limitValue = "10000" limit = "limit" noCodebashingLinkAvailable = "No codebashing link available" licenseNotFoundExitCode = 3 @@ -43,11 +44,7 @@ func (r *CodeBashingHTTPWrapper) GetCodeBashingLinks(params map[string]string, c if err != nil { return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) switch resp.StatusCode { case http.StatusBadRequest, http.StatusInternalServerError: diff --git a/internal/wrappers/feature-flags-http.go b/internal/wrappers/feature-flags-http.go index 3806e79bf..cb037c4a5 100644 --- a/internal/wrappers/feature-flags-http.go +++ b/internal/wrappers/feature-flags-http.go @@ -42,11 +42,7 @@ func (f FeatureFlagsHTTPWrapper) GetAll() (*FeatureFlagsResponseModel, error) { } decoder := json.NewDecoder(resp.Body) - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() switch resp.StatusCode { case http.StatusBadRequest, http.StatusInternalServerError: diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index 5dc19dcd8..b049fe5b5 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -7,8 +7,6 @@ import ( const tenantIDClaimKey = "tenant_id" const PackageEnforcementEnabled = "PACKAGE_ENFORCEMENT_ENABLED" const CVSSV3Enabled = "CVSS_V3_ENABLED" -const MinioEnabled = "MINIO_ENABLED" -const ContainerEngineCLIEnabled = "CONTAINER_ENGINE_CLI_ENABLED" var FeatureFlagsBaseMap = []CommandFlags{ { @@ -18,10 +16,6 @@ var FeatureFlagsBaseMap = []CommandFlags{ Name: PackageEnforcementEnabled, Default: true, }, - { - Name: MinioEnabled, - Default: true, - }, }, }, { @@ -33,9 +27,6 @@ var FeatureFlagsBaseMap = []CommandFlags{ }, }, }, - { - CommandName: "cx project create", - }, } var FeatureFlags = map[string]bool{} diff --git a/internal/wrappers/github-http.go b/internal/wrappers/github-http.go index 6ba2d31e0..11dc17e24 100644 --- a/internal/wrappers/github-http.go +++ b/internal/wrappers/github-http.go @@ -163,11 +163,7 @@ func (g *GitHubHTTPWrapper) getTemplates() error { func (g *GitHubHTTPWrapper) get(url string, target interface{}) error { resp, err := get(g.client, url, target, map[string]string{}) if err != nil { - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() } return err } @@ -209,11 +205,7 @@ func collectPage( return "", err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() *pageCollection = append(*pageCollection, holder...) next := getNextPageLink(resp) @@ -248,11 +240,7 @@ func get(client *http.Client, url string, target interface{}, queryParams map[st if err != nil { return nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() logger.PrintResponse(resp, true) switch resp.StatusCode { diff --git a/internal/wrappers/gitlab-http.go b/internal/wrappers/gitlab-http.go index 6b4b53d66..7ce87fc3a 100644 --- a/internal/wrappers/gitlab-http.go +++ b/internal/wrappers/gitlab-http.go @@ -141,11 +141,7 @@ func getFromGitLab( if err != nil { return nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() logger.PrintResponse(resp, true) @@ -202,11 +198,7 @@ func collectPageForGitLab( if err != nil { return "", err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() *pageCollection = append(*pageCollection, holder...) nextPageURL := getNextPage(resp) diff --git a/internal/wrappers/groups-http.go b/internal/wrappers/groups-http.go index ed2ffa83a..a7bdfbdc2 100644 --- a/internal/wrappers/groups-http.go +++ b/internal/wrappers/groups-http.go @@ -37,11 +37,7 @@ func (g *GroupsHTTPWrapper) Get(groupName string) ([]Group, error) { if err != nil { return nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) switch resp.StatusCode { case http.StatusBadRequest, http.StatusInternalServerError: diff --git a/internal/wrappers/mock/access-management-mock.go b/internal/wrappers/mock/access-management-mock.go deleted file mode 100644 index 5e695e1ae..000000000 --- a/internal/wrappers/mock/access-management-mock.go +++ /dev/null @@ -1,19 +0,0 @@ -package mock - -import ( - "fmt" - - "github.com/checkmarx/ast-cli/internal/wrappers" -) - -type AccessManagementMockWrapper struct{} - -func (a AccessManagementMockWrapper) CreateGroupsAssignment(projectID, projectName string, groups []*wrappers.Group) error { - fmt.Println("Called CreateGroupsAssignment in AccessManagementMockWrapper") - return nil -} - -func (a AccessManagementMockWrapper) GetGroups(projectID string) ([]*wrappers.Group, error) { - fmt.Println("Called GetGroups in AccessManagementMockWrapper") - return nil, nil -} diff --git a/internal/wrappers/mock/application-mock.go b/internal/wrappers/mock/application-mock.go deleted file mode 100644 index dce914bc7..000000000 --- a/internal/wrappers/mock/application-mock.go +++ /dev/null @@ -1,41 +0,0 @@ -package mock - -import ( - "time" - - applicationErrors "github.com/checkmarx/ast-cli/internal/errors" - "github.com/checkmarx/ast-cli/internal/wrappers" - "github.com/pkg/errors" -) - -type ApplicationsMockWrapper struct{} - -func (a ApplicationsMockWrapper) Get(params map[string]string) (*wrappers.ApplicationsResponseModel, error) { - if params["name"] == NoPermissionApp { - return nil, errors.Errorf(applicationErrors.ApplicationDoesntExistOrNoPermission) - } - if params["name"] == ApplicationDoesntExist { - return nil, errors.Errorf(applicationErrors.ApplicationDoesntExistOrNoPermission) - } - if params["name"] == FakeHTTPStatusBadRequest { - return nil, errors.Errorf(applicationErrors.FailedToGetApplication) - } - if params["name"] == FakeHTTPStatusInternalServerError { - return nil, errors.Errorf(applicationErrors.FailedToGetApplication) - } - mockApplication := wrappers.Application{ - ID: "mockID", - Name: "MOCK", - Description: "This is a mock application", - Criticality: 2, - ProjectIds: []string{"ProjectID1", "ProjectID2"}, - CreatedAt: time.Now(), - } - - response := &wrappers.ApplicationsResponseModel{ - TotalCount: 1, - Applications: []wrappers.Application{mockApplication}, - } - - return response, nil -} diff --git a/internal/wrappers/mock/constants.go b/internal/wrappers/mock/constants.go deleted file mode 100644 index 96d7d5a63..000000000 --- a/internal/wrappers/mock/constants.go +++ /dev/null @@ -1,8 +0,0 @@ -package mock - -const ( - ApplicationDoesntExist = "application-doesnt-exist" - NoPermissionApp = "NoPermissionApp" - FakeHTTPStatusBadRequest = "fake-http-status-bad-request" - FakeHTTPStatusInternalServerError = "fake-http-status-internal-server-error" -) diff --git a/internal/wrappers/mock/feature-flags-mock.go b/internal/wrappers/mock/feature-flags-mock.go index 4d19e83aa..7ca3db375 100644 --- a/internal/wrappers/mock/feature-flags-mock.go +++ b/internal/wrappers/mock/feature-flags-mock.go @@ -1,17 +1,11 @@ package mock import ( - "fmt" - "github.com/checkmarx/ast-cli/internal/wrappers" ) -var Flags wrappers.FeatureFlagsResponseModel - -type FeatureFlagsMockWrapper struct { -} +type FeatureFlagsMockWrapper struct{} func (f FeatureFlagsMockWrapper) GetAll() (*wrappers.FeatureFlagsResponseModel, error) { - fmt.Println("Called GetAll in FeatureFlagsMockWrapper") - return &Flags, nil + return &wrappers.FeatureFlagsResponseModel{}, nil } diff --git a/internal/wrappers/mock/groups-mock.go b/internal/wrappers/mock/groups-mock.go index 721b820e6..4c3c39e45 100644 --- a/internal/wrappers/mock/groups-mock.go +++ b/internal/wrappers/mock/groups-mock.go @@ -6,5 +6,5 @@ type GroupsMockWrapper struct { } func (g *GroupsMockWrapper) Get(_ string) ([]wrappers.Group, error) { - return []wrappers.Group{{ID: "1", Name: "group"}}, nil + return nil, nil } diff --git a/internal/wrappers/mock/policy-mock.go b/internal/wrappers/mock/policy-mock.go index c39a8e688..5316680ec 100644 --- a/internal/wrappers/mock/policy-mock.go +++ b/internal/wrappers/mock/policy-mock.go @@ -23,7 +23,7 @@ func (r *PolicyMockWrapper) EvaluatePolicy(params map[string]string) ( var policies []wrappers.Policy policies = append(policies, policy) - policyResponseModel.Policies = policies + policyResponseModel.Polices = policies return &policyResponseModel, nil, nil } diff --git a/internal/wrappers/mock/projects-mock.go b/internal/wrappers/mock/projects-mock.go index 78be2a59a..a0391a8fc 100644 --- a/internal/wrappers/mock/projects-mock.go +++ b/internal/wrappers/mock/projects-mock.go @@ -14,8 +14,7 @@ func (p *ProjectsMockWrapper) Create(model *wrappers.Project) ( error) { fmt.Println("Called Create in ProjectsMockWrapper") return &wrappers.ProjectResponseModel{ - Name: model.Name, - ApplicationIds: model.ApplicationIds, + Name: model.Name, }, nil, nil } func (p *ProjectsMockWrapper) Update(projectID string, model *wrappers.Project) error { diff --git a/internal/wrappers/mock/results-mock.go b/internal/wrappers/mock/results-mock.go index 0761f3cb2..d6dbdaa77 100644 --- a/internal/wrappers/mock/results-mock.go +++ b/internal/wrappers/mock/results-mock.go @@ -51,123 +51,22 @@ func (r ResultsMockWrapper) GetAllResultsByScanID(_ map[string]string) ( var dependencyPath = wrappers.DependencyPath{ID: mock, Name: mock, Version: mock, IsResolved: true, IsDevelopment: false, Locations: nil} var dependencyArray = [][]wrappers.DependencyPath{{dependencyPath}} return &wrappers.ScanResultsCollection{ - TotalCount: 7, + TotalCount: 3, Results: []*wrappers.ScanResult{ { Type: "sast", - ID: "1", Severity: "high", ScanResultData: wrappers.ScanResultData{ - LanguageName: "JavaScript", - QueryName: "mock-query-name-1", Nodes: []*wrappers.ScanResultNode{ { - FileName: "dummy-file-name-1", - Line: 10, - Column: 10, - Length: 20, - }, - { - FileName: "dummy-file-name-1", - Line: 11, - Column: 3, - Length: 10, - }, - }, - }, - }, - { - Type: "sast", - ID: "2", - Severity: "high", - ScanResultData: wrappers.ScanResultData{ - LanguageName: "Java", - QueryName: "mock-query-name-2", - Nodes: []*wrappers.ScanResultNode{ - { - FileName: "dummy-file-name-2", - Line: 10, - Column: 10, - Length: 20, - }, - { - FileName: "dummy-file-name-2", - Line: 11, - Column: 3, - Length: 10, - }, - }, - }, - }, - { - Type: "sast", - Severity: "high", - ID: "3", - ScanResultData: wrappers.ScanResultData{ - LanguageName: "Java", - QueryName: "mock-query-name-2", - Nodes: []*wrappers.ScanResultNode{ - { - FileName: "dummy-file-name-2", - Line: 10, - Column: 10, - Length: 20, - }, - { - FileName: "dummy-file-name-2", - Line: 11, - Column: 3, - Length: 10, - }, - { - FileName: "dummy-file-name-2", - Line: 12, - Column: 3, - Length: 10, - }, - }, - }, - }, - { - Type: "sast", - ID: "4", - Severity: "high", - ScanResultData: wrappers.ScanResultData{ - LanguageName: "Java", - QueryName: "mock-query-name-3", - Nodes: []*wrappers.ScanResultNode{ - { - FileName: "dummy-file-name-3", - Line: 10, - Column: 10, - Length: 20, - }, - { - FileName: "dummy-file-name-3", - Line: 11, - Column: 3, - Length: 10, - }, - }, - }, - }, - { - Type: "sast", - ID: "5", - Severity: "high", - ScanResultData: wrappers.ScanResultData{ - LanguageName: "Java", - QueryName: "mock-query-name-3", - Nodes: []*wrappers.ScanResultNode{ - { - FileName: "dummy-file-name-4", + FileName: "dummy-file-name", Line: 10, Column: 10, Length: 20, }, { - FileName: "dummy-file-name-4", - Line: 11, + FileName: "dummy-file-name", + Line: 0, Column: 3, Length: 10, }, diff --git a/internal/wrappers/mock/tenant-mock.go b/internal/wrappers/mock/tenant-mock.go index 3ef26e66a..f0fe441a3 100644 --- a/internal/wrappers/mock/tenant-mock.go +++ b/internal/wrappers/mock/tenant-mock.go @@ -2,8 +2,6 @@ package mock import "github.com/checkmarx/ast-cli/internal/wrappers" -var TenantConfiguration []*wrappers.TenantConfigurationResponse - type TenantConfigurationMockWrapper struct { } @@ -12,17 +10,10 @@ func (t TenantConfigurationMockWrapper) GetTenantConfiguration() ( *wrappers.WebError, error, ) { - if len(TenantConfiguration) == 0 { - TenantConfiguration = []*wrappers.TenantConfigurationResponse{ - { - Key: "scan.config.plugins.ideScans", - Value: "true", - }, - { - Key: "scan.config.plugins.aiGuidedRemediation", - Value: "true", - }, - } - } - return &TenantConfiguration, nil, nil + return &[]*wrappers.TenantConfigurationResponse{ + { + Key: "scan.config.plugins.ideScans", + Value: "true", + }, + }, nil, nil } diff --git a/internal/wrappers/policy.go b/internal/wrappers/policy.go index 53470615e..9ce3934df 100644 --- a/internal/wrappers/policy.go +++ b/internal/wrappers/policy.go @@ -3,7 +3,7 @@ package wrappers type PolicyResponseModel struct { Status string `json:"status"` BreakBuild bool `json:"breakBuild"` - Policies []Policy `json:"policies"` + Polices []Policy `json:"policies"` } type Policy struct { @@ -15,12 +15,6 @@ type Policy struct { Tags []string `json:"tags"` } -type PrPolicy struct { - Name string `json:"policyName"` - RulesNames []string `json:"rulesNames"` - BreakBuild bool `json:"breakBuild"` -} - type PolicyWrapper interface { EvaluatePolicy(map[string]string) (*PolicyResponseModel, *WebError, error) } diff --git a/internal/wrappers/pr-http.go b/internal/wrappers/pr-http.go index 8756d74ac..fa70f1bd4 100644 --- a/internal/wrappers/pr-http.go +++ b/internal/wrappers/pr-http.go @@ -41,11 +41,7 @@ func (r *PRHTTPWrapper) PostPRDecoration(model *PRModel) ( if err != nil { return "", nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handlePRResponseWithBody(resp, err) } @@ -63,11 +59,7 @@ func (r *PRHTTPWrapper) PostGitlabPRDecoration(model *GitlabPRModel) ( if err != nil { return "", nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handlePRResponseWithBody(resp, err) } diff --git a/internal/wrappers/pr.go b/internal/wrappers/pr.go index 1a6fb0cbf..7158fd4da 100644 --- a/internal/wrappers/pr.go +++ b/internal/wrappers/pr.go @@ -5,22 +5,20 @@ type PRResponseModel struct { } type PRModel struct { - ScanID string `json:"scanId"` - ScmToken string `json:"scmToken"` - Namespace string `json:"namespace"` - RepoName string `json:"repoName"` - PrNumber int `json:"prNumber"` - Policies []PrPolicy `json:"violatedPolicyList"` + ScanID string `json:"scanId"` + ScmToken string `json:"scmToken"` + Namespace string `json:"namespace"` + RepoName string `json:"repoName"` + PrNumber int `json:"prNumber"` } type GitlabPRModel struct { - ScanID string `json:"scanId"` - ScmToken string `json:"scmToken"` - Namespace string `json:"namespace"` - RepoName string `json:"repoName"` - IiD int `json:"iid"` - GitlabProjectID int `json:"gitlabProjectID"` - Policies []PrPolicy `json:"violatedPolicyList"` + ScanID string `json:"scanId"` + ScmToken string `json:"scmToken"` + Namespace string `json:"namespace"` + RepoName string `json:"repoName"` + IiD int `json:"iid"` + GitlabProjectID int `json:"gitlabProjectID"` } type PRWrapper interface { diff --git a/internal/wrappers/predicates-http.go b/internal/wrappers/predicates-http.go index db1130d68..0b1dc4edd 100644 --- a/internal/wrappers/predicates-http.go +++ b/internal/wrappers/predicates-http.go @@ -51,11 +51,7 @@ func (r *ResultsPredicatesHTTPWrapper) GetAllPredicatesForSimilarityID(similarit if err != nil { return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handleResponseWithBody(resp, err) } diff --git a/internal/wrappers/projects-http.go b/internal/wrappers/projects-http.go index fe4814a32..d369bf55c 100644 --- a/internal/wrappers/projects-http.go +++ b/internal/wrappers/projects-http.go @@ -33,11 +33,7 @@ func (p *ProjectsHTTPWrapper) Create(model *Project) (*ProjectResponseModel, *Er if err != nil { return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handleProjectResponseWithBody(resp, err, http.StatusCreated) } @@ -52,16 +48,10 @@ func (p *ProjectsHTTPWrapper) Update(projectID string, model *Project) error { if err != nil { return err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() switch resp.StatusCode { case http.StatusNoContent: return nil - case http.StatusForbidden: - return errors.Errorf("Failed to update project %s, status - %d, %s:", projectID, resp.StatusCode, "No permission") default: return errors.Errorf("failed to update project %s, status - %d", projectID, resp.StatusCode) } @@ -82,11 +72,7 @@ func (p *ProjectsHTTPWrapper) UpdateConfiguration(projectID string, configuratio if err != nil { return nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handleProjectResponseWithNoBody(resp, err, http.StatusNoContent) } @@ -105,11 +91,7 @@ func (p *ProjectsHTTPWrapper) Get(params map[string]string) ( } decoder := json.NewDecoder(resp.Body) - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() switch resp.StatusCode { case http.StatusBadRequest, http.StatusInternalServerError: errorModel := ErrorModel{} @@ -140,11 +122,7 @@ func (p *ProjectsHTTPWrapper) GetByID(projectID string) ( if err != nil { return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handleProjectResponseWithBody(resp, err, http.StatusOK) } @@ -160,11 +138,7 @@ func (p *ProjectsHTTPWrapper) GetBranchesByID(projectID string, params map[strin } decoder := json.NewDecoder(resp.Body) - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() switch resp.StatusCode { case http.StatusBadRequest, http.StatusInternalServerError: @@ -193,11 +167,7 @@ func (p *ProjectsHTTPWrapper) Delete(projectID string) (*ErrorModel, error) { if err != nil { return nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handleProjectResponseWithNoBody(resp, err, http.StatusNoContent) } @@ -210,11 +180,7 @@ func (p *ProjectsHTTPWrapper) Tags() ( if err != nil { return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) diff --git a/internal/wrappers/projects.go b/internal/wrappers/projects.go index a1337a9ae..72a8ee1e9 100644 --- a/internal/wrappers/projects.go +++ b/internal/wrappers/projects.go @@ -13,7 +13,6 @@ type Project struct { Tags map[string]string `json:"tags,omitempty"` Groups []string `json:"groups,omitempty"` PrivatePackage bool `json:"privatePackage,omitempty"` - ApplicationIds []string `json:"applicationIds,omitempty"` } type ProjectsCollectionResponseModel struct { @@ -23,17 +22,16 @@ type ProjectsCollectionResponseModel struct { } type ProjectResponseModel struct { - ID string `json:"id"` - Name string `json:"name"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - Groups []string `json:"groups"` - Tags map[string]string `json:"tags"` - RepoURL string `json:"repoUrl"` - MainBranch string `json:"mainBranch"` - Origin string `json:"origin,omitempty"` - ScmRepoID string `json:"scmRepoId,omitempty"` - ApplicationIds []string `json:"applicationIds"` + ID string `json:"id"` + Name string `json:"name"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + Groups []string `json:"groups"` + Tags map[string]string `json:"tags"` + RepoURL string `json:"repoUrl"` + MainBranch string `json:"mainBranch"` + Origin string `json:"origin,omitempty"` + ScmRepoID string `json:"scmRepoId,omitempty"` } type ProjectConfiguration struct { diff --git a/internal/wrappers/response.go b/internal/wrappers/response.go index f0212be8d..30b347a6c 100644 --- a/internal/wrappers/response.go +++ b/internal/wrappers/response.go @@ -94,11 +94,7 @@ func handleProjectResponseWithBody(resp *http.Response, err error, } decoder := json.NewDecoder(resp.Body) - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() switch resp.StatusCode { case http.StatusBadRequest, http.StatusInternalServerError: @@ -110,8 +106,6 @@ func handleProjectResponseWithBody(resp *http.Response, err error, return nil, &errorModel, nil case http.StatusNotFound: return nil, nil, errors.Errorf("project not found") - case http.StatusForbidden: - return nil, nil, errors.Errorf("forbidden action") case successStatusCode: model := ProjectResponseModel{} err = decoder.Decode(&model) diff --git a/internal/wrappers/results-http.go b/internal/wrappers/results-http.go index 116beddb7..8c618f888 100644 --- a/internal/wrappers/results-http.go +++ b/internal/wrappers/results-http.go @@ -191,11 +191,7 @@ func (r *ResultsHTTPWrapper) GetAllResultsTypeByScanID(params map[string]string) return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) @@ -248,11 +244,7 @@ func (r *ResultsHTTPWrapper) GetScanSummariesByScanIDS(params map[string]string) return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) diff --git a/internal/wrappers/results-json.go b/internal/wrappers/results-json.go index 2697cd857..ca38fb8c3 100644 --- a/internal/wrappers/results-json.go +++ b/internal/wrappers/results-json.go @@ -93,7 +93,6 @@ type ScanResultData struct { Group string `json:"group,omitempty"` ResultHash string `json:"resultHash,omitempty"` LanguageName string `json:"languageName,omitempty"` - Redundancy string `json:"redundancy,omitempty"` Description string `json:"description,omitempty"` Nodes []*ScanResultNode `json:"nodes,omitempty"` PackageData []*ScanResultPackageData `json:"packageData,omitempty"` diff --git a/internal/wrappers/results-summary.go b/internal/wrappers/results-summary.go index 90b4b92a0..f93e70df7 100644 --- a/internal/wrappers/results-summary.go +++ b/internal/wrappers/results-summary.go @@ -33,7 +33,6 @@ type ResultSummary struct { ScanInfoMessage string EnginesEnabled []string Policies *PolicyResponseModel - EnginesResult EnginesResultsSummary } // nolint: govet @@ -42,81 +41,11 @@ type APISecResult struct { TotalRisksCount int `json:"total_risks_count,omitempty"` Risks []int `json:"risks,omitempty"` RiskDistribution []riskDistribution `json:"risk_distribution,omitempty"` - StatusCode int } type riskDistribution struct { Origin string `json:"origin,omitempty"` Total int `json:"total,omitempty"` } -type EngineResultSummary struct { - Critical int - High int - Medium int - Low int - Info int - StatusCode int -} - -type EnginesResultsSummary map[string]*EngineResultSummary - -func (engineSummary *EnginesResultsSummary) GetCriticalIssues() int { - criticalIssues := 0 - for _, v := range *engineSummary { - criticalIssues += v.Critical - } - return criticalIssues -} - -func (engineSummary *EnginesResultsSummary) GetHighIssues() int { - highIssues := 0 - for _, v := range *engineSummary { - highIssues += v.High - } - return highIssues -} - -func (engineSummary *EnginesResultsSummary) GetLowIssues() int { - lowIssues := 0 - for _, v := range *engineSummary { - lowIssues += v.Low - } - return lowIssues -} - -func (engineSummary *EnginesResultsSummary) GetMediumIssues() int { - mediumIssues := 0 - for _, v := range *engineSummary { - mediumIssues += v.Medium - } - return mediumIssues -} - -func (engineSummary *EnginesResultsSummary) GetInfoIssues() int { - infoIssues := 0 - for _, v := range *engineSummary { - infoIssues += v.Info - } - return infoIssues -} - -func (engineSummary *EngineResultSummary) Increment(level string) { - switch level { - case "critical": - engineSummary.Critical++ - case "high": - engineSummary.High++ - case "medium": - engineSummary.Medium++ - case "low": - engineSummary.Low++ - case "info": - engineSummary.Info++ - } -} - -func (summary *ResultSummary) UpdateEngineResultSummary(engineType, severity string) { - summary.EnginesResult[engineType].Increment(severity) -} func (r *ResultSummary) HasEngine(engine string) bool { for _, v := range r.EnginesEnabled { @@ -152,11 +81,11 @@ func (r *ResultSummary) GetAPISecurityDocumentationTotal() int { if riskAPIDocumentation != nil { return riskAPIDocumentation.Total } - return 0 + return -1 } func (r *ResultSummary) HasPolicies() bool { - return r.Policies != nil && len(r.Policies.Policies) > 0 + return r.Policies != nil && len(r.Policies.Polices) > 0 } func (r *ResultSummary) GeneratePolicyHTML() string { @@ -183,20 +112,20 @@ func (r *ResultSummary) GeneratePolicyHTML() string { ` - for _, policy := range r.Policies.Policies { + for _, police := range r.Policies.Polices { html += ` ` + - policy.Name + + police.Name + ` ` + ` - ` + strings.Join(policy.RulesViolated, ",") + + ` + strings.Join(police.RulesViolated, ",") + ` ` + `` + - strconv.FormatBool(policy.BreakBuild) + + strconv.FormatBool(police.BreakBuild) + ` @@ -215,8 +144,8 @@ func (r *ResultSummary) GeneratePolicyMarkdown() string { markdown += "### Policy Management Violation\n" } markdown += "| Policy | Rule | Break Build |\n|:----------:|:------------:|:---------:|\n" - for _, policy := range r.Policies.Policies { - markdown += "|" + policy.Name + "|" + strings.Join(policy.RulesViolated, ",") + "|" + strconv.FormatBool(policy.BreakBuild) + "|\n" + for _, police := range r.Policies.Polices { + markdown += "|" + police.Name + "|" + strings.Join(police.RulesViolated, ",") + "|" + strconv.FormatBool(police.BreakBuild) + "|\n" } return markdown } diff --git a/internal/wrappers/risks-overview-http.go b/internal/wrappers/risks-overview-http.go index f9cded7b8..f2e2dfb19 100644 --- a/internal/wrappers/risks-overview-http.go +++ b/internal/wrappers/risks-overview-http.go @@ -32,11 +32,7 @@ func (r *RisksOverviewHTTPWrapper) GetAllAPISecRisksByScanID(scanID string) ( return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) switch resp.StatusCode { diff --git a/internal/wrappers/sast-metadata-http.go b/internal/wrappers/sast-metadata-http.go index 0d437f690..f36d8861a 100644 --- a/internal/wrappers/sast-metadata-http.go +++ b/internal/wrappers/sast-metadata-http.go @@ -30,11 +30,7 @@ func (s *SastIncrementalHTTPWrapper) GetSastMetadataByIDs(params map[string]stri } decoder := json.NewDecoder(resp.Body) - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() switch resp.StatusCode { case http.StatusBadRequest, http.StatusInternalServerError: diff --git a/internal/wrappers/scans-http.go b/internal/wrappers/scans-http.go index fc65bedb1..5fe00946a 100644 --- a/internal/wrappers/scans-http.go +++ b/internal/wrappers/scans-http.go @@ -39,11 +39,7 @@ func (s *ScansHTTPWrapper) Create(model *Scan) (*ScanResponseModel, *ErrorModel, if err != nil { return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handleScanResponseWithBody(resp, err, http.StatusCreated) } @@ -55,11 +51,7 @@ func (s *ScansHTTPWrapper) Get(params map[string]string) (*ScansCollectionRespon } decoder := json.NewDecoder(resp.Body) - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() switch resp.StatusCode { case http.StatusBadRequest, http.StatusInternalServerError: @@ -89,11 +81,7 @@ func (s *ScansHTTPWrapper) GetByID(scanID string) (*ScanResponseModel, *ErrorMod if err != nil { return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handleScanResponseWithBody(resp, err, http.StatusOK) } @@ -104,11 +92,7 @@ func (s *ScansHTTPWrapper) GetWorkflowByID(scanID string) ([]*ScanTaskResponseMo if err != nil { return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handleWorkflowResponseWithBody(resp, err) } @@ -145,11 +129,7 @@ func (s *ScansHTTPWrapper) Delete(scanID string) (*ErrorModel, error) { if err != nil { return nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handleScanResponseWithNoBody(resp, err, http.StatusNoContent) } @@ -166,11 +146,7 @@ func (s *ScansHTTPWrapper) Cancel(scanID string) (*ErrorModel, error) { if err != nil { return nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() return handleScanResponseWithNoBody(resp, err, http.StatusNoContent) } @@ -180,11 +156,7 @@ func (s *ScansHTTPWrapper) Tags() (map[string][]string, *ErrorModel, error) { if err != nil { return nil, nil, err } - defer func() { - if err == nil { - _ = resp.Body.Close() - } - }() + defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) switch resp.StatusCode { diff --git a/internal/wrappers/uploads-http.go b/internal/wrappers/uploads-http.go index 10b959bbb..3191ead03 100644 --- a/internal/wrappers/uploads-http.go +++ b/internal/wrappers/uploads-http.go @@ -51,8 +51,7 @@ func (u *UploadsHTTPWrapper) UploadFile(sourcesFile string) (*string, error) { if err != nil { return nil, errors.Errorf("Failed to stat file %s: %s", sourcesFile, err.Error()) } - useAccessToken := FeatureFlags[MinioEnabled] - resp, err := SendHTTPRequestByFullURLContentLength(http.MethodPut, *preSignedURL, file, stat.Size(), useAccessToken, NoTimeout, accessToken, true) + resp, err := SendHTTPRequestByFullURLContentLength(http.MethodPut, *preSignedURL, file, stat.Size(), true, NoTimeout, accessToken, true) if err != nil { return nil, errors.Errorf("Invoking HTTP request to upload file failed - %s", err.Error()) } diff --git a/internal/wrappers/wrapper-constants.go b/internal/wrappers/wrapper-constants.go deleted file mode 100644 index 242bebd6c..000000000 --- a/internal/wrappers/wrapper-constants.go +++ /dev/null @@ -1,5 +0,0 @@ -package wrappers - -const ( - limitValue = "10000" -) diff --git a/test/integration/data/positive1.tf b/test/integration/data/positive1.tf index 1a0fcc2a6..532c41524 100644 --- a/test/integration/data/positive1.tf +++ b/test/integration/data/positive1.tf @@ -17,5 +17,4 @@ resource "aws_lb" "test3" { load_balancer_type = "application" subnets = [aws_subnet.subnet1.id, aws_subnet.subnet2.id] internal = true - drop_invalid_header_fields = true } diff --git a/test/integration/data/sources.zip b/test/integration/data/sources.zip index b8335f64e..9327d23e4 100644 Binary files a/test/integration/data/sources.zip and b/test/integration/data/sources.zip differ diff --git a/test/integration/pr_test.go b/test/integration/pr_test.go index 155b797ef..c742d4a84 100644 --- a/test/integration/pr_test.go +++ b/test/integration/pr_test.go @@ -23,7 +23,8 @@ const ( ) func TestPRGithubDecorationSuccessCase(t *testing.T) { - scanID, _ := getRootScan(t, params.SastType) + scanID, _ := getRootScan(t) + args := []string{ "utils", "pr", @@ -64,7 +65,7 @@ func TestPRGithubDecorationFailure(t *testing.T) { } func TestPRGitlabDecorationSuccessCase(t *testing.T) { - scanID, _ := getRootScan(t, params.SastType) + scanID, _ := getRootScan(t) args := []string{ "utils", diff --git a/test/integration/predicate_test.go b/test/integration/predicate_test.go index 1038b3303..bd2b72709 100644 --- a/test/integration/predicate_test.go +++ b/test/integration/predicate_test.go @@ -98,6 +98,8 @@ func TestSastUpdateAndGetPredicatesForSimilarityId(t *testing.T) { assert.Assert(t, (len(predicateResult)) >= 1, "Should have at least 1 predicate as the result.") + deleteScanAndProject() + } func TestGetAndUpdatePredicateWithInvalidScannerType(t *testing.T) { diff --git a/test/integration/project_test.go b/test/integration/project_test.go index c78c75995..bae5c8a65 100644 --- a/test/integration/project_test.go +++ b/test/integration/project_test.go @@ -14,7 +14,6 @@ import ( "github.com/google/uuid" "github.com/checkmarx/ast-cli/internal/commands/util/printer" - applicationErrors "github.com/checkmarx/ast-cli/internal/errors" "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" "github.com/spf13/viper" @@ -34,7 +33,7 @@ const SSHKeyFilePath = "ssh-key-file.txt" // - Delete the created project // - Get and assert the project was deleted func TestProjectsE2E(t *testing.T) { - projectID, _ := createProject(t, Tags, Groups) + projectID, _ := createProject(t, Tags) response := listProjectByID(t, projectID) @@ -44,7 +43,7 @@ func TestProjectsE2E(t *testing.T) { project := showProject(t, projectID) assert.Equal(t, project.ID, projectID, "Project ID should match the created project") - assertTagsAndGroups(t, project, Groups) + assertTags(t, project) deleteProject(t, projectID) @@ -54,7 +53,7 @@ func TestProjectsE2E(t *testing.T) { } // Assert project contains created tags and groups -func assertTagsAndGroups(t *testing.T, project wrappers.ProjectResponseModel, groups []string) { +func assertTags(t *testing.T, project wrappers.ProjectResponseModel) { allTags := getAllTags(t, "project") @@ -66,8 +65,6 @@ func assertTagsAndGroups(t *testing.T, project wrappers.ProjectResponseModel, gr assert.Assert(t, ok, "Project should contain all created tags. Missing %s", key) assert.Equal(t, val, Tags[key], "Tag value should be equal") } - - assert.Assert(t, len(project.Groups) >= len(groups), "The project must contain at least %d groups", len(groups)) } // Create a project with empty project name should fail @@ -93,32 +90,6 @@ func TestCreateAlreadyExistingProject(t *testing.T) { assertError(t, err, "Failed creating a project: CODE: 208, Failed to create a project, project name") } -func TestProjectCreate_ApplicationDoesntExist_FailAndReturnErrorMessage(t *testing.T) { - - err, _ := executeCommand( - t, "project", "create", flag(params.FormatFlag), - printer.FormatJSON, flag(params.ProjectName), projectNameRandom, - flag(params.ApplicationName), "application-that-doesnt-exist", - ) - - assertError(t, err, applicationErrors.ApplicationDoesntExistOrNoPermission) -} - -func TestProjectCreate_ApplicationExists_CreateProjectSuccessfully(t *testing.T) { - - err, outBuffer := executeCommand( - t, "project", "create", flag(params.FormatFlag), - printer.FormatJSON, flag(params.ProjectName), projectNameRandom, - flag(params.ApplicationName), "my-application", - ) - createdProject := wrappers.ProjectResponseModel{} - unmarshall(t, outBuffer, &createdProject, "Reading project create response JSON should pass") - defer deleteProject(t, createdProject.ID) - assert.NilError(t, err) - assert.Assert(t, createdProject.ID != "", "Project ID should not be empty") - assert.Assert(t, len(createdProject.ApplicationIds) == 1, "The project must be connected to the application") -} - func TestCreateWithInvalidGroup(t *testing.T) { err, _ := executeCommand( t, "project", "create", flag(params.FormatFlag), @@ -146,10 +117,9 @@ func TestProjectBranches(t *testing.T) { assert.Assert(t, strings.Contains(string(result), "[]")) } -func createProject(t *testing.T, tags map[string]string, groups []string) (string, string) { +func createProject(t *testing.T, tags map[string]string) (string, string) { projectName := getProjectNameForTest() + "_for_project" tagsStr := formatTags(tags) - groupsStr := formatGroups(groups) fmt.Printf("Creating project : %s \n", projectName) outBuffer := executeCmdNilAssertion( @@ -159,7 +129,6 @@ func createProject(t *testing.T, tags map[string]string, groups []string) (strin flag(params.ProjectName), projectName, flag(params.BranchFlag), "master", flag(params.TagList), tagsStr, - flag(params.GroupList), groupsStr, ) createdProject := wrappers.ProjectResponseModel{} diff --git a/test/integration/result_test.go b/test/integration/result_test.go index b3711da84..b9fbbbd03 100644 --- a/test/integration/result_test.go +++ b/test/integration/result_test.go @@ -48,7 +48,6 @@ func TestResultListJson(t *testing.T) { flag(params.TargetFlag), fileName, flag(params.ScanIDFlag), scanID, flag(params.TargetPathFlag), resultsDirectory, - flag(params.SastRedundancyFlag), ) result := wrappers.ScanResultsCollection{} diff --git a/test/integration/root_test.go b/test/integration/root_test.go index feeec9567..29c1a08f6 100644 --- a/test/integration/root_test.go +++ b/test/integration/root_test.go @@ -6,7 +6,6 @@ import ( "fmt" "log" "os" - "strings" "testing" "github.com/spf13/viper" @@ -29,16 +28,9 @@ var Tags = map[string]string{ "Integration": "Tests", } -var Groups = []string{ - "it_test_group_1", - "it_test_group_2", -} - var testInstance *testing.T var rootScanId string -var rootEnginesScanId string var rootScanProjectId string -var rootEnginesScanProjectId string var rootProjectId string var rootProjectName string @@ -52,7 +44,7 @@ func TestMain(m *testing.M) { } // Create or return a scan to be shared between tests -func getRootScan(t *testing.T, scanTypes ...string) (string, string) { +func getRootScan(t *testing.T) (string, string) { testInstance = t if len(rootScanId) > 0 { @@ -60,13 +52,10 @@ func getRootScan(t *testing.T, scanTypes ...string) (string, string) { log.Println("Using the projectID: ", rootScanProjectId) return rootScanId, rootScanProjectId } - if len(scanTypes) == 0 { - rootScanId, rootScanProjectId = createScan(testInstance, Zip, Tags) - return rootScanId, rootScanProjectId - } else { - rootEnginesScanId, rootEnginesScanProjectId = createScanWithEngines(testInstance, Zip, Tags, strings.Join(scanTypes, ",")) - return rootEnginesScanId, rootEnginesScanProjectId - } + + rootScanId, rootScanProjectId = createScan(testInstance, Zip, Tags) + + return rootScanId, rootScanProjectId } // Delete scan and projects @@ -96,7 +85,7 @@ func getRootProject(t *testing.T) (string, string) { return rootProjectId, rootProjectName } - rootProjectId, rootProjectName = createProject(t, Tags, Groups) + rootProjectId, rootProjectName = createProject(t, Tags) return rootProjectId, rootProjectName } diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index c8b6055de..baa5b91c1 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -22,7 +22,6 @@ import ( realtime "github.com/checkmarx/ast-cli/internal/commands/scarealtime" "github.com/checkmarx/ast-cli/internal/commands/util" "github.com/checkmarx/ast-cli/internal/commands/util/printer" - applicationErrors "github.com/checkmarx/ast-cli/internal/errors" "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" "github.com/spf13/viper" @@ -68,68 +67,9 @@ func TestScanCreateEmptyProjectName(t *testing.T) { assertError(t, err, "Project name is required") // Creating a scan with empty project name should fail } -func TestScanCreate_ExistingApplicationAndExistingProject_CreateScanSuccessfully(t *testing.T) { - args := []string{ - "scan", "create", - flag(params.ApplicationName), "my-application", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), ".", - flag(params.ScanTypes), "sast", - flag(params.BranchFlag), "dummy_branch", - } - - err, _ := executeCommand(t, args...) - assert.NilError(t, err) -} - -func TestScanCreate_ExistingApplicationAndNotExistingProject_CreatingNewProjectAndCreateScanSuccessfully(t *testing.T) { - args := []string{ - "scan", "create", - flag(params.ApplicationName), "my-application", - flag(params.ProjectName), projectNameRandom, - flag(params.SourcesFlag), ".", - flag(params.ScanTypes), "sast", - flag(params.BranchFlag), "dummy_branch", - flag(params.ScanInfoFormatFlag), printer.FormatJSON, - } - scanID, projectID := executeCreateScan(t, args) - defer deleteProject(t, projectID) - assert.Assert(t, scanID != "", "Scan ID should not be empty") - assert.Assert(t, projectID != "", "Project ID should not be empty") -} - -func TestScanCreate_ApplicationDoesntExist_FailScanWithError(t *testing.T) { - args := []string{ - "scan", "create", - flag(params.ApplicationName), "application-that-doesnt-exist", - flag(params.ProjectName), "my-project", - flag(params.SourcesFlag), ".", - flag(params.ScanTypes), "sast", - flag(params.BranchFlag), "dummy_branch", - } - - err, _ := executeCommand(t, args...) - assertError(t, err, applicationErrors.ApplicationDoesntExistOrNoPermission) -} - // Create scans from current dir, zip and url and perform assertions in executeScanAssertions func TestScansE2E(t *testing.T) { - scanID, projectID := executeCreateScan(t, getCreateArgsWithGroups(Zip, Tags, Groups, "sast,iac-security,sca")) - defer deleteProject(t, projectID) - - executeScanAssertions(t, projectID, scanID, Tags) - glob, err := filepath.Glob(filepath.Join(os.TempDir(), "cx*.zip")) - if err != nil { - - return - } - assert.Equal(t, len(glob), 0, "Zip file not removed") -} - -func TestScansUpdateProjectGroups(t *testing.T) { - scanID, projectID := executeCreateScan(t, getCreateArgs(Zip, Tags, "sast")) - response := listScanByID(t, scanID) - scanID, projectID = executeCreateScan(t, getCreateArgsWithNameAndGroups(Zip, Tags, Groups, response[0].ProjectName, "sast")) + scanID, projectID := executeCreateScan(t, getCreateArgs(Zip, Tags, "sast,iac-security,sca")) defer deleteProject(t, projectID) executeScanAssertions(t, projectID, scanID, Tags) @@ -455,6 +395,7 @@ func executeScanAssertions(t *testing.T, projectID, scanID string, tags map[stri assert.Assert(t, ok, "Scan should contain all created tags. Missing %s", key) assert.Equal(t, val, Tags[key], "Tag value should be equal") } + deleteScan(t, scanID) response = listScanByID(t, scanID) @@ -473,9 +414,6 @@ func createScanNoWait(t *testing.T, source string, tags map[string]string) (stri func createScanSastNoWait(t *testing.T, source string, tags map[string]string) (string, string) { return executeCreateScan(t, append(getCreateArgs(source, tags, "sast,sca"), flag(params.AsyncFlag))) } -func createScanWithEngines(t *testing.T, source string, tags map[string]string, scanTypes string) (string, string) { - return executeCreateScan(t, append(getCreateArgs(source, tags, scanTypes), flag(params.AsyncFlag))) -} // Create sca scan with resolver func createScanScaWithResolver( @@ -507,17 +445,11 @@ func getProjectNameForScanTests() string { } func getCreateArgs(source string, tags map[string]string, scanTypes string) []string { - return getCreateArgsWithGroups(source, tags, nil, scanTypes) -} -func getCreateArgsWithGroups(source string, tags map[string]string, groups []string, scanTypes string) []string { projectName := getProjectNameForScanTests() - return getCreateArgsWithNameAndGroups(source, tags, groups, projectName, scanTypes) + return getCreateArgsWithName(source, tags, projectName, scanTypes) } func getCreateArgsWithName(source string, tags map[string]string, projectName, scanTypes string) []string { - return getCreateArgsWithNameAndGroups(source, tags, nil, projectName, scanTypes) -} -func getCreateArgsWithNameAndGroups(source string, tags map[string]string, groups []string, projectName, scanTypes string) []string { args := []string{ "scan", "create", flag(params.ProjectName), projectName, @@ -526,7 +458,6 @@ func getCreateArgsWithNameAndGroups(source string, tags map[string]string, group flag(params.ScanInfoFormatFlag), printer.FormatJSON, flag(params.TagList), formatTags(tags), flag(params.BranchFlag), SlowRepoBranch, - flag(params.ProjectGroupList), formatGroups(groups), } return args } @@ -1243,13 +1174,3 @@ func TestScanWithPolicyTimeout(t *testing.T) { err, _ := executeCommand(t, args...) assert.Error(t, err, "--policy-timeout should be equal or higher than 0") } - -func TestScanListWithFilters(t *testing.T) { - args := []string{ - "scan", "list", - flag(params.FilterFlag), "limit=100", - } - - err, _ := executeCommand(t, args...) - assert.NilError(t, err, "") -} diff --git a/test/integration/util.go b/test/integration/util.go index 2f9ceae08..8f0c0efca 100644 --- a/test/integration/util.go +++ b/test/integration/util.go @@ -26,15 +26,6 @@ func formatTags(tags map[string]string) string { tagsStr = strings.TrimRight(tagsStr, ",") return tagsStr } -func formatGroups(groups []string) string { - var groupsStr string - for _, group := range groups { - groupsStr += group - groupsStr += "," - } - groupsStr = strings.TrimRight(groupsStr, ",") - return groupsStr -} func getAllTags(t *testing.T, baseCmd string) map[string][]string { tagsCommand, buffer := createRedirectedTestCommand(t) diff --git a/test/integration/util_command.go b/test/integration/util_command.go index 0ecec9c58..233b32bf6 100644 --- a/test/integration/util_command.go +++ b/test/integration/util_command.go @@ -60,7 +60,6 @@ func createASTIntegrationTestCommand(t *testing.T) *cobra.Command { viper.AutomaticEnv() viper.Set("CX_TOKEN_EXPIRY_SECONDS", 2) scans := viper.GetString(params.ScansPathKey) - applications := viper.GetString(params.ApplicationsPathKey) groups := viper.GetString(params.GroupsPathKey) projects := viper.GetString(params.ProjectsPathKey) results := viper.GetString(params.ResultsPathKey) @@ -81,10 +80,8 @@ func createASTIntegrationTestCommand(t *testing.T) *cobra.Command { featureFlagsPath := viper.GetString(params.FeatureFlagsKey) policyEvaluationPath := viper.GetString(params.PolicyEvaluationPathKey) sastIncrementalPath := viper.GetString(params.SastMetadataPathKey) - accessManagementPath := viper.GetString(params.AccessManagementPathKey) scansWrapper := wrappers.NewHTTPScansWrapper(scans) - applicationsWrapper := wrappers.NewApplicationsHTTPWrapper(applications) resultsPdfReportsWrapper := wrappers.NewResultsPdfReportsHTTPWrapper(resultsPdfPath) resultsSbomReportsWrapper := wrappers.NewResultsSbomReportsHTTPWrapper(resultsSbomPath, resultsSbomProxyPath) @@ -111,10 +108,8 @@ func createASTIntegrationTestCommand(t *testing.T) *cobra.Command { featureFlagsWrapper := wrappers.NewFeatureFlagsHTTPWrapper(featureFlagsPath) policyWrapper := wrappers.NewHTTPPolicyWrapper(policyEvaluationPath) sastMetadataWrapper := wrappers.NewSastIncrementalHTTPWrapper(sastIncrementalPath) - accessManagementWrapper := wrappers.NewAccessManagementHTTPWrapper(accessManagementPath) astCli := commands.NewAstCLI( - applicationsWrapper, scansWrapper, resultsSbomReportsWrapper, resultsPdfReportsWrapper, @@ -142,7 +137,6 @@ func createASTIntegrationTestCommand(t *testing.T) *cobra.Command { featureFlagsWrapper, policyWrapper, sastMetadataWrapper, - accessManagementWrapper, ) return astCli }