From 1af6c3cf47da4876214d5a89ea543792b495b853 Mon Sep 17 00:00:00 2001 From: OriYosef <45240478+OriYosef@users.noreply.github.com> Date: Thu, 6 Oct 2022 15:46:44 +0300 Subject: [PATCH] feat: Add a rule to ensure code quality scanner in the repo * code quality scanners rule * code quality scanners rule * add if condition on rule * increase rule unique id --- .../defaultRules/17-ensure-code-quality.go | 177 ++++++++++++++++++ pkg/rulesConfig/defaultRules/defaultRules.go | 3 + .../github/17-ensure-code-quality.json | 7 + .../gitlab/17-ensure-code-quality.json | 7 + 4 files changed, 194 insertions(+) create mode 100644 pkg/rulesConfig/defaultRules/17-ensure-code-quality.go create mode 100644 pkg/rulesConfig/defaultRules/github/17-ensure-code-quality.json create mode 100644 pkg/rulesConfig/defaultRules/gitlab/17-ensure-code-quality.json diff --git a/pkg/rulesConfig/defaultRules/17-ensure-code-quality.go b/pkg/rulesConfig/defaultRules/17-ensure-code-quality.go new file mode 100644 index 0000000..db5d5a7 --- /dev/null +++ b/pkg/rulesConfig/defaultRules/17-ensure-code-quality.go @@ -0,0 +1,177 @@ +package defaultRules + +import ( + "encoding/json" + + githubConnector "github.com/allero-io/allero/pkg/connectors/github" + gitlabConnector "github.com/allero-io/allero/pkg/connectors/gitlab" +) + +func EnsureCodeQualityScanner(githubData map[string]*githubConnector.GithubOwner, gitlabData map[string]*gitlabConnector.GitlabGroup) ([]*SchemaError, error) { + schemaErrors := make([]*SchemaError, 0) + var err error + + if githubData != nil { + schemaErrors, err = githubErrorsRule17(githubData) + if err != nil { + return nil, err + } + } + + if gitlabData != nil { + schemaErrors, err = gitlabErrorsRule17(gitlabData) + if err != nil { + return nil, err + } + } + + return schemaErrors, nil +} + +func githubErrorsRule17(githubData map[string]*githubConnector.GithubOwner) ([]*SchemaError, error) { + schemaErrors := make([]*SchemaError, 0) + + usesRegexExpressions := []string{ + ".*paambaati/codeclimate-action@.*", + ".*kitabisa/sonarqube-action@.*", + ".*sonarsource/sonarcloud-github-action@.*", + } + + runRegexExpressions := []string{ + ".*docker .* run .*codeclimate/codeclimate analyze.*", + } + + for _, owner := range githubData { + for _, repo := range owner.Repositories { + foundCodeQualityScanner := false + + for _, workflow := range repo.GithubActionsWorkflows { + content := workflow.Content + contentByteArr, err := json.Marshal(content) + if err != nil { + return nil, err + } + + var workflowObj Workflow + err = json.Unmarshal(contentByteArr, &workflowObj) + if err != nil { + return nil, err + } + + for _, job := range workflowObj.Jobs { + for _, step := range job.Steps { + for _, regexExpression := range usesRegexExpressions { + if matchRegex(regexExpression, step.Uses) { + foundCodeQualityScanner = true + break + } + } + + for _, regexExpression := range runRegexExpressions { + if matchRegex(regexExpression, step.Run) { + foundCodeQualityScanner = true + break + } + } + + if foundCodeQualityScanner { + break + } + } + + if foundCodeQualityScanner { + break + } + } + + if foundCodeQualityScanner { + break + } + } + + if !foundCodeQualityScanner { + schemaErrors = append(schemaErrors, &SchemaError{ + ErrorLevel: 1, + RepositryName: repo.Name, + CiCdPlatform: "github-actions-workflows", + OwnerName: owner.Name, + ScmPlatform: "github", + }) + } + } + } + + return schemaErrors, nil +} + +func gitlabErrorsRule17(gitlabData map[string]*gitlabConnector.GitlabGroup) ([]*SchemaError, error) { + schemaErrors := make([]*SchemaError, 0) + + for _, group := range gitlabData { + for _, project := range group.Projects { + foundCodeQualityScanner, err := findCodeQualityScannerRule17(project) + if err != nil { + return nil, err + } + + if !foundCodeQualityScanner { + schemaErrors = append(schemaErrors, &SchemaError{ + ErrorLevel: 2, + RepositryName: project.Name, + CiCdPlatform: "gitlab-ci", + OwnerName: group.Name, + ScmPlatform: "gitlab", + }) + } + } + } + + return schemaErrors, nil +} + +func findCodeQualityScannerRule17(project *gitlabConnector.GitlabProject) (bool, error) { + scriptRegexExpressions := []string{ + ".*docker .* run .*codeclimate/codeclimate analyze.*", + } + + for _, pipeline := range project.GitlabCi { + + for _, stage := range pipeline.Content { + stageBytes, err := json.Marshal(stage) + if err != nil { + return false, err + } + + var stageWithSingleScript GitlabStageScript + var stageWithScripts GitlabStageScripts + + err = json.Unmarshal(stageBytes, &stageWithSingleScript) + if err != nil { + err = json.Unmarshal(stageBytes, &stageWithScripts) + if err != nil { + continue + } + } + + if stageWithSingleScript.Script != "" { + for _, regexExpression := range scriptRegexExpressions { + if matchRegex(regexExpression, stageWithSingleScript.Script) { + return true, nil + } + } + } + + if stageWithScripts.Scripts != nil { + for _, script := range stageWithScripts.Scripts { + for _, regexExpression := range scriptRegexExpressions { + if matchRegex(regexExpression, script) { + return true, nil + } + } + } + } + } + } + + return false, nil +} diff --git a/pkg/rulesConfig/defaultRules/defaultRules.go b/pkg/rulesConfig/defaultRules/defaultRules.go index 9672ba1..e66db5b 100644 --- a/pkg/rulesConfig/defaultRules/defaultRules.go +++ b/pkg/rulesConfig/defaultRules/defaultRules.go @@ -60,6 +60,9 @@ func Validate(rule *Rule, githubData map[string]*githubConnector.GithubOwner, gi if rule.UniqueId == 16 { return EnsureLinter(githubData, gitlabData) } + if rule.UniqueId == 17 { + return EnsureCodeQualityScanner(githubData, gitlabData) + } return nil, fmt.Errorf("missing implementation for rule %d", rule.UniqueId) } diff --git a/pkg/rulesConfig/defaultRules/github/17-ensure-code-quality.json b/pkg/rulesConfig/defaultRules/github/17-ensure-code-quality.json new file mode 100644 index 0000000..aa7fc79 --- /dev/null +++ b/pkg/rulesConfig/defaultRules/github/17-ensure-code-quality.json @@ -0,0 +1,7 @@ +{ + "description": "Ensure that at least one pipeline in each repository runs Code Quality scanner", + "failureMessage": "Code Quality scanner was not detected in the repository pipelines. It is highly recommended to add one to keep quality code.", + "uniqueId": 17, + "enabledByDefault": false, + "inCodeImplementation": true +} diff --git a/pkg/rulesConfig/defaultRules/gitlab/17-ensure-code-quality.json b/pkg/rulesConfig/defaultRules/gitlab/17-ensure-code-quality.json new file mode 100644 index 0000000..aa7fc79 --- /dev/null +++ b/pkg/rulesConfig/defaultRules/gitlab/17-ensure-code-quality.json @@ -0,0 +1,7 @@ +{ + "description": "Ensure that at least one pipeline in each repository runs Code Quality scanner", + "failureMessage": "Code Quality scanner was not detected in the repository pipelines. It is highly recommended to add one to keep quality code.", + "uniqueId": 17, + "enabledByDefault": false, + "inCodeImplementation": true +}