diff --git a/src/extractors.rs b/src/extractors.rs index d3d1fdf..6bd4bfe 100644 --- a/src/extractors.rs +++ b/src/extractors.rs @@ -6,13 +6,12 @@ use axum::{ http::request::{Parts, Request}, }; use hmac::{Hmac, Mac}; +use serde_json::Value; use sha2::Sha256; use crate::{errors::AppError, states}; -pub struct ReceivedSignature { - pub inner: Vec, -} +pub struct ReceivedSignature(pub Vec); #[async_trait] impl FromRequestParts for ReceivedSignature @@ -33,9 +32,7 @@ where let received_signature = hex::decode(received_signature) .context("Can not hex decode the received signature!")?; - Ok(ReceivedSignature { - inner: received_signature.to_vec(), - }) + Ok(ReceivedSignature(received_signature.to_vec())) } } @@ -46,13 +43,11 @@ impl ReceivedSignature { mac.update(body); let expected_signature = mac.finalize().into_bytes(); - self.inner[..] == expected_signature[..] + self.0[..] == expected_signature[..] } } -pub struct ValidatedBody { - pub inner: Bytes, -} +pub struct ValidatedBody(pub Bytes); #[async_trait] impl FromRequest for ValidatedBody @@ -81,6 +76,27 @@ where return Err("Invalid signature!".into()); } - Ok(Self { inner: body }) + Ok(Self(body)) + } +} + +pub struct ValidatedJson(pub Value); + +#[async_trait] +impl FromRequest for ValidatedJson +where + Bytes: FromRequest, + B: Send + 'static, + S: Send + Sync + states::ConfigState, +{ + type Rejection = AppError; + + async fn from_request(req: Request, state: &S) -> Result { + let body = ValidatedBody::from_request(req, state).await?.0; + + let json: Value = + serde_json::from_slice(&body).context("Can not parse the request body into JSON!")?; + + Ok(Self(json)) } } diff --git a/src/routes.rs b/src/routes.rs index 3054afc..ed6ffea 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -5,12 +5,11 @@ use axum::{ response::Response, }; use serde::Deserialize; -use serde_json::Value; use std::sync::Arc; use tokio::task; use tracing::info; -use crate::{db, errors, extractors, mailer, states, templates, webhook}; +use crate::{db, errors, extractors::ValidatedJson, mailer, states, templates, webhook}; #[derive(Deserialize)] pub struct IndexQuery { @@ -40,13 +39,10 @@ pub async fn trigger( State(db): State>, State(state_config): State>, State(mailer): State>, - body: extractors::ValidatedBody, + ValidatedJson(json): ValidatedJson, ) -> Result { info!("Trigger called"); - let json: Value = - serde_json::from_slice(&body.inner).context("Can not parse the request body into JSON!")?; - let repo = json .get("repository") .context("Can not get the repository value from the request body!")?;