From 15596c609974b66ed2e1559dd0a8d5d68afdbd72 Mon Sep 17 00:00:00 2001 From: Javier Parada Date: Wed, 4 Dec 2024 13:15:46 +0100 Subject: [PATCH] add find cve query handler --- .../cves/application/cve_query_response.rs | 49 +++++++++++++++++++ .../cves/application/find_one/cve_finder.rs | 25 ++++++++++ .../find_one/find_cve_q_handler.rs | 42 ++++++++++++++++ .../application/find_one/find_cve_query.rs | 26 ++++++++++ libs/cti/src/cves/application/find_one/mod.rs | 3 ++ libs/cti/src/cves/application/mod.rs | 3 +- 6 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 libs/cti/src/cves/application/cve_query_response.rs create mode 100644 libs/cti/src/cves/application/find_one/cve_finder.rs create mode 100644 libs/cti/src/cves/application/find_one/find_cve_q_handler.rs create mode 100644 libs/cti/src/cves/application/find_one/find_cve_query.rs diff --git a/libs/cti/src/cves/application/cve_query_response.rs b/libs/cti/src/cves/application/cve_query_response.rs new file mode 100644 index 0000000..a050309 --- /dev/null +++ b/libs/cti/src/cves/application/cve_query_response.rs @@ -0,0 +1,49 @@ +use cqrs::domain::query_bus_response::QueryBusResponse; + +use crate::{cves::domain::entities::cve::Cve, shared::domain::errors::DomainError}; + + +pub struct CveQueryResponse { + pub error: Option, + pub cve: Option, +} + +impl CveQueryResponse { + pub const RES_TYPE: &'static str = "CveQueryResponse"; + + pub fn ok(cve: Cve) -> CveQueryResponse { + CveQueryResponse { error: None, cve: Some(cve) } + } + + pub fn boxed_ok(cve: Cve) -> Box { + let res = CveQueryResponse::ok(cve); + Box::new(res) + } + + pub fn err(error: DomainError) -> CveQueryResponse { + CveQueryResponse { error: Some(error), cve: None } + } + + pub fn boxed_err(error: DomainError) -> Box { + let res = CveQueryResponse::err(error); + Box::new(res) + } + + pub fn is_err(&self) -> bool { + self.error.is_some() + } + + pub fn is_ok(&self) -> bool { + self.error.is_none() + } +} + +impl QueryBusResponse for CveQueryResponse { + fn response_type(&self) -> String { + Self::RES_TYPE.to_string() + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } +} \ No newline at end of file diff --git a/libs/cti/src/cves/application/find_one/cve_finder.rs b/libs/cti/src/cves/application/find_one/cve_finder.rs new file mode 100644 index 0000000..3ca81d6 --- /dev/null +++ b/libs/cti/src/cves/application/find_one/cve_finder.rs @@ -0,0 +1,25 @@ +use tracing::debug; + +use crate::{cves::domain::{entities::{cve::Cve, cve_id::CveId}, repositories::cve_repository::CveRepository}, shared::domain::errors::DomainError}; +use std::sync::Arc; + +pub struct CveFinder { + repository: Arc, +} + +impl CveFinder { + pub fn new(cve_repository: Arc) -> CveFinder { + CveFinder { repository: cve_repository } + } + + pub async fn run(&self, id: CveId) -> Result { + debug!("Finding CVE with id: {}.", id); + let res = self.repository.find_by_id(&id).await; + if res.is_err() { + debug!("Error finding CVE with id: {}.", id); + return Err(res.err().unwrap()); + } + debug!("CVE with id: {} found.", id); + Ok(res.unwrap()) + } +} diff --git a/libs/cti/src/cves/application/find_one/find_cve_q_handler.rs b/libs/cti/src/cves/application/find_one/find_cve_q_handler.rs new file mode 100644 index 0000000..413119f --- /dev/null +++ b/libs/cti/src/cves/application/find_one/find_cve_q_handler.rs @@ -0,0 +1,42 @@ +use std::ops::Deref; + +use async_trait::async_trait; +use cqrs::domain::{query::Query, query_bus_response::QueryBusResponse, query_handler::QueryHandler}; + +use crate::cves::{application::cve_query_response::CveQueryResponse, domain::{entities::cve_id::CveId, repositories::cve_repository::CveRepository}}; + +use super::{cve_finder::CveFinder, find_cve_query::FindCveQuery}; + + +pub struct FindCveQueryHandler { + crypto_keys_by_user_finder: CveFinder, +} + +impl FindCveQueryHandler { + pub fn new(crypto_keys_by_user_finder: CveFinder) -> FindCveQueryHandler { + FindCveQueryHandler { crypto_keys_by_user_finder } + } +} + +#[async_trait] +impl QueryHandler for FindCveQueryHandler { + async fn handle(&self, query: Box) -> Box { + let query = query.deref().as_any().downcast_ref::().unwrap(); + + let id = match CveId::from_optional(&query.id) { + Ok(id) => id, + Err(err) => return CveQueryResponse::boxed_err(err), + }; + + let res = self.crypto_keys_by_user_finder.run(id).await; + if res.is_err() { + return CveQueryResponse::boxed_err(res.err().unwrap()); + } + + CveQueryResponse::boxed_ok(res.ok().unwrap()) + } + + fn subscribet_to(&self) -> String { + return FindCveQuery::QUERY_TYPE.to_string(); + } +} \ No newline at end of file diff --git a/libs/cti/src/cves/application/find_one/find_cve_query.rs b/libs/cti/src/cves/application/find_one/find_cve_query.rs new file mode 100644 index 0000000..cd9c7ef --- /dev/null +++ b/libs/cti/src/cves/application/find_one/find_cve_query.rs @@ -0,0 +1,26 @@ +use std::any::Any; + +use cqrs::domain::query::Query; + + +pub struct FindCveQuery { + pub id: Option, +} + +impl FindCveQuery { + pub const QUERY_TYPE: &'static str = "FindCveQuery"; + + pub fn new(id: Option) -> FindCveQuery { + FindCveQuery { id } + } +} + +impl Query for FindCveQuery { + fn get_type(&self) -> String { + FindCveQuery::QUERY_TYPE.to_string() + } + + fn as_any(&self) -> &dyn Any { + self + } +} \ No newline at end of file diff --git a/libs/cti/src/cves/application/find_one/mod.rs b/libs/cti/src/cves/application/find_one/mod.rs index e69de29..e2d18a6 100644 --- a/libs/cti/src/cves/application/find_one/mod.rs +++ b/libs/cti/src/cves/application/find_one/mod.rs @@ -0,0 +1,3 @@ +pub mod cve_finder; +pub mod find_cve_query; +pub mod find_cve_q_handler; \ No newline at end of file diff --git a/libs/cti/src/cves/application/mod.rs b/libs/cti/src/cves/application/mod.rs index 30e8a9f..a7b0166 100644 --- a/libs/cti/src/cves/application/mod.rs +++ b/libs/cti/src/cves/application/mod.rs @@ -4,4 +4,5 @@ pub mod create_one; pub mod update_one; pub mod delete_one; -pub mod cve_command_response; \ No newline at end of file +pub mod cve_command_response; +pub mod cve_query_response; \ No newline at end of file