Skip to content
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

fix: deserialize relationships filter from query params #1256

Merged
merged 3 commits into from
Feb 7, 2025
Merged
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
2 changes: 2 additions & 0 deletions entity/src/relationship.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ use std::fmt;
EnumIter,
DeriveActiveEnum,
strum::VariantArray,
strum::EnumString,
serde::Serialize,
serde::Deserialize,
utoipa::ToSchema,
)]
#[sea_orm(rs_type = "i32", db_type = "Integer")]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
#[derive(DeepSizeOf)]
// When adding a new variant, also add this to the "relationship" table.
pub enum Relationship {
Expand Down
1 change: 0 additions & 1 deletion modules/analysis/src/endpoints/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,6 @@ async fn spdx_package_of(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {

#[test_context(TrustifyContext)]
#[test(actix_web::test)]
#[ignore = "currently throws query serialize error"]
async fn spdx_only_contains_relationships(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
// test case for the simple case of filtering descendants "relationshipType": "CONTAINS" spdx relationships:
// https://github.com/trustification/trustify/issues/1232
Expand Down
21 changes: 18 additions & 3 deletions modules/analysis/src/service/query.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use serde::{Deserialize, Deserializer};
use std::collections::HashSet;
use std::str::FromStr;
use trustify_common::{cpe::Cpe, db::query::Query, purl::Purl};
use trustify_entity::relationship::Relationship;
use utoipa::IntoParams;
Expand Down Expand Up @@ -60,7 +62,7 @@ impl<'a> From<&'a Query> for GraphQuery<'a> {
}

/// Options when querying the graph.
#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Deserialize, IntoParams)]
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, IntoParams)]
pub struct QueryOptions {
/// The level of ancestors to return.
///
Expand All @@ -72,13 +74,26 @@ pub struct QueryOptions {
/// Zero, the default, meaning none.
#[serde(default)]
pub descendants: u64,
/// A set of relationships to filter for.
/// A set of relationships to filter for, deserialized from a
/// comma-delimited string
///
/// An empty set, the default, meaning all relationships.
#[serde(default)]
#[serde(default, deserialize_with = "deserialize_relationships")]
#[param(value_type = String)]
pub relationships: HashSet<Relationship>,
}

fn deserialize_relationships<'de, D>(deserializer: D) -> Result<HashSet<Relationship>, D::Error>
where
D: Deserializer<'de>,
{
let buf = String::deserialize(deserializer)?;
buf.split_terminator(',')
.map(Relationship::from_str)
.collect::<Result<HashSet<_>, _>>()
.map_err(serde::de::Error::custom)
}

impl QueryOptions {
pub fn any() -> Self {
Self {
Expand Down
16 changes: 6 additions & 10 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -290,15 +290,13 @@ paths:
- name: relationships
in: query
description: |-
A set of relationships to filter for.
A set of relationships to filter for, deserialized from a
comma-delimited string

An empty set, the default, meaning all relationships.
required: false
schema:
type: array
items:
$ref: '#/components/schemas/Relationship'
uniqueItems: true
type: string
responses:
'200':
description: Retrieved component(s) located by search
Expand Down Expand Up @@ -380,15 +378,13 @@ paths:
- name: relationships
in: query
description: |-
A set of relationships to filter for.
A set of relationships to filter for, deserialized from a
comma-delimited string

An empty set, the default, meaning all relationships.
required: false
schema:
type: array
items:
$ref: '#/components/schemas/Relationship'
uniqueItems: true
type: string
responses:
'200':
description: Retrieved component(s) located by name, pURL, or CPE
Expand Down