Skip to content

Rename validation profile to validation preset throughout #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ This is work-in-progress.
If you want to build `csaf-validator` on your own, please install Rust (see https://rustup.rs) and then run

```bash
# make sure, submodules are up-to-date
# make sure submodules are up-to-date
git submodule init
git submodule update --remote

# run the tests
Expand All @@ -35,7 +36,7 @@ Arguments:

Options:
-c, --csaf-version <CSAF_VERSION> Version of CSAF to use [default: 2.0]
-p, --profile <PROFILE> The profile to use [default: basic]
-p, --preset <PRESET> The validation preset (formerly known as "profile") to use [default: basic]
-o, --only-test <ONLY_TEST> Run only the selected test
-h, --help Print help
-V, --version Print version
Expand All @@ -48,7 +49,7 @@ Some examples to use are included below. Please note that the validation is not
csaf-validator --csaf-version 2.0 my-csaf-2-0-document.json

# validate a CSAF 2.0 document with profile full
csaf-validator --csaf-version 2.0 --profile full my-csaf-2-0-document.json
csaf-validator --csaf-version 2.0 --preset full my-csaf-2-0-document.json

# validate a CSAF 2.1 document with a specific test
csaf-validator --csaf-version 2.1 --only-test 6.1.34 my-csaf-2-1-document.json
Expand Down
2 changes: 1 addition & 1 deletion csaf
Submodule csaf updated 128 files
10 changes: 5 additions & 5 deletions csaf-lib/src/csaf/csaf2_0/validation.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use super::product_helper::*;
use super::schema::CommonSecurityAdvisoryFramework;
use crate::csaf::validation::{Test, Validatable, ValidationProfile};
use crate::csaf::validation::{Test, Validatable, ValidationPreset};
use std::collections::{HashMap, HashSet};
use crate::csaf::helpers::find_duplicates;

impl Validatable<CommonSecurityAdvisoryFramework> for CommonSecurityAdvisoryFramework {
fn profiles(&self) -> HashMap<ValidationProfile, Vec<&str>> {
fn presets(&self) -> HashMap<ValidationPreset, Vec<&str>> {
HashMap::from([
(ValidationProfile::Basic, Vec::from(["6.1.1", "6.1.2"])),
(ValidationProfile::Extended, Vec::from(["6.1.1", "6.1.2"])),
(ValidationProfile::Full, Vec::from(["6.1.1", "6.1.2"])),
(ValidationPreset::Basic, Vec::from(["6.1.1", "6.1.2"])),
(ValidationPreset::Extended, Vec::from(["6.1.1", "6.1.2"])),
(ValidationPreset::Full, Vec::from(["6.1.1", "6.1.2"])),
])
}

Expand Down
10 changes: 5 additions & 5 deletions csaf-lib/src/csaf/csaf2_1/validation.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use super::product_helper::*;
use super::schema::CommonSecurityAdvisoryFramework;
use crate::csaf::helpers::find_duplicates;
use crate::csaf::validation::{Test, Validatable, ValidationProfile};
use crate::csaf::validation::{Test, Validatable, ValidationPreset};
use std::collections::{HashMap, HashSet};

impl Validatable<CommonSecurityAdvisoryFramework> for CommonSecurityAdvisoryFramework {
fn profiles(&self) -> HashMap<ValidationProfile, Vec<&str>> {
fn presets(&self) -> HashMap<ValidationPreset, Vec<&str>> {
HashMap::from([
(
ValidationProfile::Basic,
ValidationPreset::Basic,
Vec::from(["6.1.1", "6.1.2", "6.1.34"]),
),
(ValidationProfile::Extended, Vec::from(["6.1.1", "6.1.2"])),
(ValidationProfile::Full, Vec::from(["6.1.1", "6.1.2"])),
(ValidationPreset::Extended, Vec::from(["6.1.1", "6.1.2"])),
(ValidationPreset::Full, Vec::from(["6.1.1", "6.1.2"])),
])
}

Expand Down
34 changes: 17 additions & 17 deletions csaf-lib/src/csaf/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,28 @@ use std::str::FromStr;
pub enum ValidationError {}

#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum ValidationProfile {
pub enum ValidationPreset {
Basic,
Extended,
Full,
}

impl FromStr for ValidationProfile {
impl FromStr for ValidationPreset {
type Err = ();

fn from_str(input: &str) -> Result<ValidationProfile, Self::Err> {
fn from_str(input: &str) -> Result<ValidationPreset, Self::Err> {
match input {
"basic" => Ok(ValidationProfile::Basic),
"extended" => Ok(ValidationProfile::Extended),
"full" => Ok(ValidationProfile::Full),
"basic" => Ok(ValidationPreset::Basic),
"extended" => Ok(ValidationPreset::Extended),
"full" => Ok(ValidationPreset::Full),
_ => Err(()),
}
}
}

pub trait Validate {
/// Validates this object according to a validation profile
fn validate_profile(&'static self, profile: ValidationProfile);
/// Validates this object according to a validation preset
fn validate_preset(&'static self, preset: ValidationPreset);

/// Validates this object according to a specific test ID.
fn validate_by_test(&self, version: &str);
Expand All @@ -38,35 +38,35 @@ pub type Test<VersionedDocument> =
/// This trait MUST be implemented by the struct that represents a CSAF document
/// in the respective version.
///
/// It can then be used to validate documents with either [validate_by_profile] or [validate_by_test].
/// It can then be used to validate documents with either [validate_by_preset] or [validate_by_test].
pub trait Validatable<VersionedDocument> {
/// Returns a hashmap containing the test ID per profile
fn profiles(&self) -> HashMap<ValidationProfile, Vec<&str>>;
/// Returns a hashmap containing the test ID per preset
fn presets(&self) -> HashMap<ValidationPreset, Vec<&str>>;

/// Returns a hashmap containing the test function per test ID
fn tests(&self) -> HashMap<&str, Test<VersionedDocument>>;

fn doc(&self) -> &VersionedDocument;
}

/// Executes all tests of the specified [profile] against the [target]
/// Executes all tests of the specified [preset] against the [target]
/// (which is of type [VersionedDocument], e.g. a CSAF 2.0 document).
pub fn validate_by_profile<VersionedDocument>(
pub fn validate_by_preset<VersionedDocument>(
target: &impl Validatable<VersionedDocument>,
profile: ValidationProfile,
preset: ValidationPreset,
) {
println!("Validating document with {:?} profile... \n", profile);
println!("Validating document with {:?} preset... \n", preset);

// Loop through tests
if let Some(tests) = target.profiles().get(&profile) {
if let Some(tests) = target.presets().get(&preset) {
for test_id in tests {
println!("Executing Test {}... ", test_id);
validate_by_test(target, test_id);

println!()
}
} else {
println!("No tests found for profile")
println!("No tests found for preset")
}
}

Expand Down
16 changes: 10 additions & 6 deletions csaf-validator/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::str::FromStr;
use anyhow::{bail, Result};
use csaf_lib::csaf::csaf2_0::loader::load_document as load_document_2_0;
use csaf_lib::csaf::csaf2_1::loader::load_document as load_document_2_1;
use csaf_lib::csaf::validation::{validate_by_profile, validate_by_test, ValidationProfile};
use csaf_lib::csaf::validation::{validate_by_preset, validate_by_test, ValidationPreset};
use clap::Parser;

/// A validator for CSAF documents
Expand All @@ -15,9 +16,9 @@ struct Args {
#[arg(short, long, default_value = "2.0")]
csaf_version: String,

/// The profile to use
/// The validation preset (formerly known as "profile") to use
#[arg(short, long, default_value = "basic")]
profile: String,
preset: String,

/// Run only the selected test
#[arg(short, long)]
Expand All @@ -26,7 +27,10 @@ struct Args {

fn main() -> Result<()> {
let args = Args::parse();
let profile = ValidationProfile::Basic;
let preset = match ValidationPreset::from_str(args.preset.as_str()) {
Ok(preset) => preset,
Err(_) => bail!(format!("Invalid validation preset: {}", args.preset)),
};

// TODO: it would be nice to return the validatable from this match, but this is beyond my
// rust generics knowledge, so a little bit of duplicate code here
Expand All @@ -45,10 +49,10 @@ fn main() -> Result<()> {
} else {
let result = match args.csaf_version.as_str() {
"2.0" => {
validate_by_profile(&load_document_2_0(args.path.as_str())?, profile)
validate_by_preset(&load_document_2_0(args.path.as_str())?, preset)
}
"2.1" => {
validate_by_profile(&load_document_2_1(args.path.as_str())?, profile)
validate_by_preset(&load_document_2_1(args.path.as_str())?, preset)
}
_ => bail!("invalid version"),
};
Expand Down