Source code for src.checks

"""Module that allows to instantiate any selection of available checks
on a project"""

import json
import logging
from collections.abc import Callable, Iterable
from pathlib import Path
from typing import Any, Optional

import jsonschema
from git import Repo
from gitlab import Gitlab
from gitlab.v4.objects import Project
from jsonschema import SchemaError, ValidationError

from src.checks.checked_in_binaries import CheckedInBinaries
from src.checks.comments_in_code import CommentsInCode
from src.checks.existence_of_documentation_infrastructure import (
    ExistenceOfDocumentationInfrastructure,
)
from src.checks.opencode_usage import OpencodeUsage
from src.checks.sast_usage_basic import SastUsageBasic
from src.checks.secrets import Secrets
from src.checks.security_policy import SecurityPolicy
from src.checks.signed_releases import SignedReleases
from src.config import context
from src.exceptions import CheckConstructionError
from src.interfaces import CheckInterface

logger: logging.Logger = logging.getLogger(__name__)

available_checks: list[type[CheckInterface]] = [
    CheckedInBinaries,
    CommentsInCode,
    ExistenceOfDocumentationInfrastructure,
    OpencodeUsage,
    SastUsageBasic,
    Secrets,
    SecurityPolicy,
    SignedReleases,
]


[docs] def results_valid(results: dict[str, Any]) -> bool: """ Validates the results that a check instance's run method returned. """ schema_path: Path = Path( context.settings["local_repo_db_resources_dir"] ) / Path("schemas/check_common_output_format.json") logger.info(f"Loading check result schema from {schema_path}") with schema_path.open(mode="r") as f: schema = json.load(f) logger.info("Validating check results against schema") try: jsonschema.validate(results, schema) return True except ValidationError: logger.error("Check results do not conform to expected schema") except SchemaError: logger.error("Check results schema is not valid") return False
[docs] def validate_args(args_dict: dict[str, Any]) -> bool: """Validates the set of arguments passed to the 'check' subcommand""" if args_dict.get("directory") and not args_dict.get("id"): logger.error( "Fatal: Illegal combination of parameters: " "The 'directory' option requires a project " "'id'" ) return False return True
[docs] def transform_args( args_dict: dict[str, Any], ) -> tuple[Optional[Path], Optional[int]]: """Transforms the set of arguments passed to the check subcommand""" if args_dict.get("verbose"): logging.getLogger().level = logging.DEBUG logger.debug("Prepare for lots out output") directory: str | Path | None = args_dict.get("directory") if isinstance(directory, str): directory = Path(directory) _id: str | int | None = args_dict.get("id") if isinstance(_id, str): _id = int(_id) return directory, _id
[docs] def iter_checks( proj: Project, repo: Repo, api: Gitlab, filter_func: Callable[[type[CheckInterface]], bool] = lambda _: False, ) -> Iterable[CheckInterface]: """ This method is used to get instances of all checks in the set filter_func(availableChecks) for a single project. yields: check instances for the given project """ for check in available_checks: if filter_func(check): continue try: yield check(proj, repo, api) except CheckConstructionError as E: logger.error( f"Failed to instantiate {check.name()} on {proj.name_with_namespace}, {repo}: {E}" ) continue