diff --git a/.github/workflows/deploy-cli-tools.yml b/.github/workflows/deploy-cli-tools.yml index cfc7a7b11..d3a2136f3 100644 --- a/.github/workflows/deploy-cli-tools.yml +++ b/.github/workflows/deploy-cli-tools.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: tool_name: - description: 'Tool to deploy on dockerhub: bandit, brakeman, gitleaks, gosec, npmaudit, safety, securitycodescan, hcl, spotbugs, horusec-kotlin, horusec-java, horusec-leaks, horusec-csharp, horusec-nodejs, horusec-kubernetes' + description: 'Tool to deploy on dockerhub: bandit, brakeman, gitleaks, gosec, npmaudit, safety, securitycodescan, hcl, spotbugs, horusec-kotlin, horusec-java, horusec-leaks, horusec-csharp, horusec-nodejs, horusec-kubernetes, eslint' required: true update_type: description: 'Update Type: alpha, rc, release, minor, major' diff --git a/README.md b/README.md index bf045fa62..506253b72 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Currently, performance analysis consists of: * [Brakeman][Brakeman] * Javascript/Typescript * [Npm Audit][NpmAudit] - * [Yarn Audit][YarnAudit] + * [Yarn Audit][YarnAudit][Eslint Eslint] * [Semgrep][Semgrep] * [HorusecNodeJS][HorusecNodeJS] * [EsLint][EsLint] diff --git a/deployments/dockerfiles/eslint/.semver.yaml b/deployments/dockerfiles/eslint/.semver.yaml new file mode 100644 index 000000000..380baee26 --- /dev/null +++ b/deployments/dockerfiles/eslint/.semver.yaml @@ -0,0 +1,4 @@ +alpha: 0 +beta: 0 +rc: 0 +release: v0.0.1 diff --git a/deployments/dockerfiles/eslint/Dockerfile b/deployments/dockerfiles/eslint/Dockerfile new file mode 100644 index 000000000..53811f2ad --- /dev/null +++ b/deployments/dockerfiles/eslint/Dockerfile @@ -0,0 +1,18 @@ +# Copyright 2020 ZUP IT SERVICOS EM TECNOLOGIA E INOVACAO SA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM node + +RUN npm install -g eslint +RUN npm install -g eslint-plugin-security \ No newline at end of file diff --git a/deployments/scripts/update-image-tool.sh b/deployments/scripts/update-image-tool.sh index bdfbc2de6..091e8ea19 100755 --- a/deployments/scripts/update-image-tool.sh +++ b/deployments/scripts/update-image-tool.sh @@ -97,6 +97,10 @@ getDirectoryAndImageNameByToolName () { IMAGE_NAME="horuszup/horusec-leaks" DIRECTORY_CONFIG="$CURRENT_FOLDER/horusec-cli/internal/services/formatters/leaks/horusecleaks/config.go" DIRECTORY_SEMVER="$CURRENT_FOLDER/horusec-leaks";; + "eslint") + IMAGE_NAME="horuszup/eslint" + DIRECTORY_CONFIG="$CURRENT_FOLDER/horusec-cli/internal/services/formatters/javascript/eslint/config.go" + DIRECTORY_SEMVER="$CURRENT_FOLDER/deployments/dockerfiles/eslint";; "horusec-nodejs") IMAGE_NAME="horuszup/horusec-nodejs" DIRECTORY_CONFIG="$CURRENT_FOLDER/horusec-cli/internal/services/formatters/javascript/horusecnodejs/config.go" diff --git a/development-kit/pkg/entities/analyser/eslint/output.go b/development-kit/pkg/entities/analyser/eslint/output.go new file mode 100644 index 000000000..3aa124999 --- /dev/null +++ b/development-kit/pkg/entities/analyser/eslint/output.go @@ -0,0 +1,37 @@ +// Copyright 2020 ZUP IT SERVICOS EM TECNOLOGIA E INOVACAO SA +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package eslint + +type Message struct { + RuleID string `json:"ruleId"` + Severity int `json:"severity"` + Message string `json:"message"` + Line int `json:"line"` + Column int `json:"column"` + NodeType string `json:"nodeType"` + MessageID string `json:"messageId"` + EndLine int `json:"endLine"` + EndColumn int `json:"endColumn"` +} + +type Output struct { + FilePath string `json:"filePath"` + Messages *[]Message `json:"messages"` + ErrorCount int `json:"errorCount"` + WarningCount int `json:"warningCount"` + FixableErrorCount int `json:"fixableErrorCount"` + FixableWarningCount int `json:"fixableWarningCount"` + Source string `json:"source"` +} diff --git a/development-kit/pkg/enums/tools/tools.go b/development-kit/pkg/enums/tools/tools.go index ce157a64c..3405b87ca 100644 --- a/development-kit/pkg/enums/tools/tools.go +++ b/development-kit/pkg/enums/tools/tools.go @@ -33,6 +33,7 @@ const ( Semgrep Tool = "Semgrep" HorusecCsharp Tool = "HorusecCsharp" HorusecKubernetes Tool = "HorusecKubernetes" + Eslint Tool = "Eslint" HorusecNodejs Tool = "HorusecNodeJS" ) diff --git a/development-kit/pkg/usecases/analysis/analysis.go b/development-kit/pkg/usecases/analysis/analysis.go index 9a219564c..076d981fe 100644 --- a/development-kit/pkg/usecases/analysis/analysis.go +++ b/development-kit/pkg/usecases/analysis/analysis.go @@ -177,6 +177,7 @@ func (au *UseCases) sliceTools() []interface{} { tools.HorusecLeaks, tools.Semgrep, tools.HorusecCsharp, + tools.Eslint, tools.HorusecKubernetes, } } diff --git a/horusec-cli/cmd/horusec/start/start.go b/horusec-cli/cmd/horusec/start/start.go index 96a6d85de..f895145dd 100644 --- a/horusec-cli/cmd/horusec/start/start.go +++ b/horusec-cli/cmd/horusec/start/start.go @@ -210,5 +210,5 @@ func (s *Start) loadFlags(cmd *cobra.Command) { "Used to ignore a vulnerability by hash and setting it to be of the risk accept type. Example -R=\"hash3, hash4\"") cmd.PersistentFlags(). StringVarP(&s.configs.ToolsToIgnore, "tools-ignore", "T", s.configs.GetToolsToIgnore(), - "Tools to ignore in the analysis. Available are: GoSec,SecurityCodeScan,Brakeman,Safety,Bandit,NpmAudit,YarnAudit,SpotBugs,HorusecKotlin,HorusecJava,HorusecLeaks,GitLeaks,TfSec,Semgrep,HorusecCsharp,HorusecNodeJS,HorusecKubernetes. Example: -T=\"GoSec, Brakeman\"") + "Tools to ignore in the analysis. Available are: GoSec,SecurityCodeScan,Brakeman,Safety,Bandit,NpmAudit,YarnAudit,SpotBugs,HorusecKotlin,HorusecJava,HorusecLeaks,GitLeaks,TfSec,Semgrep,HorusecCsharp,HorusecNodeJS,HorusecKubernetes,Eslint. Example: -T=\"GoSec, Brakeman\"") } diff --git a/horusec-cli/internal/controllers/analyser/analyser.go b/horusec-cli/internal/controllers/analyser/analyser.go index 9816486bc..ae1ec7150 100644 --- a/horusec-cli/internal/controllers/analyser/analyser.go +++ b/horusec-cli/internal/controllers/analyser/analyser.go @@ -49,6 +49,7 @@ import ( "github.com/ZupIT/horusec/horusec-cli/internal/services/formatters/generic/semgrep" "github.com/ZupIT/horusec/horusec-cli/internal/services/formatters/golang/gosec" "github.com/ZupIT/horusec/horusec-cli/internal/services/formatters/hcl" + "github.com/ZupIT/horusec/horusec-cli/internal/services/formatters/javascript/eslint" "github.com/ZupIT/horusec/horusec-cli/internal/services/formatters/javascript/npmaudit" "github.com/ZupIT/horusec/horusec-cli/internal/services/formatters/javascript/yarnaudit" "github.com/ZupIT/horusec/horusec-cli/internal/services/formatters/leaks/gitleaks" @@ -229,9 +230,10 @@ func (a *Analyser) detectVulnerabilityKotlin(projectSubPath string) { } func (a *Analyser) detectVulnerabilityJavascript(projectSubPath string) { - a.monitor.AddProcess(3) + a.monitor.AddProcess(4) go yarnaudit.NewFormatter(a.formatterService).StartAnalysis(projectSubPath) go npmaudit.NewFormatter(a.formatterService).StartAnalysis(projectSubPath) + go eslint.NewFormatter(a.formatterService).StartAnalysis(projectSubPath) go horusecnodejs.NewFormatter(a.formatterService).StartAnalysis(projectSubPath) } diff --git a/horusec-cli/internal/services/formatters/javascript/eslint/config.go b/horusec-cli/internal/services/formatters/javascript/eslint/config.go new file mode 100644 index 000000000..0cb67f318 --- /dev/null +++ b/horusec-cli/internal/services/formatters/javascript/eslint/config.go @@ -0,0 +1,44 @@ +// Copyright 2020 ZUP IT SERVICOS EM TECNOLOGIA E INOVACAO SA +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package eslint + +const ( + ImageName = "horuszup/eslint" + ImageTag = "v0.0.1" + ImageCmd = ` + {{WORK_DIR}} + eslint \ + --no-eslintrc \ + -f json \ + --resolve-plugins-relative-to /usr/local/lib/node_modules \ + --plugin security \ + --rule 'security/detect-buffer-noassert: warn' \ + --rule 'security/detect-child-process: warn' \ + --rule 'security/detect-disable-mustache-escape: warn' \ + --rule 'security/detect-eval-with-expression: warn' \ + --rule 'security/detect-new-buffer: warn' \ + --rule 'security/detect-no-csrf-before-method-override: warn' \ + --rule 'security/detect-non-literal-fs-filename: warn' \ + --rule 'security/detect-non-literal-regexp: warn' \ + --rule 'security/detect-non-literal-require: warn' \ + --rule 'security/detect-possible-timing-attacks: warn' \ + --rule 'security/detect-pseudoRandomBytes: warn' \ + --rule 'security/detect-unsafe-regex: warn' \ + --parser-options=ecmaVersion:7 \ + --parser-options=sourceType:module \ + "*/**/*.{js,ts,tsx}" > /tmp/results.json + cat /tmp/results.json + ` +) diff --git a/horusec-cli/internal/services/formatters/javascript/eslint/formatter.go b/horusec-cli/internal/services/formatters/javascript/eslint/formatter.go new file mode 100644 index 000000000..cad351d98 --- /dev/null +++ b/horusec-cli/internal/services/formatters/javascript/eslint/formatter.go @@ -0,0 +1,162 @@ +// Copyright 2020 ZUP IT SERVICOS EM TECNOLOGIA E INOVACAO SA +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package eslint + +import ( + "fmt" + "strings" + + "github.com/ZupIT/horusec/development-kit/pkg/entities/analyser/eslint" + "github.com/ZupIT/horusec/development-kit/pkg/entities/horusec" + "github.com/ZupIT/horusec/development-kit/pkg/enums/languages" + "github.com/ZupIT/horusec/development-kit/pkg/enums/severity" + "github.com/ZupIT/horusec/development-kit/pkg/enums/tools" + jsonUtils "github.com/ZupIT/horusec/development-kit/pkg/utils/json" + "github.com/ZupIT/horusec/development-kit/pkg/utils/logger" + vulnhash "github.com/ZupIT/horusec/development-kit/pkg/utils/vuln_hash" + dockerEntities "github.com/ZupIT/horusec/horusec-cli/internal/entities/docker" + "github.com/ZupIT/horusec/horusec-cli/internal/helpers/messages" + "github.com/ZupIT/horusec/horusec-cli/internal/services/formatters" +) + +type Formatter struct { + formatters.IService +} + +func NewFormatter(service formatters.IService) formatters.IFormatter { + return &Formatter{ + service, + } +} + +func (f *Formatter) StartAnalysis(projectSubPath string) { + if f.ToolIsToIgnore(tools.Eslint) { + logger.LogDebugWithLevel(messages.MsgDebugToolIgnored+tools.Eslint.ToString(), logger.DebugLevel) + return + } + + err := f.executeDockerContainer(projectSubPath) + f.LogAnalysisError(err, tools.Eslint, projectSubPath) + + f.SetLanguageIsFinished() +} + +func (f *Formatter) executeDockerContainer(projectSubPath string) error { + f.LogDebugWithReplace(messages.MsgDebugToolStartAnalysis, tools.Eslint) + + output, err := f.ExecuteContainer(f.getDockerConfig(projectSubPath)) + if err != nil { + f.SetAnalysisError(err) + return err + } + + f.processOutput(output) + f.LogDebugWithReplace(messages.MsgDebugToolFinishAnalysis, tools.Eslint) + + return nil +} + +func (f *Formatter) getDockerConfig(projectSubPath string) *dockerEntities.AnalysisData { + return &dockerEntities.AnalysisData{ + Image: ImageName, + Tag: ImageTag, + CMD: f.AddWorkDirInCmd(ImageCmd, projectSubPath, tools.Eslint), + Language: languages.Javascript, + } +} + +func (f *Formatter) processOutput(output string) { + if output == "" { + logger.LogDebugWithLevel( + messages.MsgDebugOutputEmpty, logger.DebugLevel, map[string]interface{}{"tool": tools.Eslint.ToString()}) + return + } + + eslintOutput, err := f.parseOutput(output) + if err != nil { + return + } + + f.concatOutputIntoAnalysisVulns(eslintOutput) +} + +func (f *Formatter) parseOutput(output string) (eslintOutput *[]eslint.Output, err error) { + err = jsonUtils.ConvertStringToOutput(output, &eslintOutput) + logger.LogErrorWithLevel(f.GetAnalysisIDErrorMessage(tools.Eslint, output), err, logger.ErrorLevel) + return eslintOutput, err +} + +func (f *Formatter) concatOutputIntoAnalysisVulns(output *[]eslint.Output) { + for _, file := range *output { + for _, message := range *file.Messages { + vuln := f.parseOutputToVuln(file.FilePath, file.Source, message) + + vulnhash.Bind(vuln) + f.setCommitAuthor(vuln) + + f.setIntoAnalysisVulns(vuln) + } + } +} + +// nolint +func (f *Formatter) parseOutputToVuln(filePath, source string, message eslint.Message) *horusec.Vulnerability { + return &horusec.Vulnerability{ + File: filePath, + Line: fmt.Sprintf(`%d`, message.Line), + Column: fmt.Sprintf(`%d`, message.Column), + Language: languages.Javascript, + SecurityTool: tools.Eslint, + Details: message.Message, + Code: f.getCode(source, message.Line, message.EndLine, message.Column), + Severity: severity.Low, + } +} + +func (f *Formatter) setCommitAuthor(vuln *horusec.Vulnerability) *horusec.Vulnerability { + commitAuthor := f.GetCommitAuthor(vuln.Line, vuln.File) + vuln.CommitAuthor = commitAuthor.Author + vuln.CommitEmail = commitAuthor.Email + vuln.CommitHash = commitAuthor.CommitHash + vuln.CommitMessage = commitAuthor.Message + vuln.CommitDate = commitAuthor.Date + + return vuln +} + +func (f *Formatter) setIntoAnalysisVulns(vuln *horusec.Vulnerability) { + f.GetAnalysis().AnalysisVulnerabilities = append(f.GetAnalysis().AnalysisVulnerabilities, + horusec.AnalysisVulnerabilities{ + Vulnerability: *vuln, + }) +} + +func (f *Formatter) getCode(source string, line, endLine, column int) string { + var result string + startLine := line - 1 + lines := strings.Split(source, "\n") + + for i, line := range lines { + if i >= startLine && i <= endLine { + result += line + } + + if i > endLine { + break + } + } + + return f.GetCodeWithMaxCharacters(result, column) +} diff --git a/horusec-cli/internal/services/formatters/javascript/eslint/formatter_test.go b/horusec-cli/internal/services/formatters/javascript/eslint/formatter_test.go new file mode 100644 index 000000000..ef7b1b27a --- /dev/null +++ b/horusec-cli/internal/services/formatters/javascript/eslint/formatter_test.go @@ -0,0 +1,89 @@ +package eslint + +import ( + "errors" + "testing" + + "github.com/ZupIT/horusec/development-kit/pkg/entities/horusec" + cliConfig "github.com/ZupIT/horusec/horusec-cli/config" + "github.com/ZupIT/horusec/horusec-cli/internal/entities/workdir" + "github.com/ZupIT/horusec/horusec-cli/internal/services/docker" + "github.com/ZupIT/horusec/horusec-cli/internal/services/formatters" + "github.com/stretchr/testify/assert" +) + +func TestStartAnalysis(t *testing.T) { + t.Run("should pupulate analysis vulnerabilities", func(t *testing.T) { + analysis := &horusec.Analysis{} + dockerMock := &docker.Mock{} + output := "[{\"filePath\":\"/src/node/auth.js\",\"messages\":[],\"errorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0,\"usedDeprecatedRules\":[]},{\"filePath\":\"/src/node/injection.js\",\"messages\":[],\"errorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0,\"usedDeprecatedRules\":[]},{\"filePath\":\"/src/node/product.js\",\"messages\":[{\"ruleId\":\"security/detect-unsafe-regex\",\"severity\":1,\"message\":\"Unsafe Regular Expression\",\"line\":53,\"column\":27,\"nodeType\":\"Literal\",\"endLine\":53,\"endColumn\":92}],\"errorCount\":0,\"warningCount\":1,\"fixableErrorCount\":0,\"fixableWarningCount\":0,\"source\":\"var config = require(\\\"../config\\\"),\\n pgp = require('pg-promise')(),\\n db = pgp(config.db.connectionString);\\n\\nfunction list_products() {\\n \\n var q = \\\"SELECT * FROM products;\\\";\\n\\n return db.many(q);\\n}\\n\\nfunction getProduct(product_id) {\\n\\n var q = \\\"SELECT * FROM products WHERE id = '\\\" + product_id + \\\"';\\\";\\n\\n return db.one(q);\\n}\\n\\nfunction search(query) {\\n\\n var q = \\\"SELECT * FROM products WHERE name ILIKE '%\\\" + query + \\\"%' OR description ILIKE '%\\\" + query + \\\"%';\\\";\\n\\n return db.many(q);\\n\\n}\\n\\nfunction purchase(cart) {\\n\\n var q = \\\"INSERT INTO purchases(mail, product_name, user_name, product_id, address, phone, ship_date, price) VALUES('\\\" +\\n cart.mail + \\\"', '\\\" +\\n cart.product_name + \\\"', '\\\" +\\n cart.username + \\\"', '\\\" +\\n cart.product_id + \\\"', '\\\" +\\n cart.address + \\\"', '\\\" +\\n cart.ship_date + \\\"', '\\\" +\\n cart.phone + \\\"', '\\\" +\\n cart.price +\\n \\\"');\\\";\\n\\n return db.one(q);\\n\\n}\\n\\nfunction get_purcharsed(username) {\\n\\n var q = \\\"SELECT * FROM purchases WHERE user_name = '\\\" + username + \\\"';\\\";\\n\\n return db.many(q);\\n\\n}\\n\\nfunction validateEmail ( string ) {\\n var emailExpression = /^([a-zA-Z0-9_\\\\.\\\\-])+\\\\@(([a-zA-Z0-9\\\\-])+\\\\.)+([a-zA-Z0-9]{2,4})+$/;\\n\\n return emailExpression.test( string );\\n}\\n\\nvar actions = {\\n \\\"list\\\": list_products,\\n \\\"getProduct\\\": getProduct,\\n \\\"search\\\": search,\\n \\\"purchase\\\": purchase,\\n \\\"getPurchased\\\": get_purcharsed\\n}\\n\\nmodule.exports = actions;\",\"usedDeprecatedRules\":[]}]" + dockerMock.On("CreateLanguageAnalysisContainer").Return(output, nil) + + config := &cliConfig.Config{ + WorkDir: &workdir.WorkDir{}, + } + + service := formatters.NewFormatterService(analysis, dockerMock, config, &horusec.Monitor{}) + formatter := NewFormatter(service) + + formatter.StartAnalysis("") + + assert.Equal(t, 1, len(analysis.AnalysisVulnerabilities)) + }) + + t.Run("should avoid process when tool is ignored", func(t *testing.T) { + analysis := &horusec.Analysis{} + dockerMock := &docker.Mock{} + output := "[{\"filePath\":\"/src/node/auth.js\",\"messages\":[],\"errorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0,\"usedDeprecatedRules\":[]},{\"filePath\":\"/src/node/injection.js\",\"messages\":[],\"errorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0,\"usedDeprecatedRules\":[]},{\"filePath\":\"/src/node/product.js\",\"messages\":[{\"ruleId\":\"security/detect-unsafe-regex\",\"severity\":1,\"message\":\"Unsafe Regular Expression\",\"line\":53,\"column\":27,\"nodeType\":\"Literal\",\"endLine\":53,\"endColumn\":92}],\"errorCount\":0,\"warningCount\":1,\"fixableErrorCount\":0,\"fixableWarningCount\":0,\"source\":\"var config = require(\\\"../config\\\"),\\n pgp = require('pg-promise')(),\\n db = pgp(config.db.connectionString);\\n\\nfunction list_products() {\\n \\n var q = \\\"SELECT * FROM products;\\\";\\n\\n return db.many(q);\\n}\\n\\nfunction getProduct(product_id) {\\n\\n var q = \\\"SELECT * FROM products WHERE id = '\\\" + product_id + \\\"';\\\";\\n\\n return db.one(q);\\n}\\n\\nfunction search(query) {\\n\\n var q = \\\"SELECT * FROM products WHERE name ILIKE '%\\\" + query + \\\"%' OR description ILIKE '%\\\" + query + \\\"%';\\\";\\n\\n return db.many(q);\\n\\n}\\n\\nfunction purchase(cart) {\\n\\n var q = \\\"INSERT INTO purchases(mail, product_name, user_name, product_id, address, phone, ship_date, price) VALUES('\\\" +\\n cart.mail + \\\"', '\\\" +\\n cart.product_name + \\\"', '\\\" +\\n cart.username + \\\"', '\\\" +\\n cart.product_id + \\\"', '\\\" +\\n cart.address + \\\"', '\\\" +\\n cart.ship_date + \\\"', '\\\" +\\n cart.phone + \\\"', '\\\" +\\n cart.price +\\n \\\"');\\\";\\n\\n return db.one(q);\\n\\n}\\n\\nfunction get_purcharsed(username) {\\n\\n var q = \\\"SELECT * FROM purchases WHERE user_name = '\\\" + username + \\\"';\\\";\\n\\n return db.many(q);\\n\\n}\\n\\nfunction validateEmail ( string ) {\\n var emailExpression = /^([a-zA-Z0-9_\\\\.\\\\-])+\\\\@(([a-zA-Z0-9\\\\-])+\\\\.)+([a-zA-Z0-9]{2,4})+$/;\\n\\n return emailExpression.test( string );\\n}\\n\\nvar actions = {\\n \\\"list\\\": list_products,\\n \\\"getProduct\\\": getProduct,\\n \\\"search\\\": search,\\n \\\"purchase\\\": purchase,\\n \\\"getPurchased\\\": get_purcharsed\\n}\\n\\nmodule.exports = actions;\",\"usedDeprecatedRules\":[]}]" + dockerMock.On("CreateLanguageAnalysisContainer").Return(output, nil) + + config := &cliConfig.Config{ + WorkDir: &workdir.WorkDir{}, + ToolsToIgnore: "Eslint", + } + + service := formatters.NewFormatterService(analysis, dockerMock, config, &horusec.Monitor{}) + formatter := NewFormatter(service) + + formatter.StartAnalysis("") + + assert.Equal(t, 0, len(analysis.AnalysisVulnerabilities)) + }) + + t.Run("should avoid process when tool return an empty string", func(t *testing.T) { + analysis := &horusec.Analysis{} + dockerMock := &docker.Mock{} + output := "" + dockerMock.On("CreateLanguageAnalysisContainer").Return(output, nil) + + config := &cliConfig.Config{ + WorkDir: &workdir.WorkDir{}, + ToolsToIgnore: "Eslint", + } + + service := formatters.NewFormatterService(analysis, dockerMock, config, &horusec.Monitor{}) + formatter := NewFormatter(service) + + formatter.StartAnalysis("") + + assert.Equal(t, 0, len(analysis.AnalysisVulnerabilities)) + }) + + t.Run("should avoid process when docker fails", func(t *testing.T) { + analysis := &horusec.Analysis{} + dockerMock := &docker.Mock{} + dockerMock.On("CreateLanguageAnalysisContainer").Return(nil, errors.New("test")) + + config := &cliConfig.Config{ + WorkDir: &workdir.WorkDir{}, + ToolsToIgnore: "Eslint", + } + + service := formatters.NewFormatterService(analysis, dockerMock, config, &horusec.Monitor{}) + formatter := NewFormatter(service) + + formatter.StartAnalysis("") + + assert.Equal(t, 0, len(analysis.AnalysisVulnerabilities)) + }) +}