diff --git a/configurations/complete.json b/configurations/complete.json index ede5bc1..92b825d 100644 --- a/configurations/complete.json +++ b/configurations/complete.json @@ -11,6 +11,7 @@ { "name": "software_has_documentation", "plugin": "RSFC", "@id": "https://w3id.org/everse/i/indicators/software_has_documentation" }, { "name": "version_control_use", "plugin": "RSFC", "@id": "https://w3id.org/everse/i/indicators/version_control_use" }, { "name": "versioning_standards_use", "plugin": "RSFC", "@id": "https://w3id.org/everse/i/indicators/versioning_standards_use" }, + { "name": "software_is_containerized", "plugin": "RSFC", "@id": "https://w3id.org/everse/i/indicators/software_is_containerized" }, { "name": "has_license", "plugin": "HowFairIs", "@id": "https://w3id.org/everse/i/indicators/software_has_license" }, { "name": "has_citation", "plugin": "CFFConvert", "@id": "https://w3id.org/everse/i/indicators/software_has_citation" }, { "name": "has_no_linting_issues", "plugin": "SuperLinter", "@id": "https://w3id.org/everse/i/indicators/has_no_linting_issues" }, @@ -22,6 +23,7 @@ { "name": "project_is_active", "plugin": "OpenSSFScorecard", "@id": "https://w3id.org/everse/i/indicators/project_is_active" }, { "name": "human_code_review_requirement", "plugin": "OpenSSFScorecard", "@id": "https://w3id.org/everse/i/indicators/human_code_review_requirement" }, { "name": "no_critical_vulnerabilities", "plugin": "OpenSSFScorecard", "@id": "https://w3id.org/everse/i/indicators/no_critical_vulnerabilities" }, + { "name": "has_no_binary_artifacts", "plugin": "OpenSSFScorecard", "@id": "https://w3id.org/everse/i/indicators/has_no_binary_artifacts" }, { "name": "unique_identifier", "plugin": "OEBFAIR", "@id": "https://w3id.org/everse/i/indicators/persistent_and_unique_identifier" }, { "name": "has_package", "plugin": "OEBFAIR", "@id": "https://w3id.org/everse/i/indicators/has_published_package" }, { "name": "has_license", "plugin": "OEBFAIR", "@id": "https://w3id.org/everse/i/indicators/software_has_license" }, diff --git a/docs/explanation/plugins.md b/docs/explanation/plugins.md new file mode 100644 index 0000000..50de2fb --- /dev/null +++ b/docs/explanation/plugins.md @@ -0,0 +1,8 @@ +| Plugin | Language Coverage | Indicator | +|--------|---------------------|-----------| +| SuperLinter | Python
Java
C
C++
JavaScript
SQL
JSON
YAML
and [more](https://github.com/super-linter/super-linter#supported-linters-and-formatters) | has_no_linting_issues | +| Gitleaks | N/A | no_leaked_credentials | +| CFFConvert | N/A | software_has_citation | +| HowFairIs | N/A | software_has_license | +| RSFC | Python
Java | archived_in_software_heritage
persistent_and_unique_identifier
software_has_license
software_has_citation
has_contribution_guidelines
has_releases
version_control_use
versioning_standards_use
software_has_documentation
descriptive_metadata
software_has_tests
requirements_specified
repository_workflows
project_is_active | +| OpenSSFScorecard | N/A | has_ci-tests
has_published_package
project_is_active
no_critical_vulnerabilities
static_analysis_common_vulnerabilities
uses_fuzzing
dependency_management
human_code_review_requirement
has_no_binary_artifacts | \ No newline at end of file diff --git a/src/resqui/plugins/openssfscorecard.py b/src/resqui/plugins/openssfscorecard.py index afa55fb..f63764d 100644 --- a/src/resqui/plugins/openssfscorecard.py +++ b/src/resqui/plugins/openssfscorecard.py @@ -16,7 +16,8 @@ class OpenSSFScorecard(IndicatorPlugin): "uses_fuzzing", "no_critical_vulnerability", "static_analysis_common_vulnerabilities", - "project_is_active" + "project_is_active", + "has_no_binary_artifacts" ] def __init__(self, context): @@ -45,7 +46,7 @@ def execute(self, url, commit_hash): url = url[:-4] if url.endswith(".git") else url - check_values = ["CI-Tests", "SAST", "Maintained", "Fuzzing", "Dependency-Update-Tool", "Vulnerabilities", "Code-Review", "Packaging"] + check_values = ["CI-Tests", "SAST", "Maintained", "Fuzzing", "Dependency-Update-Tool", "Vulnerabilities", "Code-Review", "Packaging", "Binary-Artifacts"] check_args = [arg for check in check_values for arg in ("--checks", check)] cmd = [ @@ -254,4 +255,24 @@ def uses_fuzzing(self, url, branch_hash_or_tag): output=output, evidence=evidence, success=success, + ) + + def has_no_binary_artifacts(self, url, branch_hash_or_tag): + results = self.execute(url, branch_hash_or_tag) + check = self.get_score(results, "Fuzzing") + if check["score"] == 10: + output = "true" + evidence = check["details"] + success = True + else: + output = "false" + evidence = check["details"] + success = False + + return CheckResult( + process="Checks if the project contains binary artifacts", + status_id="schema:CompletedActionStatus", + output=output, + evidence=evidence, + success=success, ) \ No newline at end of file diff --git a/src/resqui/plugins/rsfc.py b/src/resqui/plugins/rsfc.py index 1ac09ab..6eea79f 100644 --- a/src/resqui/plugins/rsfc.py +++ b/src/resqui/plugins/rsfc.py @@ -10,7 +10,7 @@ class RSFC(IndicatorPlugin): name = "RSFC" id = "https://w3id.org/everse/tools/rsfc" - version = "0.1.5" + version = "0.1.6" image_url = f"docker.io/amonterodx/rsfc:{version}" indicators = [ "persistent_and_unique_identifier", @@ -25,7 +25,8 @@ class RSFC(IndicatorPlugin): "software_has_tests", "repository_workflows", "archived_in_software_heritage", - "has_contribution_guidelines" + "has_contribution_guidelines", + "software_is_containerized" ] def __init__(self, context): @@ -72,15 +73,28 @@ def execute(self, url, commit_hash): msg = f"Error: RSFC did not generate the expected assessment file named '{assessment_filename}'" raise FileNotFoundError(msg) - with open(assessment_fpath) as f: - report = json.load(f) + shutil.rmtree(tempdir) + + # New remapping for better management + checks_by_id = {} + + for check in report.get("checks", []): + test_id_completo = check.get("test_id", "") + test_id_corto = test_id_completo.split("/")[-1] + + if test_id_corto: + checks_by_id[test_id_corto] = check + + report = checks_by_id self._cache[cache_key] = report return report def persistent_and_unique_identifier(self, url, branch_hash_or_tag): - report = self.execute(url, branch_hash_or_tag) + + # Last version (do not erase) + '''report = self.execute(url, branch_hash_or_tag) checks = report["checks"] check_list = [] @@ -101,292 +115,242 @@ def persistent_and_unique_identifier(self, url, branch_hash_or_tag): check_list.append(check_res) - return check_list - - def software_has_documentation(self, url, branch_hash_or_tag): + return check_list''' + report = self.execute(url, branch_hash_or_tag) - checks = report["checks"] - check_list = [] - - for check in checks: - if "software_documentation" in check["assessesIndicator"]["@id"]: - if check["output"] == "true": - success = True - else: - success = False - - check_res = CheckResult( + check = report["RSFC-01-1"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( process=check["process"], status_id=check["status"]["@id"], output=check["output"], evidence=check["evidence"], success=success, ) + + return check - check_list.append(check_res) - return check_list + def software_has_documentation(self, url, branch_hash_or_tag): + report = self.execute(url, branch_hash_or_tag) + check = report["RSFC-05-3"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( + process=check["process"], + status_id=check["status"]["@id"], + output=check["output"], + evidence=check["evidence"], + success=success, + ) + + return check def requirements_specified(self, url, branch_hash_or_tag): report = self.execute(url, branch_hash_or_tag) - checks = report["checks"] - check_list = [] - - for check in checks: - if "requirements_specified" in check["assessesIndicator"]["@id"]: - if check["output"] == "true": - success = True - else: - success = False - - check_res = CheckResult( + check = report["RSFC-13-1"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( process=check["process"], status_id=check["status"]["@id"], output=check["output"], evidence=check["evidence"], success=success, ) - - check_list.append(check_res) - - return check_list + + return check def has_releases(self, url, branch_hash_or_tag): report = self.execute(url, branch_hash_or_tag) - checks = report["checks"] - check_list = [] - - for check in checks: - if "has_releases" in check["assessesIndicator"]["@id"]: - if check["output"] == "true": - success = True - else: - success = False - - check_res = CheckResult( + check = report["RSFC-03-1"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( process=check["process"], status_id=check["status"]["@id"], output=check["output"], evidence=check["evidence"], success=success, ) - - check_list.append(check_res) - - return check_list + + return check def software_has_license(self, url, branch_hash_or_tag): report = self.execute(url, branch_hash_or_tag) - checks = report["checks"] - check_list = [] - - for check in checks: - if "software_has_license" in check["assessesIndicator"]["@id"]: - if check["output"] == "true": - success = True - else: - success = False - - check_res = CheckResult( + check = report["RSFC-15-1"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( process=check["process"], status_id=check["status"]["@id"], output=check["output"], evidence=check["evidence"], success=success, ) - - check_list.append(check_res) - - return check_list + + return check def descriptive_metadata(self, url, branch_hash_or_tag): report = self.execute(url, branch_hash_or_tag) - checks = report["checks"] - check_list = [] - - for check in checks: - if "descriptive_metadata" in check["assessesIndicator"]["@id"]: - if check["output"] == "true": - success = True - else: - success = False - - check_res = CheckResult( + check = report["RSFC-04-4"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( process=check["process"], status_id=check["status"]["@id"], output=check["output"], evidence=check["evidence"], success=success, ) - - check_list.append(check_res) - - return check_list + + return check def versioning_standards_use(self, url, branch_hash_or_tag): report = self.execute(url, branch_hash_or_tag) - checks = report["checks"] - check_list = [] - - for check in checks: - if "versioning_standards_use" in check["assessesIndicator"]["@id"]: - if check["output"] == "true": - success = True - else: - success = False - - check_res = CheckResult( + check = report["RSFC-03-6"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( process=check["process"], status_id=check["status"]["@id"], output=check["output"], evidence=check["evidence"], success=success, ) - - check_list.append(check_res) - - return check_list + + return check def version_control_use(self, url, branch_hash_or_tag): report = self.execute(url, branch_hash_or_tag) - checks = report["checks"] - check_list = [] - - for check in checks: - if "version_control_use" in check["assessesIndicator"]["@id"]: - if check["output"] == "true": - success = True - else: - success = False - - check_res = CheckResult( + check = report["RSFC-09-1"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( process=check["process"], status_id=check["status"]["@id"], output=check["output"], evidence=check["evidence"], success=success, ) - - check_list.append(check_res) - - return check_list + + return check def software_has_tests(self, url, branch_hash_or_tag): report = self.execute(url, branch_hash_or_tag) - checks = report["checks"] - check_list = [] - - for check in checks: - if "software_tests" in check["assessesIndicator"]["@id"]: - if check["output"] == "true": - success = True - else: - success = False - - check_res = CheckResult( + check = report["RSFC-14-1"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( process=check["process"], status_id=check["status"]["@id"], output=check["output"], evidence=check["evidence"], success=success, ) - - check_list.append(check_res) - - return check_list + + return check def software_has_citation(self, url, branch_hash_or_tag): report = self.execute(url, branch_hash_or_tag) - checks = report["checks"] - check_list = [] - - for check in checks: - if "software_has_citation" in check["assessesIndicator"]["@id"]: - if check["output"] == "true": - success = True - else: - success = False - - check_res = CheckResult( + check = report["RSFC-18-1"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( process=check["process"], status_id=check["status"]["@id"], output=check["output"], evidence=check["evidence"], success=success, ) - - check_list.append(check_res) - - return check_list + + return check def repository_workflows(self, url, branch_hash_or_tag): report = self.execute(url, branch_hash_or_tag) - checks = report["checks"] - check_list = [] - - for check in checks: - if "repository_workflows" in check["assessesIndicator"]["@id"]: - if check["output"] == "true": - success = True - else: - success = False - - check_res = CheckResult( + check = report["RSFC-19-1"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( process=check["process"], status_id=check["status"]["@id"], output=check["output"], evidence=check["evidence"], success=success, ) - - check_list.append(check_res) - - return check_list + + return check def archived_in_software_heritage(self, url, branch_hash_or_tag): report = self.execute(url, branch_hash_or_tag) - checks = report["checks"] - check_list = [] - - for check in checks: - if "archived_in_software_heritage" in check["assessesIndicator"]["@id"]: - if check["output"] == "true": - success = True - else: - success = False - - check_res = CheckResult( + check = report["RSFC-08-1"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( process=check["process"], status_id=check["status"]["@id"], output=check["output"], evidence=check["evidence"], success=success, ) - - check_list.append(check_res) - - return check_list + + return check def has_contribution_guidelines(self, url, branch_hash_or_tag): report = self.execute(url, branch_hash_or_tag) - checks = report["checks"] - check_list = [] - - for check in checks: - if "has_contribution_guidelines" in check["assessesIndicator"]["@id"]: - if check["output"] == "true": - success = True - else: - success = False - - check_res = CheckResult( + check = report["RSFC-21-1"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( process=check["process"], status_id=check["status"]["@id"], output=check["output"], evidence=check["evidence"], success=success, ) + + return check - check_list.append(check_res) - - return check_list + def software_is_containerized(self, url, branch_hash_or_tag): + report = self.execute(url, branch_hash_or_tag) + check = report["RSFC-22-1"] + if check["output"] == "true": + success = True + else: + success = False + check = CheckResult( + process=check["process"], + status_id=check["status"]["@id"], + output=check["output"], + evidence=check["evidence"], + success=success, + ) + + return check \ No newline at end of file