///|
pub(all) struct SarifOptions {
tool_name : String
tool_version : String
repository_uri : String
include_help : Bool
} derive(Eq, Debug, ToJson)
///|
pub(all) struct SarifTool {
name : String
version : String
information_uri : String
} derive(Eq, Debug, ToJson)
///|
pub(all) struct SarifDriver {
name : String
version : String
information_uri : String
rules : Array[SarifRule]
} derive(Eq, Debug, ToJson)
///|
pub(all) struct SarifRule {
id : String
name : String
short_description : String
help_uri : String
} derive(Eq, Debug, ToJson)
///|
pub(all) struct SarifArtifactLocation {
uri : String
} derive(Eq, Debug, ToJson)
///|
pub(all) struct SarifLocation {
artifact_location : SarifArtifactLocation
logical_regions : Array[SarifRegion]
} derive(Eq, Debug, ToJson)
///|
pub(all) struct SarifRegion {
start_line : Int
start_column : Int
} derive(Eq, Debug, ToJson)
///|
pub(all) struct SarifMessage {
text : String
} derive(Eq, Debug, ToJson)
///|
pub(all) struct SarifResult {
rule_id : String
level : String
message : SarifMessage
locations : Array[SarifLocation]
fingerprints : Map[String, String]
} derive(Eq, Debug, ToJson)
///|
pub(all) struct SarifRun {
tool : SarifToolWrapper
results : Array[SarifResult]
} derive(Eq, Debug, ToJson)
///|
pub(all) struct SarifToolWrapper {
driver : SarifDriver
} derive(Eq, Debug, ToJson)
///|
pub(all) struct SarifReport {
version : String
schema : String
runs : Array[SarifRun]
} derive(Eq, Debug, ToJson)
///|
pub fn default_sarif_options() -> SarifOptions {
{
tool_name: "MoonTrustFlow",
tool_version: "0.1.1",
repository_uri: "https://github.com/lllg123/MoonTrustFlow-MoonBit",
include_help: true,
}
}
///|
pub fn format_sarif(findings : Array[Finding]) -> String {
format_sarif_with_options(findings, default_sarif_options())
}
///|
pub fn format_sarif_with_options(
findings : Array[Finding],
options : SarifOptions,
) -> String {
let rules = sarif_rules(findings, options)
let results = sarif_results(findings, options)
let driver : SarifDriver = {
name: options.tool_name,
version: options.tool_version,
information_uri: options.repository_uri,
rules,
}
let report : SarifReport = {
version: "2.1.0",
schema: "https://json.schemastore.org/sarif-2.1.0.json",
runs: [{ tool: { driver, }, results }],
}
report.to_json().stringify(indent=2)
}
///|
fn sarif_rules(
findings : Array[Finding],
options : SarifOptions,
) -> Array[SarifRule] {
let ids : Array[String] = []
let rules : Array[SarifRule] = []
for finding in findings {
let id = sarif_rule_id(finding)
if !ids.contains(id) {
ids.push(id)
rules.push({
id,
name: sarif_rule_name(finding),
short_description: sarif_rule_name(finding),
help_uri: if options.include_help {
options.repository_uri + "#public-api"
} else {
""
},
})
}
}
rules
}
///|
fn sarif_results(
findings : Array[Finding],
options : SarifOptions,
) -> Array[SarifResult] {
let results : Array[SarifResult] = []
for finding in findings {
let rule_id = sarif_rule_id(finding)
let explanation = explain_finding(finding)
results.push({
rule_id,
level: sarif_level(finding.severity),
message: {
text: if options.include_help {
format_finding(finding) + " | " + explanation.summary
} else {
format_finding(finding)
},
},
locations: [
{
artifact_location: { uri: "model.mtf" },
logical_regions: [{ start_line: 1, start_column: 1 }],
},
],
fingerprints: { "moontrustflow/path": finding.path.join("->") },
})
}
results
}
///|
fn sarif_rule_id(finding : Finding) -> String {
"moontrustflow/\{finding.rule}-\{finding.severity}"
}
///|
fn sarif_rule_name(finding : Finding) -> String {
if finding.rule == "deny" {
"Forbidden trust-flow route"
} else if finding.rule == "require" {
"Missing required control point"
} else {
"Trust-flow policy finding"
}
}
///|
fn sarif_level(severity : String) -> String {
if severity == "high" {
"error"
} else if severity == "medium" {
"warning"
} else {
"note"
}
}