Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
50 changes: 28 additions & 22 deletions modules/ingestor/src/graph/sbom/clearly_defined.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,61 @@
use crate::graph::purl::creator::PurlCreator;
use crate::graph::sbom::{LicenseCreator, LicenseInfo, SbomContext, SbomInformation};
use sea_orm::ConnectionTrait;
use sea_orm::{ConnectionTrait, EntityTrait, Set};
use sea_query::OnConflict;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use tracing::instrument;
use trustify_common::purl::Purl;
use trustify_entity::sbom_package_license;
use uuid::Uuid;

const CLEARLY_DEFINED_CURATION: &str = "ClearlyDefinedCuration";

impl SbomContext {
#[instrument(skip(db, curation), err)]
pub async fn ingest_clearly_defined_curation<C: ConnectionTrait>(
&self,
curation: Curation,
db: &C,
sbom_id: Uuid,
) -> Result<(), anyhow::Error> {
let mut purls = PurlCreator::new();
let mut licenses = LicenseCreator::new();

// TODO: Since the node id cannot be obtained here, it’s not possible to replace purl_license_assertion with sbom_package_license.
// let mut assertions = Vec::new();
let mut sbom_package_license_list = Vec::new();

for (purl, license) in curation.iter() {
let license_info = LicenseInfo {
license: license.clone(),
};

// assertions.push(purl_license_assertion::ActiveModel {
// id: Default::default(),
// license_id: Set(license_info.uuid()),
// versioned_purl_id: Set(purl.version_uuid()),
// sbom_id: Set(self.sbom.sbom_id),
// });
sbom_package_license_list.push(sbom_package_license::ActiveModel {
sbom_id: Set(self.sbom.sbom_id),
node_id: Set(CLEARLY_DEFINED_CURATION.to_string()),
license_id: Set(license_info.uuid()),
license_type: Set(sbom_package_license::LicenseCategory::Declared),
});

purls.add(purl);
licenses.add(&license_info);
}
purls.create(db).await?;
licenses.create(db).await?;

// purl_license_assertion::Entity::insert_many(assertions)
// .on_conflict(
// OnConflict::columns([
// purl_license_assertion::Column::SbomId,
// purl_license_assertion::Column::LicenseId,
// purl_license_assertion::Column::VersionedPurlId,
// ])
// .do_nothing()
// .to_owned(),
// )
// .do_nothing()
// .exec(db)
// .await?;
sbom_package_license::Entity::insert_many(sbom_package_license_list)
.on_conflict(
OnConflict::columns([
sbom_package_license::Column::SbomId,
sbom_package_license::Column::NodeId,
sbom_package_license::Column::LicenseId,
sbom_package_license::Column::LicenseType,
])
.do_nothing()
.to_owned(),
)
.do_nothing()
.exec(db)
.await?;

Ok(())
}
Expand Down
31 changes: 29 additions & 2 deletions modules/ingestor/src/service/sbom/clearly_defined.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,19 @@ mod test {
use crate::graph::Graph;
use crate::service::{Cache, Error, Format, IngestorService};
use anyhow::anyhow;
use sea_orm::{EntityTrait, FromQueryResult, QuerySelect, RelationTrait};
use sea_query::JoinType;
use test_context::test_context;
use test_log::test;
use trustify_common::purl::Purl;
use trustify_test_context::TrustifyContext;
use trustify_test_context::document_bytes;
use trustify_entity::{license, sbom_package_license};
use trustify_test_context::{TrustifyContext, document_bytes};

#[derive(Debug, FromQueryResult)]
struct PackageLicenseInfo {
pub node_id: String,
pub license_expression: String,
}

fn coordinates_to_purl(coords: &str) -> Result<Purl, Error> {
let parts = coords.split('/').collect::<Vec<_>>();
Expand Down Expand Up @@ -179,6 +187,25 @@ mod test {
.await
.expect("must ingest");

let result: Vec<PackageLicenseInfo> = sbom_package_license::Entity::find()
.join(
JoinType::Join,
sbom_package_license::Relation::License.def(),
)
.select_only()
.column_as(sbom_package_license::Column::NodeId, "node_id")
.column_as(license::Column::Text, "license_expression")
.into_model::<PackageLicenseInfo>()
.all(&ctx.db)
.await?;

assert_eq!(1, result.len());
assert_eq!("OTHER", result[0].license_expression);
assert_eq!(
"nuget/nuget/-/microsoft.aspnet.mvc/4.0.40804",
result[0].node_id
);

Ok(())
}
}
38 changes: 28 additions & 10 deletions modules/ingestor/src/service/sbom/clearly_defined_curation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,15 @@ impl<'g> ClearlyDefinedCurationLoader<'g> {
) -> Result<IngestResult, Error> {
let tx = self.graph.db.begin().await?;

let document_id = curation.document_id().clone();
let sbom = match self
.graph
.ingest_sbom(
labels,
digests,
Some(curation.document_id()),
&curation,
&tx,
)
.ingest_sbom(labels, digests, Some(document_id.clone()), &curation, &tx)
.await?
{
Outcome::Existed(sbom) => sbom,
Outcome::Added(sbom) => {
sbom.ingest_clearly_defined_curation(curation, &tx)
sbom.ingest_clearly_defined_curation(curation, &tx, sbom.sbom.sbom_id)
.await
.map_err(Error::Generic)?;

Expand All @@ -61,10 +56,17 @@ impl<'g> ClearlyDefinedCurationLoader<'g> {
mod test {
use crate::graph::Graph;
use crate::service::{Cache, Format, IngestorService};
use sea_orm::{EntityTrait, FromQueryResult, QuerySelect, RelationTrait};
use sea_query::JoinType;
use test_context::test_context;
use test_log::test;
use trustify_test_context::TrustifyContext;
use trustify_test_context::document_bytes;
use trustify_entity::{license, sbom_package_license};
use trustify_test_context::{TrustifyContext, document_bytes};
#[derive(Debug, FromQueryResult)]
struct PackageLicenseInfo {
pub node_id: String,
pub license_expression: String,
}

#[test_context(TrustifyContext)]
#[test(tokio::test)]
Expand All @@ -85,6 +87,22 @@ mod test {
.await
.expect("must ingest");

let result: Vec<PackageLicenseInfo> = sbom_package_license::Entity::find()
.join(
JoinType::Join,
sbom_package_license::Relation::License.def(),
)
.select_only()
.column_as(sbom_package_license::Column::NodeId, "node_id")
.column_as(license::Column::Text, "license_expression")
.into_model::<PackageLicenseInfo>()
.all(&ctx.db)
.await?;

assert_eq!(1, result.len());
assert_eq!("Apache-2.0 OR MIT", result[0].license_expression);
assert_eq!("ClearlyDefinedCuration", result[0].node_id);

Ok(())
}
}
Loading