pub(crate) struct AnonymousDefinition;
use crate::{
audit::AuditError,
finding::{Confidence, Persona, Severity, location::Locatable as _},
state::AuditState,
};
use super::{Audit, AuditLoadError, Job, audit_meta};
const ANONYMOUS_DEFINITION_WORKFLOW_SEVERITY: Severity = Severity::Low;
const ANONYMOUS_DEFINITION_JOB_SEVERITY: Severity = Severity::Informational;
audit_meta!(
AnonymousDefinition,
"anonymous-definition",
"workflow or action definition without a name"
);
#[async_trait::async_trait]
impl Audit for AnonymousDefinition {
fn new(_state: &AuditState) -> Result<Self, AuditLoadError> {
Ok(Self)
}
async fn audit_workflow<'doc>(
&self,
workflow: &'doc crate::models::workflow::Workflow,
_config: &crate::config::Config,
) -> Result<Vec<crate::finding::Finding<'doc>>, AuditError> {
let mut findings = vec![];
if workflow.name.is_none() {
findings.push(
Self::finding()
.severity(ANONYMOUS_DEFINITION_WORKFLOW_SEVERITY)
.confidence(Confidence::High)
.persona(Persona::Pedantic)
.add_location(workflow.location().primary())
.tip("use 'name: ...' to give this workflow a name")
.build(workflow)?,
);
}
for job in workflow.jobs() {
match job {
Job::NormalJob(normal) => {
if normal.name.is_none() {
findings.push(
Self::finding()
.severity(ANONYMOUS_DEFINITION_JOB_SEVERITY)
.confidence(Confidence::High)
.persona(Persona::Pedantic)
.add_location(normal.location_with_grip().primary())
.tip("use 'name: ...' to give this job a name")
.build(workflow)?,
);
}
}
_ => continue,
}
}
Ok(findings)
}
}