From 8f8de31e4b8bf8dcd2c3f9f42b56c0b3b2a65066 Mon Sep 17 00:00:00 2001 From: MorAlon1 <101275199+MorAlon1@users.noreply.github.com> Date: Mon, 4 Jul 2022 11:24:22 +0300 Subject: [PATCH] Check entity is initialize before checking rules inside (#45) * change all rule to same format * change to cb policy * change builder to build valid object * merge * repository builder * fix 2 test files * fix all other files * add consts * fix pipeline test * change tests description * move consts to testutils, rewrite debug file * remove debug file * add is organinztion fetched to utils * change details to be in 1 object * change all statuses to consts * move to consts * move details to const * move to go funk * rename functions * handle repository data fetching failed + check if pul request * check if the information is avalible before checking the rules * reorder consts --- .../access_to_artifacts_test.go | 21 ++++++++ .../artifacts/access-to-artifacts/rules.rego | 10 ++++ .../artifacts/package-registries/rules.rego | 9 ++++ .../pipeline_instructions_test.go | 6 +-- .../pipeline-instructions/rules.rego | 2 +- .../pipeline_integrity_test.go | 4 +- .../pipeline-integrity/rules.rego | 2 +- internal/checks/common/assets/consts.rego | 9 ++-- internal/checks/common/assets/utils.rego | 8 ++++ internal/checks/consts/details.go | 3 ++ .../third-party-packages/rules.rego | 2 +- .../third_party_packages_test.go | 2 +- .../dependencies/validate_packages/rules.rego | 2 +- .../validate_packages_test.go | 4 +- .../code-changes/code_changes_test.go | 48 ++++++++++++++----- .../source-code/code-changes/rules.rego | 21 +++++++- .../contribution-access/rules.rego | 21 +++++++- .../repository_management_test.go | 34 +++++++++++++ .../repository-management/rules.rego | 15 ++++++ internal/scm-clients/clients/clients.go | 8 ++-- .../testutils/builders/assets_data_builder.go | 11 +++++ 21 files changed, 208 insertions(+), 34 deletions(-) diff --git a/internal/checks/artifacts/access-to-artifacts/access_to_artifacts_test.go b/internal/checks/artifacts/access-to-artifacts/access_to_artifacts_test.go index 2e32e57..c4b8fa6 100644 --- a/internal/checks/artifacts/access-to-artifacts/access_to_artifacts_test.go +++ b/internal/checks/artifacts/access-to-artifacts/access_to_artifacts_test.go @@ -12,6 +12,16 @@ import ( func TestAccessToArtifactsChecker(t *testing.T) { tests := []testutils.CheckTest{ + { + Name: "should return unknown when registry was not fetched", + Data: &checkmodels.CheckData{ + AssetsMetadata: builders.NewAssetsDataBuilder().WithNoRegistryData().Build(), + }, + Expected: []*checkmodels.CheckRunResult{ + checkmodels.ToCheckRunResult("4.2.3", checksMetadata.Checks["4.2.3"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_registry_data_is_missing}), + checkmodels.ToCheckRunResult("4.2.5", checksMetadata.Checks["4.2.5"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_registry_data_is_missing}), + }, + }, { Name: "should return unknown with explanation when there are no org settings permissions", Data: &checkmodels.CheckData{ @@ -43,6 +53,17 @@ func TestAccessToArtifactsChecker(t *testing.T) { checkmodels.ToCheckRunResult("4.2.3", checksMetadata.Checks["4.2.3"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Failed}), }, }, + { + Name: "Should fail when the user have package registry with 1 public package under private repo", + Data: &checkmodels.CheckData{ + AssetsMetadata: builders.NewAssetsDataBuilder(). + WithPackageRegistry(builders.NewRegistryBuilder().WithTwoFactorAuthenticationEnabled(false).Build()). + Build(), + }, + Expected: []*checkmodels.CheckRunResult{ + checkmodels.ToCheckRunResult("4.2.3", checksMetadata.Checks["4.2.3"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Failed}), + }, + }, { Name: "Should fail when the user have package registry with 1 public package under private repo", Data: &checkmodels.CheckData{ diff --git a/internal/checks/artifacts/access-to-artifacts/rules.rego b/internal/checks/artifacts/access-to-artifacts/rules.rego index 27289d0..399efd5 100644 --- a/internal/checks/artifacts/access-to-artifacts/rules.rego +++ b/internal/checks/artifacts/access-to-artifacts/rules.rego @@ -2,6 +2,7 @@ package main import data.common.consts as constsLib import data.common.permissions as permissionslib +import data.generic.utils as utilsLib import future.keywords.in is_two_factor_authentication_disabled_in_registry { @@ -20,22 +21,31 @@ is_registry_packages_allows_anonymous_access[unauth_packages] { } CbPolicy[msg] { + utilsLib.is_registry_data_missing + msg := {"ids": ["4.2.3", "4.2.5"], "status": constsLib.status.Unknown, "details": constsLib.details.registry_data_is_missing} +} + +CbPolicy[msg] { + not utilsLib.is_registry_data_missing permissionslib.is_missing_org_settings_permission msg := {"ids": ["4.2.3"], "status": constsLib.status.Unknown, "details": constsLib.details.organization_missing_minimal_permissions} } CbPolicy[msg] { + not utilsLib.is_registry_data_missing permissionslib.is_missing_org_packages_permission msg := {"ids": ["4.2.5"], "status": constsLib.status.Unknown, "details": constsLib.details.organization_packages_missing_minimal_permissions} } CbPolicy[msg] { + not utilsLib.is_registry_data_missing not permissionslib.is_missing_org_settings_permission is_two_factor_authentication_disabled_in_registry msg := {"ids": ["4.2.3"], "status": constsLib.status.Failed} } CbPolicy[msg] { + not utilsLib.is_registry_data_missing not permissionslib.is_missing_org_packages_permission unauth_packages := is_registry_packages_allows_anonymous_access[i] details := sprintf("%v %v", [format_int(unauth_packages, 10), "anonymous accessed packages"]) diff --git a/internal/checks/artifacts/package-registries/rules.rego b/internal/checks/artifacts/package-registries/rules.rego index 67c3872..e73b4e2 100644 --- a/internal/checks/artifacts/package-registries/rules.rego +++ b/internal/checks/artifacts/package-registries/rules.rego @@ -2,6 +2,7 @@ package main import data.common.consts as constsLib import data.common.permissions as permissionslib +import data.generic.utils as utilsLib import future.keywords.in is_org_have_unsucured_hooks[unsecuredHooks] { @@ -18,6 +19,12 @@ is_org_have_unsucured_hooks[unsecuredHooks] { unsecuredHooks > 0 } +CbPolicy[msg] { + utilsLib.is_repository_data_missing + utilsLib.is_organization_data_missing + msg := {"ids": ["4.3.4"], "status": constsLib.status.Unknown} +} + CbPolicy[msg] { permissionslib.is_missing_hooks_permission msg := {"ids": ["4.3.4"], "status": constsLib.status.Unknown, "details": constsLib.details.hooks_missing_minimal_permissions} @@ -25,6 +32,8 @@ CbPolicy[msg] { #Looking for organization 2mfa enforcements that is disabled CbPolicy[msg] { + not utilsLib.is_repository_data_missing + not utilsLib.is_organization_data_missing not permissionslib.is_missing_hooks_permission unsecuredHooks := is_org_have_unsucured_hooks[i] details := sprintf("%v %v", [format_int(unsecuredHooks, 10), "unsecured webhooks"]) diff --git a/internal/checks/build-pipelines/pipeline-instructions/pipeline_instructions_test.go b/internal/checks/build-pipelines/pipeline-instructions/pipeline_instructions_test.go index e2cb094..7e7a858 100644 --- a/internal/checks/build-pipelines/pipeline-instructions/pipeline_instructions_test.go +++ b/internal/checks/build-pipelines/pipeline-instructions/pipeline_instructions_test.go @@ -43,9 +43,9 @@ func TestBuildChecker(t *testing.T) { AssetsMetadata: builders.NewAssetsDataBuilder().WithNoPipelinesData().Build(), }, Expected: []*checkmodels.CheckRunResult{ - checkmodels.ToCheckRunResult("2.3.1", checksMetadata.Checks["2.3.1"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("2.3.7", checksMetadata.Checks["2.3.7"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("2.3.8", checksMetadata.Checks["2.3.8"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), + checkmodels.ToCheckRunResult("2.3.1", checksMetadata.Checks["2.3.1"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_pipeline_are_missing}), + checkmodels.ToCheckRunResult("2.3.7", checksMetadata.Checks["2.3.7"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_pipeline_are_missing}), + checkmodels.ToCheckRunResult("2.3.8", checksMetadata.Checks["2.3.8"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_pipeline_are_missing}), }, }, { diff --git a/internal/checks/build-pipelines/pipeline-instructions/rules.rego b/internal/checks/build-pipelines/pipeline-instructions/rules.rego index 711598d..34af645 100644 --- a/internal/checks/build-pipelines/pipeline-instructions/rules.rego +++ b/internal/checks/build-pipelines/pipeline-instructions/rules.rego @@ -46,7 +46,7 @@ is_build_job_missing { # In case pipelines weren't fetched CbPolicy[msg] { utilsLib.is_pipelines_data_missing - msg = {"ids": pipelineRuleIds, "status": constsLib.status.Unknown} + msg = {"ids": pipelineRuleIds, "status": constsLib.status.Unknown, "details": constsLib.details.pipeline_data_is_missing} } # In case there are no pipelines diff --git a/internal/checks/build-pipelines/pipeline-integrity/pipeline_integrity_test.go b/internal/checks/build-pipelines/pipeline-integrity/pipeline_integrity_test.go index e627cea..32cee72 100644 --- a/internal/checks/build-pipelines/pipeline-integrity/pipeline_integrity_test.go +++ b/internal/checks/build-pipelines/pipeline-integrity/pipeline_integrity_test.go @@ -56,8 +56,8 @@ func TestBuildChecker(t *testing.T) { AssetsMetadata: builders.NewAssetsDataBuilder().WithNoPipelinesData().Build(), }, Expected: []*checkmodels.CheckRunResult{ - checkmodels.ToCheckRunResult("2.4.2", checksMetadata.Checks["2.4.2"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("2.4.6", checksMetadata.Checks["2.4.6"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), + checkmodels.ToCheckRunResult("2.4.2", checksMetadata.Checks["2.4.2"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_pipeline_are_missing}), + checkmodels.ToCheckRunResult("2.4.6", checksMetadata.Checks["2.4.6"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_pipeline_are_missing}), }, }, { diff --git a/internal/checks/build-pipelines/pipeline-integrity/rules.rego b/internal/checks/build-pipelines/pipeline-integrity/rules.rego index 0d39f58..6adf139 100644 --- a/internal/checks/build-pipelines/pipeline-integrity/rules.rego +++ b/internal/checks/build-pipelines/pipeline-integrity/rules.rego @@ -64,7 +64,7 @@ are_there_pipelines_without_sbom[pipelinesWithoutSBOM] { # In case pipelines weren't fetched CbPolicy[msg] { utilsLib.is_pipelines_data_missing - msg = {"ids": ruleIds, "status": constsLib.status.Unknown} + msg = {"ids": ruleIds, "status": constsLib.status.Unknown, "details": constsLib.details.pipeline_data_is_missing} } # In case there are no pipelines diff --git a/internal/checks/common/assets/consts.rego b/internal/checks/common/assets/consts.rego index 1dc2cc8..766eb08 100644 --- a/internal/checks/common/assets/consts.rego +++ b/internal/checks/common/assets/consts.rego @@ -3,19 +3,22 @@ package common.consts details := details { details := { "organization_missing_minimal_permissions": "Organization is missing minimal permissions", - "repository_missing_minimal_permissions": "Repository is missing minimal permissions", + "organization_not_fetched": "Organization is not fetched", "organization_packages_missing_minimal_permissions": "Organization Packages is missing minimal permissions", + "organization_premissive_default_repository_permissions": "Organization default permissions are too permissive", + "repository_missing_minimal_permissions": "Repository is missing minimal permissions", + "repository_data_is_missing": "Repository is not fetched", "hooks_missing_minimal_permissions": "Organization & Repository Hooks is missing minimal permissions", "linear_history_merge_commit_enabled": "MergeCommit is enabled for repository", "linear_history_require_rebase_or_squash_commit_enabled": "Repository is not configured to allow rebase or squash merge", "pipeline_no_pipelines_found": "No pipelines were found", "pipeline_no_build_job": "No build job was found in pipelines", - "organization_premissive_default_repository_permissions": "Organization default permissions are too permissive", + "pipeline_data_is_missing": "Pipelines are not fetched", "pipeline_pipelines_not_scanned_for_vulnerabilities": "Pipelines are not scanned for vulnerabilities", - "organization_not_fetched": "Organization is not fetched", "pipeline_repository_not_scanned_for_secrets": "Repository is not scanned for secrets", "dependencies_pipelines_not_scanned_for_vulnerabilities": "Pipeline dependencies are not scanned for vulnerabilities", "dependencies_pipelines_not_scanned_for_licenses": "Pipeline dependencies are not scanned for licenses", + "registry_data_is_missing": "Registry is not fetched", } } diff --git a/internal/checks/common/assets/utils.rego b/internal/checks/common/assets/utils.rego index 3f47a84..252fdff 100644 --- a/internal/checks/common/assets/utils.rego +++ b/internal/checks/common/assets/utils.rego @@ -11,3 +11,11 @@ is_pipelines_list_empty { is_organization_data_missing { input.Organization == null } + +is_registry_data_missing { + input.Registry == null +} + +is_repository_data_missing { + input.Repository == null +} diff --git a/internal/checks/consts/details.go b/internal/checks/consts/details.go index a7ae966..4518a76 100644 --- a/internal/checks/consts/details.go +++ b/internal/checks/consts/details.go @@ -19,4 +19,7 @@ var ( Details_pipeline_repositoryNotScannedForSecrets = "Repository is not scanned for secrets" Details_pipeline_noPipelinesFound = "No pipelines were found" Details_pipeline_noBuildJob = "No build job was found in pipelines" + Details_registry_data_is_missing = "Registry is not fetched" + Details_pipeline_are_missing = "Pipelines are not fetched" + Details_repository_is_missing = "Repository is not fetched" ) diff --git a/internal/checks/dependencies/third-party-packages/rules.rego b/internal/checks/dependencies/third-party-packages/rules.rego index a56ea0a..1d8fd7a 100644 --- a/internal/checks/dependencies/third-party-packages/rules.rego +++ b/internal/checks/dependencies/third-party-packages/rules.rego @@ -20,7 +20,7 @@ are_there_unpinned_deps[unpinnedDepsCount] { CbPolicy[msg] { utilsLib.is_pipelines_data_missing - msg = {"ids": ["3.1.7"], "status": constsLib.status.Unknown} + msg = {"ids": ["3.1.7"], "status": constsLib.status.Unknown, "details": constsLib.details.pipeline_data_is_missing} } # In case there are no pipelines diff --git a/internal/checks/dependencies/third-party-packages/third_party_packages_test.go b/internal/checks/dependencies/third-party-packages/third_party_packages_test.go index 3e8c859..745e857 100644 --- a/internal/checks/dependencies/third-party-packages/third_party_packages_test.go +++ b/internal/checks/dependencies/third-party-packages/third_party_packages_test.go @@ -18,7 +18,7 @@ func TestBuildChecker(t *testing.T) { AssetsMetadata: builders.NewAssetsDataBuilder().WithNoPipelinesData().Build(), }, Expected: []*checkmodels.CheckRunResult{ - checkmodels.ToCheckRunResult("3.1.7", checksMetadata.Checks["3.1.7"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), + checkmodels.ToCheckRunResult("3.1.7", checksMetadata.Checks["3.1.7"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_pipeline_are_missing}), }, }, { diff --git a/internal/checks/dependencies/validate_packages/rules.rego b/internal/checks/dependencies/validate_packages/rules.rego index 30a8d16..daf00ea 100644 --- a/internal/checks/dependencies/validate_packages/rules.rego +++ b/internal/checks/dependencies/validate_packages/rules.rego @@ -19,7 +19,7 @@ are_pipelines_dependencies_scanned_for_licenses { CbPolicy[msg] { utilsLib.is_pipelines_data_missing - msg = {"ids": ["3.2.2", "3.2.3"], "status": constsLib.status.Unknown} + msg = {"ids": ["3.2.2", "3.2.3"], "status": constsLib.status.Unknown, "details": constsLib.details.pipeline_data_is_missing} } # In case there are no pipelines diff --git a/internal/checks/dependencies/validate_packages/validate_packages_test.go b/internal/checks/dependencies/validate_packages/validate_packages_test.go index 62180ce..8d581cb 100644 --- a/internal/checks/dependencies/validate_packages/validate_packages_test.go +++ b/internal/checks/dependencies/validate_packages/validate_packages_test.go @@ -18,8 +18,8 @@ func TestBuildChecker(t *testing.T) { AssetsMetadata: builders.NewAssetsDataBuilder().WithNoPipelinesData().Build(), }, Expected: []*checkmodels.CheckRunResult{ - checkmodels.ToCheckRunResult("3.2.2", checksMetadata.Checks["3.2.2"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("3.2.3", checksMetadata.Checks["3.2.3"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), + checkmodels.ToCheckRunResult("3.2.2", checksMetadata.Checks["3.2.2"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_pipeline_are_missing}), + checkmodels.ToCheckRunResult("3.2.3", checksMetadata.Checks["3.2.3"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_pipeline_are_missing}), }, }, { diff --git a/internal/checks/source-code/code-changes/code_changes_test.go b/internal/checks/source-code/code-changes/code_changes_test.go index fe64088..0d8728b 100644 --- a/internal/checks/source-code/code-changes/code_changes_test.go +++ b/internal/checks/source-code/code-changes/code_changes_test.go @@ -38,19 +38,41 @@ func TestCodeChangesChecker(t *testing.T) { AssetsMetadata: builders.NewAssetsDataBuilder().WithRepository(builders.NewRepositoryBuilder().WithNoRepoPemissions().Build()).Build(), }, Expected: []*checkmodels.CheckRunResult{ - checkmodels.ToCheckRunResult("1.1.3", checksMetadata.Checks["1.1.3"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("1.1.4", checksMetadata.Checks["1.1.4"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("1.1.5", checksMetadata.Checks["1.1.5"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("1.1.6", checksMetadata.Checks["1.1.6"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("1.1.9", checksMetadata.Checks["1.1.9"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("1.1.10", checksMetadata.Checks["1.1.10"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("1.1.11", checksMetadata.Checks["1.1.11"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("1.1.12", checksMetadata.Checks["1.1.12"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("1.1.13", checksMetadata.Checks["1.1.13"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("1.1.14", checksMetadata.Checks["1.1.14"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("1.1.15", checksMetadata.Checks["1.1.15"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("1.1.16", checksMetadata.Checks["1.1.16"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), - checkmodels.ToCheckRunResult("1.1.17", checksMetadata.Checks["1.1.17"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown}), + checkmodels.ToCheckRunResult("1.1.3", checksMetadata.Checks["1.1.3"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + checkmodels.ToCheckRunResult("1.1.4", checksMetadata.Checks["1.1.4"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + checkmodels.ToCheckRunResult("1.1.5", checksMetadata.Checks["1.1.5"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + checkmodels.ToCheckRunResult("1.1.6", checksMetadata.Checks["1.1.6"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + checkmodels.ToCheckRunResult("1.1.9", checksMetadata.Checks["1.1.9"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + checkmodels.ToCheckRunResult("1.1.10", checksMetadata.Checks["1.1.10"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + checkmodels.ToCheckRunResult("1.1.11", checksMetadata.Checks["1.1.11"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + checkmodels.ToCheckRunResult("1.1.12", checksMetadata.Checks["1.1.12"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + checkmodels.ToCheckRunResult("1.1.13", checksMetadata.Checks["1.1.13"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + checkmodels.ToCheckRunResult("1.1.14", checksMetadata.Checks["1.1.14"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + checkmodels.ToCheckRunResult("1.1.15", checksMetadata.Checks["1.1.15"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + checkmodels.ToCheckRunResult("1.1.16", checksMetadata.Checks["1.1.16"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + checkmodels.ToCheckRunResult("1.1.17", checksMetadata.Checks["1.1.17"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_missing_minimal_permissions}), + }, + }, + { + Name: "Couldnt get repostiroty data because of missing permissions or wrong url", + Data: &checkmodels.CheckData{ + AssetsMetadata: builders.NewAssetsDataBuilder().WithNoRepositoryData().Build(), + }, + Expected: []*checkmodels.CheckRunResult{ + checkmodels.ToCheckRunResult("1.1.3", checksMetadata.Checks["1.1.3"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.4", checksMetadata.Checks["1.1.4"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.5", checksMetadata.Checks["1.1.5"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.6", checksMetadata.Checks["1.1.6"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.8", checksMetadata.Checks["1.1.8"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.9", checksMetadata.Checks["1.1.9"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.10", checksMetadata.Checks["1.1.10"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.11", checksMetadata.Checks["1.1.11"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.12", checksMetadata.Checks["1.1.12"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.13", checksMetadata.Checks["1.1.13"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.14", checksMetadata.Checks["1.1.14"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.15", checksMetadata.Checks["1.1.15"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.16", checksMetadata.Checks["1.1.16"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + checkmodels.ToCheckRunResult("1.1.17", checksMetadata.Checks["1.1.17"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), }, }, { diff --git a/internal/checks/source-code/code-changes/rules.rego b/internal/checks/source-code/code-changes/rules.rego index 1b44a26..ff9c2bd 100644 --- a/internal/checks/source-code/code-changes/rules.rego +++ b/internal/checks/source-code/code-changes/rules.rego @@ -2,6 +2,7 @@ package main import data.common.consts as constsLib import data.common.permissions as permissionslib +import data.generic.utils as utilsLib import future.keywords.in # for repository without branch protection setting @@ -30,6 +31,10 @@ is_branch_protection_not_requires_dismissal_restrictions { input.BranchProtections.RequiredPullRequestReviews.DismissalRestrictions == null } +is_required_pull_request_reviews_disabled { + input.BranchProtections.RequiredPullRequestReviews == null +} + is_branch_protection_not_requires_conversation_resolution { input.BranchProtections.RequiredConversationResolution == false } @@ -95,14 +100,22 @@ is_repository_prevent_rebase_and_squash_merge { input.Repository.AllowSquashMerge == false } +#couldnt get repository data +CbPolicy[msg] { + utilsLib.is_repository_data_missing + msg := {"ids": ["1.1.3", "1.1.4", "1.1.5", "1.1.6", "1.1.8", "1.1.9", "1.1.10", "1.1.11", "1.1.12", "1.1.13", "1.1.14", "1.1.15", "1.1.16", "1.1.17"], "status": constsLib.status.Unknown, "details": constsLib.details.repository_data_is_missing} +} + #missing permissions CbPolicy[msg] { + not utilsLib.is_repository_data_missing permissionslib.is_missing_repo_settings_permission - msg := {"ids": ["1.1.3", "1.1.4", "1.1.5", "1.1.6", "1.1.9", "1.1.10", "1.1.11", "1.1.12", "1.1.13", "1.1.14", "1.1.15", "1.1.16", "1.1.17"], "status": constsLib.status.Unknown} + msg := {"ids": ["1.1.3", "1.1.4", "1.1.5", "1.1.6", "1.1.9", "1.1.10", "1.1.11", "1.1.12", "1.1.13", "1.1.14", "1.1.15", "1.1.16", "1.1.17"], "status": constsLib.status.Unknown, "details": constsLib.details.repository_missing_minimal_permissions} } #Missing branch protection settings CbPolicy[msg] { + not utilsLib.is_repository_data_missing not permissionslib.is_missing_repo_settings_permission is_no_branch_protection msg := {"ids": ["1.1.3", "1.1.4", "1.1.5", "1.1.6", "1.1.9", "1.1.10", "1.1.11", "1.1.12", "1.1.14", "1.1.15", "1.1.16", "1.1.17"], "status": constsLib.status.Failed} @@ -119,6 +132,11 @@ CbPolicy[msg] { msg := {"ids": ["1.1.5"], "status": constsLib.status.Unknown} } +CbPolicy[msg] { + is_required_pull_request_reviews_disabled + msg := {"ids": ["1.1.3", "1.1.4", "1.1.5", "1.1.6"], "status": constsLib.status.Failed} +} + CbPolicy[msg] { not is_no_branch_protection is_branch_protection_not_requires_two_minimum_reviewers_before_merge @@ -148,6 +166,7 @@ CbPolicy[msg] { #Looking for inactive branches CbPolicy[msg] { + not utilsLib.is_repository_data_missing inactiveCount := is_inactive_branches[i] details := sprintf("%v %v", [format_int(inactiveCount, 10), "inactive branches"]) msg := {"ids": ["1.1.8"], "status": constsLib.status.Failed, "details": details} diff --git a/internal/checks/source-code/contribution-access/rules.rego b/internal/checks/source-code/contribution-access/rules.rego index dcfcd1a..28a1f2d 100644 --- a/internal/checks/source-code/contribution-access/rules.rego +++ b/internal/checks/source-code/contribution-access/rules.rego @@ -2,6 +2,7 @@ package main import data.common.consts as constsLib import data.common.permissions as permissionslib +import data.generic.utils as utilsLib import future.keywords.in # for repository without branch protection setting @@ -54,18 +55,33 @@ is_repository_has_inactive_users[inactiveCount] { inactiveCount > 0 } +CbPolicy[msg] { + utilsLib.is_repository_data_missing + msg := {"ids": ["1.3.1", "1.3.7"], "status": constsLib.status.Unknown, "details": constsLib.details.repository_data_is_missing} +} + +#Looking for organization missing data +CbPolicy[msg] { + utilsLib.is_organization_data_missing + msg := {"ids": ["1.3.3", "1.3.5", "1.3.7", "1.3.8", "1.3.9"], "status": constsLib.status.Unknown, "details": constsLib.details.organization_not_fetched} +} + #Looking for organization missing permissions CbPolicy[msg] { + not utilsLib.is_organization_data_missing permissionslib.is_missing_org_settings_permission - msg := {"ids": ["1.3.5", "1.3.7", "1.3.8"], "status": constsLib.status.Unknown} + msg := {"ids": ["1.3.3", "1.3.5", "1.3.7", "1.3.8"], "status": constsLib.status.Unknown} } CbPolicy[msg] { + not utilsLib.is_organization_data_missing + not permissionslib.is_missing_org_settings_permission not is_organization_admin msg := {"ids": ["1.3.3"], "status": constsLib.status.Unknown} } CbPolicy[msg] { + not utilsLib.is_repository_data_missing is_repo_has_no_commits msg := {"ids": ["1.3.1"], "status": constsLib.status.Unknown} } @@ -86,6 +102,7 @@ CbPolicy[msg] { #Looking for organization 2mfa enforcements that is disabled CbPolicy[msg] { + not utilsLib.is_organization_data_missing not permissionslib.is_missing_org_settings_permission is_2mfa_enforcement_disabled msg := {"ids": ["1.3.5"], "status": constsLib.status.Failed} @@ -93,6 +110,7 @@ CbPolicy[msg] { #Looking for repository with no 2 admins CbPolicy[msg] { + not utilsLib.is_repository_data_missing not permissionslib.is_missing_org_settings_permission is_repository_dont_have_2_admins msg := {"ids": ["1.3.7"], "status": constsLib.status.Failed} @@ -100,6 +118,7 @@ CbPolicy[msg] { #Looking for organization with non strict base permission CbPolicy[msg] { + not utilsLib.is_organization_data_missing not permissionslib.is_missing_org_settings_permission not permissionslib.is_org_default_permission_strict msg := {"ids": ["1.3.8"], "status": constsLib.status.Failed} diff --git a/internal/checks/source-code/repository-management/repository_management_test.go b/internal/checks/source-code/repository-management/repository_management_test.go index 02666b7..3f79440 100644 --- a/internal/checks/source-code/repository-management/repository_management_test.go +++ b/internal/checks/source-code/repository-management/repository_management_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/aquasecurity/chain-bench/internal/checks/common" + "github.com/aquasecurity/chain-bench/internal/checks/consts" "github.com/aquasecurity/chain-bench/internal/models/checkmodels" "github.com/aquasecurity/chain-bench/internal/testutils" "github.com/aquasecurity/chain-bench/internal/testutils/builders" @@ -17,6 +18,39 @@ func TestRepositoryChecker(t *testing.T) { json.Unmarshal(metadataString, &checksMetadata) tests := []testutils.CheckTest{ + { + Name: "Should fail for public repository without security.md file", + Data: &checkmodels.CheckData{ + + AssetsMetadata: builders.NewAssetsDataBuilder(). + WithRepository(builders.NewRepositoryBuilder().WithPrivate(false).WithSecurityMdFile(false).Build()).Build(), + }, + Expected: []*checkmodels.CheckRunResult{ + checkmodels.ToCheckRunResult("1.2.1", checksMetadata.Checks["1.2.1"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Failed}), + }, + }, + { + Name: "Should return unknown if repository not fetched", + Data: &checkmodels.CheckData{ + + AssetsMetadata: builders.NewAssetsDataBuilder().WithNoRepositoryData().Build(), + }, + Expected: []*checkmodels.CheckRunResult{ + checkmodels.ToCheckRunResult("1.2.1", checksMetadata.Checks["1.2.1"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_repository_is_missing}), + }, + }, + { + Name: "Should return unknown if organization not fetched", + Data: &checkmodels.CheckData{ + + AssetsMetadata: builders.NewAssetsDataBuilder().WithNoOrganization().Build(), + }, + Expected: []*checkmodels.CheckRunResult{ + checkmodels.ToCheckRunResult("1.2.2", checksMetadata.Checks["1.2.2"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_organization_notFetched}), + checkmodels.ToCheckRunResult("1.2.3", checksMetadata.Checks["1.2.3"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_organization_notFetched}), + checkmodels.ToCheckRunResult("1.2.4", checksMetadata.Checks["1.2.4"], checksMetadata.Url, &checkmodels.CheckResult{Status: checkmodels.Unknown, Details: consts.Details_organization_notFetched}), + }, + }, { Name: "Should fail for public repository without security.md file", Data: &checkmodels.CheckData{ diff --git a/internal/checks/source-code/repository-management/rules.rego b/internal/checks/source-code/repository-management/rules.rego index a8d272a..76e1958 100644 --- a/internal/checks/source-code/repository-management/rules.rego +++ b/internal/checks/source-code/repository-management/rules.rego @@ -1,6 +1,7 @@ package main import data.common.consts as constsLib +import data.generic.utils as utilsLib import future.keywords.in #checks if the repository is public one @@ -25,24 +26,38 @@ is_issue_deletion_not_limited_to_trusted_memebers { input.Organization.IsIssueDeletionLimited == false } +CbPolicy[msg] { + utilsLib.is_repository_data_missing + msg := {"ids": ["1.2.1"], "status": constsLib.status.Unknown, "details": constsLib.details.repository_data_is_missing} +} + +CbPolicy[msg] { + utilsLib.is_organization_data_missing + msg := {"ids": ["1.2.2", "1.2.3", "1.2.4"], "status": constsLib.status.Unknown, "details": constsLib.details.organization_not_fetched} +} + #Looking for security md file in repository CbPolicy[msg] { + not utilsLib.is_repository_data_missing is_public_repository is_missing_security_md_file msg := {"ids": ["1.2.1"], "status": constsLib.status.Failed} } CbPolicy[msg] { + not utilsLib.is_organization_data_missing is_repository_creation_not_limited_to_trusted_memebers msg := {"ids": ["1.2.2"], "status": constsLib.status.Failed} } CbPolicy[msg] { + not utilsLib.is_organization_data_missing is_repository_deletion_not_limited_to_trusted_memebers msg := {"ids": ["1.2.3"], "status": constsLib.status.Failed} } CbPolicy[msg] { + not utilsLib.is_organization_data_missing is_issue_deletion_not_limited_to_trusted_memebers msg := {"ids": ["1.2.4"], "status": constsLib.status.Failed} } diff --git a/internal/scm-clients/clients/clients.go b/internal/scm-clients/clients/clients.go index cc307d2..3176137 100644 --- a/internal/scm-clients/clients/clients.go +++ b/internal/scm-clients/clients/clients.go @@ -41,11 +41,11 @@ func FetchClientData(accessToken string, repoUrl string) (*checkmodels.AssetsDat logger.FetchingFinished("Branch Protection Settings", emoji.Seedling) orgMembers, err := adapter.ListOrganizationMembers(orgName) - if err != nil { - return nil, err + + if err == nil { + org.Members = orgMembers + logger.FetchingFinished("Members", emoji.Emoji(emoji.WomanAndManHoldingHands.Tone())) } - org.Members = orgMembers - logger.FetchingFinished("Members", emoji.Emoji(emoji.WomanAndManHoldingHands.Tone())) pipelines, _ := adapter.GetPipelines(orgName, repoName, defaultBranch) logger.FetchingFinished("Pipelines", emoji.Wrench) diff --git a/internal/testutils/builders/assets_data_builder.go b/internal/testutils/builders/assets_data_builder.go index 5bc1efb..5fe7794 100644 --- a/internal/testutils/builders/assets_data_builder.go +++ b/internal/testutils/builders/assets_data_builder.go @@ -19,6 +19,7 @@ func NewAssetsDataBuilder() *AssetsDataBuilder { BranchProtections: NewBranchProtectionBuilder().Build(), AuthorizedUser: &models.User{ID: utils.GetPtr(testutils.AuthorizedUserMockId)}, Pipelines: []*pipelineParserModels.Pipeline{NewPipelineBuilder().Build()}, + Registry: &models.PackageRegistry{Packages: []*models.Package{}}, }} } @@ -70,6 +71,16 @@ func (b *AssetsDataBuilder) WithNoPipelinesData() *AssetsDataBuilder { return b } +func (b *AssetsDataBuilder) WithNoRepositoryData() *AssetsDataBuilder { + b.assetsData.Repository = nil + return b +} + +func (b *AssetsDataBuilder) WithNoRegistryData() *AssetsDataBuilder { + b.assetsData.Registry = nil + return b +} + func (b *AssetsDataBuilder) WithNoOrganization() *AssetsDataBuilder { b.assetsData.Organization = nil return b