summaryrefslogtreecommitdiff
path: root/webhook/src
diff options
context:
space:
mode:
Diffstat (limited to 'webhook/src')
-rw-r--r--webhook/src/handler/handler.rs28
-rw-r--r--webhook/src/handler/mod.rs7
-rw-r--r--webhook/src/handler/tests/handler_integration.rs194
-rw-r--r--webhook/src/handler/types.rs9
4 files changed, 111 insertions, 127 deletions
diff --git a/webhook/src/handler/handler.rs b/webhook/src/handler/handler.rs
index d482e01..a07f995 100644
--- a/webhook/src/handler/handler.rs
+++ b/webhook/src/handler/handler.rs
@@ -1,8 +1,10 @@
use super::error::WebhookError;
-use super::{signature::validate_signature, types::Interaction};
+use super::signature::validate_signature;
use crate::config::Config;
-use common::log::{debug, error, info};
+use common::discord_models::slash_commands::{Interaction, InteractionRequestType};
+use common::log::{debug, error};
use common::nats_crate::Connection;
+use common::payloads::CacheData;
use hyper::{
body::{to_bytes, Bytes},
service::Service,
@@ -81,15 +83,12 @@ impl HandlerService {
let utf8 = from_utf8(&data);
match utf8 {
Ok(data) => match serde_json::from_str::<Interaction>(data) {
- Ok(value) => {
- if value.t == 1 {
- info!("sending pong");
- // a ping must be responded with another ping
- return Ok(Response::builder()
- .header("Content-Type", "application/json")
- .body(serde_json::to_string(&Ping { t: 1 }).unwrap().into())
- .unwrap());
- } else {
+ Ok(value) => match value.type_ {
+ InteractionRequestType::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 =
@@ -98,8 +97,9 @@ impl HandlerService {
node_id: "".to_string(),
span: None,
},
- operation: "".to_string(),
- data: value,
+ data: CacheData::InteractionCreate {
+ interaction: Box::new(value),
+ },
})
.unwrap();
@@ -122,7 +122,7 @@ impl HandlerService {
}
}
}
- }
+ },
Err(_) => Err(WebhookError::new(
StatusCode::BAD_REQUEST,
diff --git a/webhook/src/handler/mod.rs b/webhook/src/handler/mod.rs
index a437dd5..20a977a 100644
--- a/webhook/src/handler/mod.rs
+++ b/webhook/src/handler/mod.rs
@@ -1,8 +1,7 @@
+mod error;
+mod handler;
pub mod make_service;
mod signature;
-mod handler;
-mod types;
-mod error;
#[cfg(test)]
-pub mod tests; \ No newline at end of file
+pub mod tests;
diff --git a/webhook/src/handler/tests/handler_integration.rs b/webhook/src/handler/tests/handler_integration.rs
index 2475b94..906b347 100644
--- a/webhook/src/handler/tests/handler_integration.rs
+++ b/webhook/src/handler/tests/handler_integration.rs
@@ -1,106 +1,107 @@
use std::time::Duration;
-use crate::{
- config::Config,
- handler::tests::utils::{generate_keypair, sign_message},
- start,
+use ctor;
+use hyper::{Body, Method, Request, StatusCode};
+use lazy_static::lazy_static;
+use serde_json::json;
+use ed25519_dalek::Keypair;
+
+use common::{
+ config::test_init,
+ nats_crate::Connection,
+ testcontainers::{Image, images::generic::WaitFor},
};
-use common::{config::test_init, nats_crate::Connection, testcontainers::{Image, images::generic::WaitFor}};
use common::{
config::Settings,
log::info,
- testcontainers::{clients::Cli, images::generic::GenericImage, Container, Docker},
+ testcontainers::{clients::Cli, Container, Docker, images::generic::GenericImage},
};
-use hyper::{Body, Method, Request};
-use lazy_static::{__Deref, lazy_static};
-use serde_json::json;
-#[cfg(all(unix, target_arch = "x86_64"))]
-const fn nats_image<'a>() -> &'a str {
- return "amd64/nats";
-}
+use crate::{
+ config::Config,
+ handler::tests::utils::{generate_keypair, sign_message},
+ start,
+};
-#[cfg(all(unix, target_arch = "aarch64"))]
const fn nats_image<'a>() -> &'a str {
+ #[cfg(all(unix, target_arch = "x86_64"))]
+ return "amd64/nats";
+ #[cfg(all(unix, target_arch = "aarch64"))]
return "arm64v8/nats";
-}
-
-#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
-const fn nats_image<'a>() -> &'a str {
+ #[cfg(all(target_arch = "x86_64", target_os = "windows"))]
return "winamd64/nats";
}
+static mut NATS: Option<Container<Cli, GenericImage>> = None;
+static mut SETTINGS: Option<Settings<Config>> = None;
+
lazy_static! {
+ static ref TEST_KEYPAIR: Keypair = generate_keypair();
static ref DOCKER: Cli = Cli::default();
+}
- static ref NATS_CONTAINER: Container<'static, Cli, GenericImage> = {
- test_init();
-
- let image: GenericImage = GenericImage::new(nats_image())
- .with_wait_for(WaitFor::message_on_stderr("Server is ready"));
-
- let container = DOCKER.run(image);
- container.start();
- container.image().wait_until_ready(&container);
- container.get_host_port(4222).unwrap();
- container
- };
-
-
- static ref TEST_KEYPAIR: ed25519_dalek::Keypair = {
- generate_keypair()
- };
-
- static ref SETTINGS: Settings<Config> = {
- let port = NATS_CONTAINER.get_host_port(4222).unwrap();
- common::config::Settings {
- config: crate::config::Config {
- server: crate::config::ServerSettings {
- port: 5003,
- address: "0.0.0.0".to_string(),
- },
- discord: crate::config::Discord {
- public_key: hex::encode(TEST_KEYPAIR.to_bytes()),
- client_id: 0,
- },
+#[ctor::ctor]
+unsafe fn init() {
+ test_init();
+ let image = GenericImage::new(nats_image())
+ .with_wait_for(WaitFor::message_on_stderr("Server is ready"));
+
+ let container = DOCKER.run(image);
+ container.start();
+ container.image().wait_until_ready(&container);
+ container.get_host_port(4222).unwrap();
+
+ let port = container.get_host_port(4222).unwrap();
+ NATS = Some(container);
+ SETTINGS = Some(common::config::Settings {
+ config: crate::config::Config {
+ server: crate::config::ServerSettings {
+ port: 5003,
+ address: "0.0.0.0".to_string(),
},
- redis: common::redis::RedisConfiguration {
- url: "".to_string(),
+ discord: crate::config::Discord {
+ public_key: hex::encode(TEST_KEYPAIR.public.clone()),
+ client_id: 0,
},
- monitoring: common::monitoring::MonitoringConfiguration {
- enabled: false,
- address: None,
- port: None,
- },
- nats: common::nats::NatsConfiguration {
- client_cert: None,
- root_cert: None,
- jetstream_api_prefix: None,
- max_reconnects: None,
- reconnect_buffer_size: None,
- tls: None,
- client_name: None,
- tls_required: None,
- host: format!("localhost:{}", port),
- },
- }
- };
-
- static ref TASK: () = {
- std::thread::spawn(|| {
- let r = tokio::runtime::Runtime::new().unwrap();
- r.spawn(async { start(SETTINGS.clone()).await });
- loop {}
- });
- std::thread::sleep(Duration::from_secs(1));
- };
+ },
+ redis: common::redis::RedisConfiguration {
+ url: "".to_string(),
+ },
+ monitoring: common::monitoring::MonitoringConfiguration {
+ enabled: false,
+ address: None,
+ port: None,
+ },
+ nats: common::nats::NatsConfiguration {
+ client_cert: None,
+ root_cert: None,
+ jetstream_api_prefix: None,
+ max_reconnects: None,
+ reconnect_buffer_size: None,
+ tls: None,
+ client_name: None,
+ tls_required: None,
+ host: format!("localhost:{}", port),
+ },
+ });
+ let settings = (&mut SETTINGS).as_ref().unwrap();
+
+ std::thread::spawn(move || {
+ let runtime = tokio::runtime::Runtime::new().unwrap();
+ runtime.block_on(start(settings.clone()));
+ });
+ std::thread::sleep(Duration::from_secs(3));
+}
+
+#[ctor::dtor]
+unsafe fn destroy() {
+ let nats = (&mut NATS).as_ref().unwrap();
+ nats.stop();
}
#[tokio::test]
async fn respond_to_pings() {
- let _ = NATS_CONTAINER.deref();
- let _ = TASK.deref();
- let ping = json!({ "type": 1 }).to_string();
+ let ping = json!({ "type": 1, "id": "0", "application_id": "0", "token": "random token", "version": 1 }).to_string();
let timestamp = "my datetime :)";
let signature_data = [timestamp.as_bytes().to_vec(), ping.as_bytes().to_vec()].concat();
let signature = sign_message(signature_data, &TEST_KEYPAIR);
@@ -115,14 +116,12 @@ async fn respond_to_pings() {
let client = hyper::client::Client::new();
let result = client.request(req).await.unwrap();
- assert!(result.status() == 200);
+ assert_eq!(result.status(), StatusCode::OK);
}
#[tokio::test]
async fn deny_invalid_signatures() {
- let _ = NATS_CONTAINER.deref();
- let _ = TASK.deref();
- let ping = json!({ "type": 1 }).to_string();
+ let ping = json!({ "type": 1, "id": "0", "application_id": "0", "token": "random token", "version": 1 }).to_string();
let timestamp = "my datetime :)";
let req = Request::builder()
@@ -134,14 +133,12 @@ async fn deny_invalid_signatures() {
.expect("request builder");
let client = hyper::client::Client::new();
let result = client.request(req).await.unwrap();
- assert!(result.status() == 401);
+ assert_eq!(result.status(), StatusCode::UNAUTHORIZED);
}
#[tokio::test]
async fn response_500_when_no_nats_response() {
- let _ = NATS_CONTAINER.deref();
- let _ = TASK.deref();
- let ping = json!({ "type": 0 }).to_string();
+ let ping = json!({ "type": 2, "id": "0", "application_id": "0", "token": "random token", "version": 1 }).to_string();
let timestamp = "my datetime :)";
let signature_data = [timestamp.as_bytes().to_vec(), ping.as_bytes().to_vec()].concat();
let signature = sign_message(signature_data, &TEST_KEYPAIR);
@@ -157,16 +154,17 @@ async fn response_500_when_no_nats_response() {
let client = hyper::client::Client::new();
let result = client.request(req).await.unwrap();
- assert!(result.status() == 500);
+ assert_eq!(result.status(), StatusCode::INTERNAL_SERVER_ERROR);
}
#[tokio::test]
async fn respond_from_nats_response() {
- let _ = NATS_CONTAINER.deref();
- let _ = TASK.deref();
- let nats: Connection = SETTINGS.clone().nats.into();
+ let nats: Connection;
+ unsafe {
+ nats = SETTINGS.clone().unwrap().nats.into();
+ }
let sub = nats.subscribe("nova.cache.dispatch.interaction").unwrap();
- let ping = json!({ "type": 0 }).to_string();
+ let ping = json!({ "type": 2, "id": "0", "application_id": "0", "token": "random token", "version": 1 }).to_string();
let timestamp = "my datetime :)";
let signature_data = [timestamp.as_bytes().to_vec(), ping.as_bytes().to_vec()].concat();
let signature = sign_message(signature_data, &TEST_KEYPAIR);
@@ -186,13 +184,11 @@ async fn respond_from_nats_response() {
.expect("request builder");
let client = hyper::client::Client::new();
let result = client.request(req).await.unwrap();
- assert!(result.status() == 200);
+ assert_eq!(result.status(), StatusCode::OK);
}
#[tokio::test]
async fn response_400_when_invalid_json_body() {
- let _ = NATS_CONTAINER.deref();
- let _ = TASK.deref();
let ping = "{".to_string();
let timestamp = "my datetime :)";
let signature_data = [timestamp.as_bytes().to_vec(), ping.as_bytes().to_vec()].concat();
@@ -207,13 +203,11 @@ async fn response_400_when_invalid_json_body() {
.expect("request builder");
let client = hyper::client::Client::new();
let result = client.request(req).await.unwrap();
- assert!(result.status() == 400);
+ assert_eq!(result.status(), StatusCode::BAD_REQUEST);
}
#[tokio::test]
async fn response_400_when_invalid_utf8_body() {
- let _ = NATS_CONTAINER.deref();
- let _ = TASK.deref();
// invalid 2 octet sequence
let ping = vec![0xc3, 0x28];
@@ -230,5 +224,5 @@ async fn response_400_when_invalid_utf8_body() {
.expect("request builder");
let client = hyper::client::Client::new();
let result = client.request(req).await.unwrap();
- assert!(result.status() == 400);
+ assert_eq!(result.status(), StatusCode::BAD_REQUEST);
}
diff --git a/webhook/src/handler/types.rs b/webhook/src/handler/types.rs
deleted file mode 100644
index 4fc5b68..0000000
--- a/webhook/src/handler/types.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-use serde::{Serialize, Deserialize};
-use serde_json::Value;
-
-#[derive(Debug, Deserialize, Clone, Default, Serialize)]
-pub struct Interaction {
- #[serde(rename = "type")]
- pub t: i16,
- pub data: Option<Value>,
-}