summaryrefslogtreecommitdiff
path: root/webhook/src/handler/handler.rs
diff options
context:
space:
mode:
authorMatthieuCoder <matthieu@matthieu-dev.xyz>2022-12-31 17:07:30 +0400
committerMatthieuCoder <matthieu@matthieu-dev.xyz>2022-12-31 17:07:30 +0400
commit65652932f77ce194a10cbc8dd42f3064e2c1a132 (patch)
tree4ca18a9317c4e561e917e9dd0cf39b695b43bc34 /webhook/src/handler/handler.rs
parenta16bafdf5b0ec52fa0d73458597eee7c34ea5e7b (diff)
updates and bazel removal
Diffstat (limited to 'webhook/src/handler/handler.rs')
-rw-r--r--webhook/src/handler/handler.rs167
1 files changed, 0 insertions, 167 deletions
diff --git a/webhook/src/handler/handler.rs b/webhook/src/handler/handler.rs
deleted file mode 100644
index b25d270..0000000
--- a/webhook/src/handler/handler.rs
+++ /dev/null
@@ -1,167 +0,0 @@
-use super::error::WebhookError;
-use super::signature::validate_signature;
-use crate::config::Config;
-use common::log::{debug, error};
-use common::nats_crate::Connection;
-use common::payloads::SerializeHelper;
-use ed25519_dalek::PublicKey;
-use hyper::{
- body::{to_bytes, Bytes},
- service::Service,
- Body, Method, Request, Response, StatusCode,
-};
-use serde::{Deserialize, Serialize};
-use std::{
- future::Future,
- pin::Pin,
- str::from_utf8,
- sync::Arc,
- task::{Context, Poll},
- time::Duration,
-};
-use twilight_model::application::interaction::Interaction;
-use twilight_model::gateway::event::Event;
-use twilight_model::gateway::payload::InteractionCreate;
-
-/// Hyper service used to handle the discord webhooks
-#[derive(Clone)]
-pub struct HandlerService {
- pub config: Arc<Config>,
- pub nats: Arc<Connection>,
- pub public_key: Arc<PublicKey>,
-}
-
-impl HandlerService {
- async fn check_request(&self, req: Request<Body>) -> Result<Bytes, WebhookError> {
- if req.method() == Method::POST {
- let signature = if let Some(sig) = req.headers().get("X-Signature-Ed25519") {
- sig.to_owned()
- } else {
- return Err(WebhookError::new(
- StatusCode::BAD_REQUEST,
- "missing signature header",
- ));
- };
-
- let timestamp = if let Some(timestamp) = req.headers().get("X-Signature-Timestamp") {
- timestamp.to_owned()
- } else {
- return Err(WebhookError::new(
- StatusCode::BAD_REQUEST,
- "missing timestamp header",
- ));
- };
- let data = to_bytes(req.into_body()).await?;
-
- if validate_signature(
- &self.public_key,
- &[timestamp.as_bytes().to_vec(), data.to_vec()].concat(),
- signature.to_str()?,
- ) {
- Ok(data)
- } else {
- Err(WebhookError::new(
- StatusCode::UNAUTHORIZED,
- "invalid signature",
- ))
- }
- } else {
- Err(WebhookError::new(StatusCode::NOT_FOUND, "not found"))
- }
- }
-
- async fn process_request(
- &mut self,
- req: Request<Body>,
- ) -> Result<Response<Body>, WebhookError> {
- match self.check_request(req).await {
- Ok(data) => {
- let utf8 = from_utf8(&data);
- match utf8 {
- Ok(data) => match serde_json::from_str::<Interaction>(data) {
- Ok(value) => match value {
- Interaction::Ping(_) => Ok(Response::builder()
- .header("Content-Type", "application/json")
- .body(serde_json::to_string(&Ping { t: 1 }).unwrap().into())
- .unwrap()),
- _ => {
- debug!("calling nats");
- // this should hopefully not fail ?
- let payload =
- serde_json::to_string(&common::payloads::CachePayload {
- tracing: common::payloads::Tracing {
- node_id: "".to_string(),
- span: None,
- },
- data: SerializeHelper(Event::InteractionCreate(
- Box::new(InteractionCreate(value)),
- )),
- })
- .unwrap();
-
- match self.nats.request_timeout(
- "nova.cache.dispatch.interaction_create",
- payload,
- Duration::from_secs(2),
- ) {
- Ok(response) => Ok(Response::builder()
- .header("Content-Type", "application/json")
- .body(Body::from(response.data))
- .unwrap()),
-
- Err(error) => {
- error!("failed to request nats: {}", error);
- Err(WebhookError::new(
- StatusCode::INTERNAL_SERVER_ERROR,
- "failed to request nats",
- ))
- }
- }
- }
- },
-
- Err(error) => {
- error!("invalid json body: {}", error);
- Err(WebhookError::new(
- StatusCode::BAD_REQUEST,
- "invalid json body",
- ))
- }
- },
-
- Err(_) => Err(WebhookError::new(StatusCode::BAD_REQUEST, "not utf-8 body")),
- }
- }
- Err(error) => Err(error),
- }
- }
-}
-
-#[derive(Debug, Serialize, Deserialize)]
-pub struct Ping {
- #[serde(rename = "type")]
- t: i32,
-}
-
-/// Implementation of the service
-impl Service<Request<Body>> for HandlerService {
- type Response = Response<Body>;
- type Error = hyper::Error;
- type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
-
- fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
- Poll::Ready(Ok(()))
- }
-
- fn call(&mut self, req: Request<Body>) -> Self::Future {
- let mut clone = self.clone();
- Box::pin(async move {
- let response = clone.process_request(req).await;
-
- match response {
- Ok(r) => Ok(r),
- Err(e) => Ok(e.into()),
- }
- })
- }
-}