diff --git a/Cargo.lock b/Cargo.lock index 84432e5..552338e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,7 +30,7 @@ dependencies = [ "actix-service", "actix-utils", "ahash", - "base64", + "base64 0.21.7", "bitflags 2.4.1", "brotli", "bytes", @@ -39,8 +39,8 @@ dependencies = [ "encoding_rs", "flate2", "futures-core", - "h2", - "http", + "h2 0.3.22", + "http 0.2.11", "httparse", "httpdate", "itoa", @@ -75,7 +75,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d22475596539443685426b6bdadb926ad0ecaefdfc5fb05e5e3441f15463c511" dependencies = [ "bytestring", - "http", + "http 0.2.11", "regex", "serde", "tracing", @@ -384,6 +384,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + [[package]] name = "basic-toml" version = "0.1.9" @@ -961,7 +967,26 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.11", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 1.1.0", "indexmap", "slab", "tokio", @@ -1007,6 +1032,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.5" @@ -1014,7 +1050,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", - "http", + "http 0.2.11", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -1055,9 +1114,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.22", + "http 0.2.11", + "http-body 0.4.5", "httparse", "httpdate", "itoa", @@ -1069,6 +1128,26 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.4", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -1076,8 +1155,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.11", + "hyper 0.14.27", "log", "rustls", "rustls-native-certs", @@ -1091,7 +1170,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper", + "hyper 0.14.27", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -1104,10 +1183,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.27", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.2.0", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.2.0", + "pin-project-lite", + "socket2 0.5.5", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -1233,7 +1348,7 @@ version = "9.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c7ea04a7c5c055c175f189b6dc6ba036fd62306b58c66c9f6389036c503a3f4" dependencies = [ - "base64", + "base64 0.21.7", "js-sys", "pem", "ring 0.17.6", @@ -1484,16 +1599,16 @@ checksum = "abfeeafb5fa0da7046229ec3c7b3bd2981aae05c549871192c408d59fc0fffd5" dependencies = [ "arc-swap", "async-trait", - "base64", + "base64 0.21.7", "bytes", "cfg-if", "chrono", "either", "futures", "futures-util", - "http", - "http-body", - "hyper", + "http 0.2.11", + "http-body 0.4.5", + "hyper 0.14.27", "hyper-rustls", "hyper-timeout", "jsonwebtoken", @@ -1521,16 +1636,16 @@ checksum = "054a8bf47dfa8f89bb0dcf17e485e9f49f2586c05bf0aa67b8ec5a9e7bc8dfd5" dependencies = [ "arc-swap", "async-trait", - "base64", + "base64 0.21.7", "bytes", "cfg-if", "chrono", "either", "futures", "futures-util", - "http", - "http-body", - "hyper", + "http 0.2.11", + "http-body 0.4.5", + "hyper 0.14.27", "hyper-rustls", "hyper-timeout", "jsonwebtoken", @@ -1728,7 +1843,7 @@ version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3163d2912b7c3b52d651a055f2c7eec9ba5cd22d26ef75b8dd3a59980b185923" dependencies = [ - "base64", + "base64 0.21.7", "serde", ] @@ -1986,16 +2101,58 @@ version = "0.11.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" dependencies = [ - "base64", + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.22", + "http 0.2.11", + "http-body 0.4.5", + "hyper 0.14.27", + "hyper-tls 0.5.0", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.50.0", +] + +[[package]] +name = "reqwest" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e6cc1e89e689536eb5aeede61520e874df5a4707df811cd5da4aa5fbb2aae19" +dependencies = [ + "base64 0.22.0", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", + "h2 0.4.4", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.2.0", + "hyper-tls 0.6.0", + "hyper-util", "ipnet", "js-sys", "log", @@ -2004,7 +2161,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", + "rustls-pemfile 2.1.2", "serde", "serde_json", "serde_urlencoded", @@ -2017,7 +2174,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", + "winreg 0.52.0", ] [[package]] @@ -2137,7 +2294,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "schannel", "security-framework", ] @@ -2148,9 +2305,25 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64", + "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.0", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -2434,7 +2607,7 @@ dependencies = [ name = "skootrs-bin" version = "0.1.0" dependencies = [ - "base64", + "base64 0.21.7", "clap", "clap_mangen", "clio", @@ -2443,7 +2616,7 @@ dependencies = [ "opentelemetry", "opentelemetry-jaeger", "opentelemetry_sdk", - "reqwest", + "reqwest 0.11.24", "serde", "serde_json", "serde_yaml", @@ -2464,10 +2637,11 @@ name = "skootrs-lib" version = "0.1.0" dependencies = [ "askama", - "base64", + "base64 0.21.7", "chrono", "futures", "octocrab 0.33.3", + "reqwest 0.12.3", "schemars", "serde", "serde_json", @@ -2533,9 +2707,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "snafu" @@ -2901,8 +3075,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 0.2.11", + "http-body 0.4.5", "http-range-header", "iri-string", "pin-project-lite", @@ -3584,6 +3758,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "zerocopy" version = "0.7.32" diff --git a/skootrs-bin/src/helpers.rs b/skootrs-bin/src/helpers.rs index 4d083f6..c0b03b9 100644 --- a/skootrs-bin/src/helpers.rs +++ b/skootrs-bin/src/helpers.rs @@ -1,19 +1,19 @@ -use base64::prelude::*; use inquire::Text; use octocrab::Page; use serde::Serialize; use skootrs_lib::service::{project::ProjectService, source::LocalSourceService}; -use skootrs_model::{ - security_insights::insights10::SecurityInsightsVersion100YamlSchema, - skootrs::{ - facet::InitializedFacet, Config, EcosystemInitializeParams, FacetGetParams, FacetMapKey, - GithubRepoParams, GithubUser, GoParams, InitializedProject, MavenParams, - ProjectArchiveParams, ProjectCreateParams, ProjectGetParams, ProjectOutputParams, - ProjectOutputReference, ProjectOutputType, ProjectOutputsListParams, ProjectReleaseParam, - RepoCreateParams, SkootError, SourceInitializeParams, SupportedEcosystems, - }, +use skootrs_model::skootrs::{ + facet::InitializedFacet, Config, EcosystemInitializeParams, FacetGetParams, FacetMapKey, + GithubRepoParams, GithubUser, GoParams, InitializedProject, MavenParams, ProjectArchiveParams, + ProjectCreateParams, ProjectGetParams, ProjectOutput, ProjectOutputGetParams, + ProjectOutputReference, ProjectOutputType, ProjectOutputsListParams, ProjectReleaseParam, + RepoCreateParams, SkootError, SourceInitializeParams, SupportedEcosystems, +}; +use std::{ + collections::{HashMap, HashSet}, + io::Write, + str::FromStr, }; -use std::{collections::HashSet, io::Write, str::FromStr}; use strum::VariantNames; use tracing::debug; @@ -280,18 +280,15 @@ impl Output { /// Returns an error if the project output can't be fetched from a project release. pub async fn get<'a, T: ProjectService + ?Sized>( config: &Config, - _project_service: &'a T, - project_output_params: Option, - ) -> Result { + project_service: &'a T, + project_output_params: Option, + ) -> Result { let project_output_params = match project_output_params { Some(p) => p, - None => Output::prompt_project_output(config).await?, + None => Output::prompt_output_get(config, project_service).await?, }; - let output = reqwest::get(project_output_params.project_output) - .await? - .text() - .await?; + let output = project_service.output_get(project_output_params).await?; Ok(output) } @@ -319,71 +316,48 @@ impl Output { Ok(output_list) } - async fn prompt_project_output(config: &Config) -> Result { - let projects = Project::list(config).await?; - let selected_project = - inquire::Select::new("Select a project", projects.iter().collect()).prompt()?; - let selected_output_type = - inquire::Select::new("Select an output type", vec!["SBOM"]).prompt()?; - // TODO: This should probably be passed in by the config? - let mut cache = InMemoryProjectReferenceCache::load_or_create("./skootcache")?; - let project = cache.get(selected_project.clone()).await?; - - let selected_output = match selected_output_type { - "SBOM" => { - let skootrs_model::skootrs::InitializedRepo::Github(repo) = &project.repo; - let sec_ins_content_items = octocrab::instance() - .repos(repo.organization.get_name(), &repo.name) - .get_content() - .path("SECURITY-INSIGHTS.yml") - .r#ref("main") - .send() - .await?; - - let sec_ins = sec_ins_content_items - .items - .first() - .ok_or_else(|| SkootError::from("Failed to get security insights"))?; - - let content = sec_ins.content.as_ref().ok_or_else(|| { - SkootError::from("Failed to get content of security insights") - })?; - let content_decoded = - base64::engine::general_purpose::STANDARD.decode(content.replace('\n', ""))?; - let content_str = std::str::from_utf8(&content_decoded)?; - let insights: SecurityInsightsVersion100YamlSchema = - serde_yaml::from_str::(content_str)?; - let sbom_vec = insights - .dependencies - .ok_or_else(|| { - SkootError::from("Failed to get dependencies value from security insights") - })? - .sbom - .ok_or_else(|| { - SkootError::from("Failed to get sbom value from security insights") - })?; - - let sbom_files: Vec = sbom_vec - .iter() - .filter_map(|s| s.sbom_file.clone()) - .collect(); - - inquire::Select::new("Select an SBOM", sbom_files).prompt()? - } - _ => { - unimplemented!() - } - }; - - let selected_output_type_enum = match selected_output_type { - "SBOM" => ProjectOutputType::SBOM, - _ => ProjectOutputType::Custom("Other".to_string()), + async fn prompt_output_get<'a, T: ProjectService + ?Sized>( + config: &Config, + project_service: &'a T, + ) -> Result { + let selected_project = Project::get(config, project_service, None).await?; + let project_output_list_params = ProjectOutputsListParams { + initialized_project: selected_project.clone(), + // TODO: This should be a prompt. + release: ProjectReleaseParam::Latest, }; - - Ok(ProjectOutputParams { - project_url: selected_project.clone(), - project_output_type: selected_output_type_enum, + let output_list = + Output::list(config, project_service, Some(project_output_list_params)).await?; + let type_output_map: HashMap> = output_list + .iter() + .map(|o| (o.output_type.to_string(), o.name.clone())) + .fold( + HashMap::new(), + |mut acc: HashMap>, (key, value)| { + acc.entry(key).or_default().push(value); + acc + }, + ); + let selected_output_type = inquire::Select::new( + "Select an output type", + type_output_map.keys().cloned().collect(), + ) + .prompt()?; + let select_output_type_enum = ProjectOutputType::from_str(&selected_output_type)?; + let selected_output = inquire::Select::new( + "Select an output", + type_output_map + .get(&selected_output_type) + .ok_or_else(|| SkootError::from("Failed to get output type"))? + .clone(), + ) + .prompt()?; + Ok(ProjectOutputGetParams { + initialized_project: selected_project.clone(), + project_output_type: select_output_type_enum, project_output: selected_output.clone(), + // TODO: This should be selectable + release: ProjectReleaseParam::Latest, }) } } diff --git a/skootrs-lib/Cargo.toml b/skootrs-lib/Cargo.toml index d15b14b..efb74bb 100644 --- a/skootrs-lib/Cargo.toml +++ b/skootrs-lib/Cargo.toml @@ -20,6 +20,7 @@ skootrs-model = { path = "../skootrs-model" } sha2 = "0.10.8" url = "2.5.0" base64 = "0.21.7" +reqwest = "0.12.3" [dev-dependencies] tempdir = "0.3.7" diff --git a/skootrs-lib/src/service/output.rs b/skootrs-lib/src/service/output.rs index b0b0839..3ad6f41 100644 --- a/skootrs-lib/src/service/output.rs +++ b/skootrs-lib/src/service/output.rs @@ -17,20 +17,25 @@ use octocrab::models::repos::{Asset, Release}; use skootrs_model::skootrs::{ - ProjectOutputReference, ProjectOutputType, ProjectOutputsListParams, SkootError, + ProjectOutput, ProjectOutputGetParams, ProjectOutputReference, ProjectOutputType, + ProjectOutputsListParams, SkootError, }; - pub trait OutputService { - fn outputs_list( + fn list( &self, params: ProjectOutputsListParams, ) -> impl std::future::Future, SkootError>> + Send; + + fn get( + &self, + _params: ProjectOutputGetParams, + ) -> impl std::future::Future> + Send; } pub struct LocalOutputService; impl OutputService for LocalOutputService { - fn outputs_list( + fn list( &self, params: ProjectOutputsListParams, ) -> impl std::future::Future, SkootError>> + Send @@ -46,6 +51,23 @@ impl OutputService for LocalOutputService { } } } + + async fn get(&self, params: ProjectOutputGetParams) -> Result { + match params.initialized_project.repo { + skootrs_model::skootrs::InitializedRepo::Github(g) => { + let github_params = GithubOutputGetParams { + release: GithubReleaseHandler::get_release(GithubReleaseParams { + owner: g.organization.get_name(), + repo: g.name.clone(), + tag: params.release.tag(), + }) + .await?, + name: params.project_output, + }; + GithubReleaseHandler::get_output(github_params).await + } + } + } } struct GithubReleaseHandler; @@ -92,10 +114,35 @@ impl GithubReleaseHandler { // Follows: https://github.com/ossf/sbom-everywhere/blob/main/reference/sbom_naming.md _ if asset.name.contains(".spdx.") => ProjectOutputType::SBOM, _ if asset.name.contains(".cdx.") => ProjectOutputType::SBOM, + _ if asset.name.contains(".intoto.") => ProjectOutputType::InToto, // TODO: Add more types _ => ProjectOutputType::Custom("Unknown".to_string()), } } + + async fn get_output(params: GithubOutputGetParams) -> Result { + let asset = params + .release + .assets + .iter() + .find(|a| a.name == params.name) + .ok_or("Asset not found".to_string())?; + + // TODO: Figure out how to support assets in private repos + let content = reqwest::get(asset.browser_download_url.clone()) + .await + .map_err(|e| e.to_string())? + .text() + .await?; + + Ok(ProjectOutput { + reference: ProjectOutputReference { + name: asset.name.clone(), + output_type: Self::get_type(asset), + }, + output: serde_json::to_string_pretty(&content)?, + }) + } } struct GithubReleaseParams { @@ -103,3 +150,8 @@ struct GithubReleaseParams { repo: String, tag: Option, } + +struct GithubOutputGetParams { + release: Release, + name: String, +} diff --git a/skootrs-lib/src/service/project.rs b/skootrs-lib/src/service/project.rs index 7129d3a..0ef2ec7 100644 --- a/skootrs-lib/src/service/project.rs +++ b/skootrs-lib/src/service/project.rs @@ -22,8 +22,8 @@ use crate::service::facet::{FacetSetParamsGenerator, RootFacetService}; use skootrs_model::skootrs::{ facet::{CommonFacetCreateParams, InitializedFacet, SourceFile}, FacetGetParams, FacetMapKey, InitializedProject, InitializedSource, ProjectArchiveParams, - ProjectCreateParams, ProjectGetParams, ProjectOutputReference, ProjectOutputsListParams, - SkootError, + ProjectCreateParams, ProjectGetParams, ProjectOutput, ProjectOutputGetParams, + ProjectOutputReference, ProjectOutputsListParams, SkootError, }; use super::{ @@ -83,6 +83,11 @@ pub trait ProjectService { params: ProjectOutputsListParams, ) -> impl std::future::Future, SkootError>> + Send; + fn output_get( + &self, + _params: ProjectOutputGetParams, + ) -> impl std::future::Future> + Send; + /// Archives an initialized project. /// /// # Errors @@ -255,13 +260,20 @@ where &self, params: ProjectOutputsListParams, ) -> Result, SkootError> { - self.output_service.outputs_list(params).await + self.output_service.list(params).await } async fn list_facets(&self, params: ProjectGetParams) -> Result, SkootError> { Ok(self.get(params).await?.facets.keys().cloned().collect()) } + async fn output_get( + &self, + params: ProjectOutputGetParams, + ) -> Result { + self.output_service.get(params).await + } + async fn archive(&self, params: ProjectArchiveParams) -> Result { self.repo_service .archive(params.initialized_project.repo) @@ -539,7 +551,7 @@ mod tests { } impl OutputService for MockOutputService { - async fn outputs_list( + async fn list( &self, _params: ProjectOutputsListParams, ) -> Result, SkootError> { @@ -548,6 +560,19 @@ mod tests { output_type: ProjectOutputType::SBOM, }]) } + + async fn get( + &self, + _params: skootrs_model::skootrs::ProjectOutputGetParams, + ) -> Result { + Ok(skootrs_model::skootrs::ProjectOutput { + reference: ProjectOutputReference { + name: "test".into(), + output_type: ProjectOutputType::SBOM, + }, + output: "test".into(), + }) + } } #[tokio::test] diff --git a/skootrs-lib/templates/goreleaser.yml b/skootrs-lib/templates/goreleaser.yml index 6ad6b3b..59423b9 100644 --- a/skootrs-lib/templates/goreleaser.yml +++ b/skootrs-lib/templates/goreleaser.yml @@ -91,7 +91,7 @@ sboms: - id: bins cmd: trivy args: ["fs", ".", "--format", "spdx-json", "--output", "${artifact}.spdx.sbom.json"] - artifacts: any + artifacts: binary documents: - "${artifact}.spdx.sbom.json" diff --git a/skootrs-model/src/skootrs/mod.rs b/skootrs-model/src/skootrs/mod.rs index 995e226..64e8d75 100644 --- a/skootrs-model/src/skootrs/mod.rs +++ b/skootrs-model/src/skootrs/mod.rs @@ -18,7 +18,7 @@ pub mod facet; use std::{collections::HashMap, error::Error, fmt, str::FromStr}; use serde::{Deserialize, Serialize}; -use strum::{EnumString, VariantNames}; +use strum::{Display, EnumString, VariantNames}; use url::Host; use utoipa::ToSchema; @@ -184,14 +184,16 @@ impl ProjectReleaseParam { /// The paramaters for getting the output of a project, e.g. an SBOM from a release #[derive(Serialize, Deserialize, Clone, Debug)] #[cfg_attr(feature = "openapi", derive(ToSchema))] -pub struct ProjectOutputParams { - /// The URL of the Skootrs project to get the output from. - pub project_url: String, - /// The type of output to get from the project. +pub struct ProjectOutputGetParams { + /// The initialized project to get the output from. + pub initialized_project: InitializedProject, + /// The type of output, e.g. SBOM, to get from the project. pub project_output_type: ProjectOutputType, // TODO: Should project_output be a part of the ProjectOutputType enum? /// The output to get from the project. pub project_output: String, + /// The release to get the output from. + pub release: ProjectReleaseParam, } /// The parameters for archiving a project. @@ -203,12 +205,15 @@ pub struct ProjectArchiveParams { } /// The set of supported output types -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, EnumString, VariantNames, Default, Display)] #[cfg_attr(feature = "openapi", derive(ToSchema))] pub enum ProjectOutputType { - /// An output type for getting an SBOM from a project. + #[default] + /// An output type for an SBOM from a project. SBOM, - /// An output type for getting a custom output from a project. + /// An output type for an in-toto attestation from a project. + InToto, + /// An output type for a custom output from a project. Custom(String), }