Skip to content

Commit

Permalink
(fix): body consumed multiple times
Browse files Browse the repository at this point in the history
  • Loading branch information
banocean committed Jan 15, 2024
1 parent d29bd2e commit 981283d
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ anyhow = { version = "1.0", optional = true }
all = ["custom-clients", "tasks", "http-interactions", "api", "gateway"]
custom-clients = []
tasks = []
http-interactions = ["dep:warp", "dep:hex", "dep:ed25519-dalek"]
http-interactions = ["dep:warp", "dep:hex", "dep:anyhow", "dep:ed25519-dalek"]
gateway = ["dep:regex", "dep:twilight-gateway"]
api = ["dep:warp", "dep:rusty_paseto", "dep:serde_urlencoded", "dep:anyhow", "reqwest/json"]
15 changes: 7 additions & 8 deletions src/server/authorize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::{err, reject, with_value};
pub fn verify_signature(
public_key: PublicKey,
signature: String,
timestamp: String,
body: String,
timestamp: &String,
body: &String,
) -> bool {
let signature = Signature::from_str(signature.as_str());
let signature = match signature {
Expand All @@ -26,7 +26,7 @@ pub fn verify_signature(
}

pub fn filter(public_key: PublicKey)
-> impl Filter<Extract = (), Error = warp::Rejection> + Clone {
-> impl Filter<Extract = (String,), Error = warp::Rejection> + Clone {
let with_public_key = with_value!(public_key);

warp::any()
Expand All @@ -35,22 +35,21 @@ pub fn filter(public_key: PublicKey)
.and(warp::header("X-Signature-Ed25519"))
.and(warp::body::bytes())
.and_then(f)
.untuple_one()
.boxed()
}

async fn f(public_key: PublicKey, timestamp: String, signature: String, body: Bytes) -> Result<(), warp::Rejection> {
async fn f(public_key: PublicKey, timestamp: String, signature: String, body: Bytes) -> Result<String, warp::Rejection> {
let body = String::from_utf8(body.to_vec())
.map_err(|_| reject!(Rejection::BodyNotConvertableToString))?;

if !verify_signature(
public_key,
signature,
timestamp,
body
&timestamp,
&body
) {
return err!(Rejection::InvalidSignature);
}

Ok(())
Ok(body)
}
4 changes: 1 addition & 3 deletions src/server/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ pub enum Rejection {
InvalidCode,
#[cfg(feature = "api")]
Unauthorized,
#[cfg(feature = "api")]
Internal(anyhow::Error)
}

Expand All @@ -29,7 +28,6 @@ impl Display for Rejection {
Rejection::InvalidCode => f.write_str("Invalid `code` was provided"),
#[cfg(feature = "api")]
Rejection::Unauthorized => f.write_str("Invalid authorization data provided"),
#[cfg(feature = "api")]
Rejection::Internal(err) => std::fmt::Display::fmt(&err, f),
}?;
Ok(())
Expand All @@ -56,7 +54,6 @@ pub trait MapErrorIntoInternalRejection<T> {
fn map_rejection(self) -> Result<T, warp::Rejection>;
}

#[cfg(feature = "api")]
impl<T, E: Into<anyhow::Error>> MapErrorIntoInternalRejection<T> for Result<T, E> where Self: Sized {
fn map_rejection(self) -> Result<T, warp::Rejection> {
self.map_err(|err| reject!(Rejection::Internal(err.into())))
Expand All @@ -66,6 +63,7 @@ impl<T, E: Into<anyhow::Error>> MapErrorIntoInternalRejection<T> for Result<T, E
impl Reject for Rejection {}

pub async fn handle_rejection(rejection: warp::Rejection) -> Result<impl Reply, Infallible> {
println!("{:?}", rejection);
Ok(if let Some(rejection) = rejection.find::<Rejection>() {
warp::reply::with_status(rejection.to_string(), match rejection {
#[cfg(feature = "http-interactions")]
Expand Down
7 changes: 6 additions & 1 deletion src/server/routes/interactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use warp::reply::Json;
use crate::context::Context;
use crate::server::interaction::handle_interaction;
use crate::{response_type, with_value};
use crate::server::error::{MapErrorIntoInternalRejection, Rejection};

pub fn filter(
discord_http: Arc<Client>,
Expand All @@ -19,12 +20,16 @@ pub fn filter(
warp::post()
.and(warp::path("interactions"))
.and(crate::server::authorize::filter(public_key))
.and(warp::body::json())
.and_then(parse_body)
.and(with_discord_http)
.and(with_context)
.and_then(run)
}

async fn parse_body(body: String) -> Result<Interaction, warp::Rejection> {
serde_json::from_str(body.as_str()).map_rejection()
}

async fn run(content: Interaction, discord_http: Arc<Client>, context: Arc<Context>) -> Result<Json, warp::Rejection> {
let response = handle_interaction(
content,
Expand Down

0 comments on commit 981283d

Please sign in to comment.