def report( tool_name, tool_args, working_dir, metrics, skips, issues, crep_fname, file_path_list=None, ): """Prints issues in SARIF format :param tool_name: tool name :param tool_args: Args used for the tool :param working_dir: Working directory :param metrics: metrics data :param skips: skips data :param issues: issues data :param crep_fname: The output file name :param file_path_list: Full file path for any manipulation :return serialized_log: SARIF output data """ if not tool_args: tool_args = [] tool_args_str = tool_args if isinstance(tool_args, list): tool_args_str = " ".join(tool_args) repo_details = find_repo_details(working_dir) log_uuid = str(uuid.uuid4()) run_uuid = config.get("run_uuid") # Populate metrics metrics = { "total": 0, "critical": 0, "high": 0, "medium": 0, "low": 0, } total = 0 for issue in issues: issue_dict = issue_from_dict(issue).as_dict() rule_id = issue_dict.get("test_id") # Is this rule ignored globally? if rule_id in config.ignored_rules: continue total += 1 issue_severity = issue_dict["issue_severity"] # Fix up severity for certain tools issue_severity = tweak_severity(tool_name, issue_dict) key = issue_severity.lower() if not metrics.get(key): metrics[key] = 0 metrics[key] += 1 metrics["total"] = total # working directory to use in the log WORKSPACE_PREFIX = config.get("WORKSPACE", None) wd_dir_log = WORKSPACE_PREFIX if WORKSPACE_PREFIX is not None else working_dir driver_name = config.tool_purpose_message.get(tool_name, tool_name) if tool_name != "inspect" and config.get("CI") or config.get( "GITHUB_ACTIONS"): driver_name = "ShiftLeft " + driver_name # Construct SARIF log log = om.SarifLog( schema_uri= "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", version="2.1.0", inline_external_properties=[ om.ExternalProperties(guid=log_uuid, run_guid=run_uuid) ], runs=[ om.Run( automation_details=om.RunAutomationDetails( guid=log_uuid, description=om.Message( text= "Static Analysis Security Test results using @ShiftLeft/sast-scan" ), ), tool=om.Tool(driver=om.ToolComponent(name=driver_name)), invocations=[ om.Invocation( end_time_utc=datetime.datetime.utcnow().strftime( TS_FORMAT), execution_successful=True, working_directory=om.ArtifactLocation( uri=to_uri(wd_dir_log)), ) ], conversion={ "tool": om.Tool(driver=om.ToolComponent( name="@ShiftLeft/sast-scan")), "invocation": om.Invocation( execution_successful=True, command_line=tool_args_str, arguments=tool_args, working_directory=om.ArtifactLocation( uri=to_uri(wd_dir_log)), end_time_utc=datetime.datetime.utcnow().strftime( TS_FORMAT), ), }, properties={"metrics": metrics}, version_control_provenance=[ om.VersionControlDetails( repository_uri=repo_details["repositoryUri"], branch=repo_details["branch"], revision_id=repo_details["revisionId"], ) ], ) ], ) run = log.runs[0] invocation = run.invocations[0] add_skipped_file_notifications(skips, invocation) add_results(tool_name, issues, run, file_path_list, working_dir) serialized_log = to_json(log) if crep_fname: html_file = crep_fname.replace(".sarif", ".html") with io.open(crep_fname, "w") as fileobj: fileobj.write(serialized_log) render_html(json.loads(serialized_log), html_file) if fileobj.name != sys.stdout.name: LOG.debug( "SARIF and HTML report written to file: %s, %s 👍", fileobj.name, html_file, ) return serialized_log
def report( tool_name, tool_args, working_dir, metrics, skips, issues, crep_fname, file_path_list=None, ): """Prints issues in SARIF format :param tool_name: tool name :param tool_args: Args used for the tool :param working_dir: Working directory :param metrics: metrics data :param skips: skips data :param issues: issues data :param crep_fname: The output file name :param file_path_list: Full file path for any manipulation :return serialized_log: SARIF output data """ if not tool_args: tool_args = [] tool_args_str = tool_args if isinstance(tool_args, list): tool_args_str = " ".join(tool_args) repo_details = find_repo_details(working_dir) log_uuid = str(uuid.uuid4()) run_uuid = config.get("run_uuid") # working directory to use in the log WORKSPACE_PREFIX = config.get("WORKSPACE", None) wd_dir_log = WORKSPACE_PREFIX if WORKSPACE_PREFIX is not None else working_dir driver_name = config.tool_purpose_message.get(tool_name, tool_name) # Construct SARIF log log = om.SarifLog( schema_uri="https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", version="2.1.0", inline_external_properties=[ om.ExternalProperties(guid=log_uuid, run_guid=run_uuid) ], runs=[ om.Run( automation_details=om.RunAutomationDetails( guid=log_uuid, description=om.Message( text="Static Analysis Security Test results using @ShiftLeft/sast-scan" ), ), tool=om.Tool( driver=om.ToolComponent( name=driver_name, full_name=driver_name, version="1.0.0-scan" ) ), invocations=[ om.Invocation( end_time_utc=datetime.datetime.utcnow().strftime(TS_FORMAT), execution_successful=True, working_directory=om.ArtifactLocation(uri=to_uri(wd_dir_log)), ) ], conversion={ "tool": om.Tool( driver=om.ToolComponent(name="@ShiftLeft/sast-scan") ), "invocation": om.Invocation( execution_successful=True, command_line=tool_args_str, arguments=tool_args, working_directory=om.ArtifactLocation(uri=to_uri(wd_dir_log)), end_time_utc=datetime.datetime.utcnow().strftime(TS_FORMAT), ), }, version_control_provenance=[ om.VersionControlDetails( repository_uri=repo_details["repositoryUri"], branch=repo_details["branch"], revision_id=repo_details["revisionId"], ) ], ) ], ) run = log.runs[0] invocation = run.invocations[0] add_skipped_file_notifications(skips, invocation) add_results(tool_name, issues, run, file_path_list, working_dir) serialized_log = to_json(log) if crep_fname: html_file = crep_fname.replace(".sarif", ".html") with io.open(crep_fname, "w") as fileobj: fileobj.write(serialized_log) if tool_name != "empty-scan": render_html(json.loads(serialized_log), html_file) if fileobj.name != sys.stdout.name: LOG.debug( "SARIF and HTML report written to file: %s, %s :thumbsup:", fileobj.name, html_file, ) return serialized_log
def test_pmd_render(test_pmd_sarif_file): report_data = parse(test_pmd_sarif_file) with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=True) as hfile: html_content = render_html(report_data, hfile.name) assert "{{" not in html_content