From 060e56b6bdbe3a29c02699160c4ace63dd6cf94a Mon Sep 17 00:00:00 2001 From: Dima Brusilovsky Date: Tue, 18 Oct 2022 19:42:38 +0300 Subject: [PATCH] fix: validate local duplicates and support custom rules (#122) * fix: validate local duplicates * feat: support running custom rules * fix: always run custom rules --- cmd/validate/main.go | 47 +++++++++++++++++-- .../defaultRules/14-ensure-code-coverage.go | 4 +- .../defaultRules/15-ensure-secrets-scanner.go | 4 +- .../defaultRules/16-ensure-linter.go | 4 +- .../defaultRules/17-ensure-code-quality.go | 4 +- pkg/rulesConfig/rulesConfig.go | 16 +++++++ 6 files changed, 68 insertions(+), 11 deletions(-) diff --git a/cmd/validate/main.go b/cmd/validate/main.go index d70cd5a..af14566 100644 --- a/cmd/validate/main.go +++ b/cmd/validate/main.go @@ -10,6 +10,7 @@ import ( "github.com/allero-io/allero/pkg/posthog" "github.com/allero-io/allero/pkg/resultsPrinter" "github.com/allero-io/allero/pkg/rulesConfig" + "github.com/allero-io/allero/pkg/rulesConfig/defaultRules" "github.com/spf13/cobra" ) @@ -117,8 +118,10 @@ func validateOutputFlag(output string) bool { } func execute(deps *ValidateCommandDependencies, option *validateCommandOptions) error { + isLocal := option.localPathToValidate != "" var err error - if option.localPathToValidate != "" { + + if isLocal { err = deps.LocalRepositoriesClient.Get(option.localPathToValidate) if err == nil { fmt.Printf("Running validation over %s\n", option.localPathToValidate) @@ -163,7 +166,9 @@ func execute(deps *ValidateCommandDependencies, option *validateCommandOptions) return err } - if hasToken && !selectedRuleIds[rule.UniqueId] { + isCustomRule := rule.UniqueId >= 1000 + + if hasToken && !selectedRuleIds[rule.UniqueId] && !isCustomRule { continue } else if !hasToken && !rule.EnabledByDefault { continue @@ -208,7 +213,11 @@ func execute(deps *ValidateCommandDependencies, option *validateCommandOptions) summary.URL = deps.ConfigurationManager.TokenGenerationUrl } - err = resultsPrinter.PrintResults(ruleResultsById, summary, option.output, option.localPathToValidate != "") + if isLocal { + ruleResultsById = reduceLocalRuleResults(ruleResultsById) + } + + err = resultsPrinter.PrintResults(ruleResultsById, summary, option.output, isLocal) if err != nil { return err } @@ -217,3 +226,35 @@ func execute(deps *ValidateCommandDependencies, option *validateCommandOptions) } return nil } + +func reduceLocalRuleResults(ruleResultsById map[int]*rulesConfig.RuleResult) map[int]*rulesConfig.RuleResult { + reducedRuleResultsById := map[int]*rulesConfig.RuleResult{} + for uniqueId, ruleResult := range ruleResultsById { + if ruleResult.Valid { + reducedRuleResultsById[uniqueId] = ruleResult + continue + } + + schemaErrorsByScmPlatform := map[string][]*defaultRules.SchemaError{} + for _, schemaError := range ruleResult.SchemaErrors { + schemaErrorsByScmPlatform[schemaError.ScmPlatform] = append(schemaErrorsByScmPlatform[schemaError.ScmPlatform], schemaError) + } + + maxErrors := 0 + schemaErrors := []*defaultRules.SchemaError{} + for _, scmSchemaErrors := range schemaErrorsByScmPlatform { + if len(scmSchemaErrors) > maxErrors { + maxErrors = len(scmSchemaErrors) + schemaErrors = scmSchemaErrors + } + } + + reducedRuleResultsById[uniqueId] = &rulesConfig.RuleResult{ + RuleName: ruleResult.RuleName, + Valid: false, + SchemaErrors: schemaErrors, + FailureMessage: ruleResult.FailureMessage, + } + } + return reducedRuleResultsById +} diff --git a/pkg/rulesConfig/defaultRules/14-ensure-code-coverage.go b/pkg/rulesConfig/defaultRules/14-ensure-code-coverage.go index 84e5408..da1067d 100644 --- a/pkg/rulesConfig/defaultRules/14-ensure-code-coverage.go +++ b/pkg/rulesConfig/defaultRules/14-ensure-code-coverage.go @@ -91,7 +91,7 @@ func githubErrorsRule14(githubData map[string]*githubConnector.GithubOwner) ([]* schemaErrors = append(schemaErrors, &SchemaError{ ErrorLevel: 1, RepositryName: repo.Name, - CiCdPlatform: "github-actions-workflows", + CiCdPlatform: "", OwnerName: owner.Name, ScmPlatform: "github", }) @@ -116,7 +116,7 @@ func gitlabErrorsRule14(gitlabData map[string]*gitlabConnector.GitlabGroup) ([]* schemaErrors = append(schemaErrors, &SchemaError{ ErrorLevel: 2, RepositryName: project.Name, - CiCdPlatform: "gitlab-ci", + CiCdPlatform: "", OwnerName: group.Name, ScmPlatform: "gitlab", }) diff --git a/pkg/rulesConfig/defaultRules/15-ensure-secrets-scanner.go b/pkg/rulesConfig/defaultRules/15-ensure-secrets-scanner.go index b8a5d44..88146b2 100644 --- a/pkg/rulesConfig/defaultRules/15-ensure-secrets-scanner.go +++ b/pkg/rulesConfig/defaultRules/15-ensure-secrets-scanner.go @@ -116,7 +116,7 @@ func githubErrorsRule15(githubData map[string]*githubConnector.GithubOwner) ([]* schemaErrors = append(schemaErrors, &SchemaError{ ErrorLevel: 1, RepositryName: repo.Name, - CiCdPlatform: "github-actions-workflows", + CiCdPlatform: "", OwnerName: owner.Name, ScmPlatform: "github", }) @@ -141,7 +141,7 @@ func gitlabErrorsRule15(gitlabData map[string]*gitlabConnector.GitlabGroup) ([]* schemaErrors = append(schemaErrors, &SchemaError{ ErrorLevel: 2, RepositryName: project.Name, - CiCdPlatform: "gitlab-ci", + CiCdPlatform: "", OwnerName: group.Name, ScmPlatform: "gitlab", }) diff --git a/pkg/rulesConfig/defaultRules/16-ensure-linter.go b/pkg/rulesConfig/defaultRules/16-ensure-linter.go index 43ff0e6..6e06d6c 100644 --- a/pkg/rulesConfig/defaultRules/16-ensure-linter.go +++ b/pkg/rulesConfig/defaultRules/16-ensure-linter.go @@ -97,7 +97,7 @@ func githubErrorsRule16(githubData map[string]*githubConnector.GithubOwner) ([]* schemaErrors = append(schemaErrors, &SchemaError{ ErrorLevel: 1, RepositryName: repo.Name, - CiCdPlatform: "github-actions-workflows", + CiCdPlatform: "", OwnerName: owner.Name, ScmPlatform: "github", }) @@ -122,7 +122,7 @@ func gitlabErrorsRule16(gitlabData map[string]*gitlabConnector.GitlabGroup) ([]* schemaErrors = append(schemaErrors, &SchemaError{ ErrorLevel: 2, RepositryName: project.Name, - CiCdPlatform: "gitlab-ci", + CiCdPlatform: "", OwnerName: group.Name, ScmPlatform: "gitlab", }) diff --git a/pkg/rulesConfig/defaultRules/17-ensure-code-quality.go b/pkg/rulesConfig/defaultRules/17-ensure-code-quality.go index bf779a4..d75a958 100644 --- a/pkg/rulesConfig/defaultRules/17-ensure-code-quality.go +++ b/pkg/rulesConfig/defaultRules/17-ensure-code-quality.go @@ -93,7 +93,7 @@ func githubErrorsRule17(githubData map[string]*githubConnector.GithubOwner) ([]* schemaErrors = append(schemaErrors, &SchemaError{ ErrorLevel: 1, RepositryName: repo.Name, - CiCdPlatform: "github-actions-workflows", + CiCdPlatform: "", OwnerName: owner.Name, ScmPlatform: "github", }) @@ -118,7 +118,7 @@ func gitlabErrorsRule17(gitlabData map[string]*gitlabConnector.GitlabGroup) ([]* schemaErrors = append(schemaErrors, &SchemaError{ ErrorLevel: 2, RepositryName: project.Name, - CiCdPlatform: "gitlab-ci", + CiCdPlatform: "", OwnerName: group.Name, ScmPlatform: "gitlab", }) diff --git a/pkg/rulesConfig/rulesConfig.go b/pkg/rulesConfig/rulesConfig.go index 36bd266..7512d43 100644 --- a/pkg/rulesConfig/rulesConfig.go +++ b/pkg/rulesConfig/rulesConfig.go @@ -209,16 +209,26 @@ func (rc *RulesConfig) parseSchemaFieldGitlab(gitlabData map[string]*gitlabConne func (rc *RulesConfig) GetAllRuleNames(scmPlatform string) []string { alleroHomedir := fileManager.GetAlleroHomedir() rulesPath := fmt.Sprintf("%s/rules/%s", alleroHomedir, scmPlatform) + customRulesPath := fmt.Sprintf("%s/rules/%s/custom", alleroHomedir, scmPlatform) ruleNames := []string{} files := fileManager.ReadFolder(rulesPath) + customFiles := fileManager.ReadFolder(customRulesPath) + for _, file := range files { if strings.HasSuffix(file.Name(), ".json") { ruleNames = append(ruleNames, strings.TrimSuffix(file.Name(), ".json")) } } + for _, file := range customFiles { + if strings.HasSuffix(file.Name(), ".json") { + ruleName := "custom/" + strings.TrimSuffix(file.Name(), ".json") + ruleNames = append(ruleNames, ruleName) + } + } + return ruleNames } @@ -243,6 +253,8 @@ func (rc *RulesConfig) GetSelectedRuleIds() (map[int]bool, error) { } func (rc *RulesConfig) GetRule(ruleName string, scmPlatform string) (*defaultRules.Rule, error) { + isCustomRule := strings.HasPrefix(ruleName, "custom/") + alleroHomedir := fileManager.GetAlleroHomedir() ruleFilename := fmt.Sprintf("%s/rules/%s/%s.json", alleroHomedir, scmPlatform, ruleName) @@ -257,6 +269,10 @@ func (rc *RulesConfig) GetRule(ruleName string, scmPlatform string) (*defaultRul return nil, err } + if isCustomRule { + rule.UniqueId = rule.UniqueId + 1000 + } + return rule, rc.validateRuleStructure(ruleName, rule) }