diff options
Diffstat (limited to 'webhook/src')
| -rw-r--r-- | webhook/src/handler/handler.rs | 28 | ||||
| -rw-r--r-- | webhook/src/handler/mod.rs | 7 | ||||
| -rw-r--r-- | webhook/src/handler/tests/handler_integration.rs | 194 | ||||
| -rw-r--r-- | webhook/src/handler/types.rs | 9 |
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>, -} |
