From 3d0669fdacdfd9cafff39ea46094ff3a5a296bd9 Mon Sep 17 00:00:00 2001 From: KunoiSayami Date: Sun, 12 Dec 2021 15:51:23 +0800 Subject: [PATCH] feat(server): Support reply ping event Signed-off-by: KunoiSayami --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- src/datastructures.rs | 22 ++++++++++++++++----- src/main.rs | 46 ++++++++++++++++++++++++++++++++----------- 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4311a7..227e4ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -787,7 +787,7 @@ dependencies = [ [[package]] name = "github-webhook-notification" -version = "1.1.1" +version = "1.1.2" dependencies = [ "actix", "actix-rt", diff --git a/Cargo.toml b/Cargo.toml index f51186f..1547098 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "github-webhook-notification" -version = "1.1.1" +version = "1.1.2" edition = "2021" [dependencies] @@ -10,7 +10,7 @@ actix-web = "4.0.0-beta.3" anyhow = "1" clap = "2" env_logger = "0.8" -hmac = "0.12.0" +hmac = "0.12" log = { version = "0.4", features = ["max_level_trace", "release_max_level_debug"] } serde = { version = "1.0", features = ["derive"] } serde_derive = "1" diff --git a/src/datastructures.rs b/src/datastructures.rs index 6786007..470335d 100644 --- a/src/datastructures.rs +++ b/src/datastructures.rs @@ -23,7 +23,19 @@ use std::fmt::Formatter; use std::ops::Index; #[derive(Deserialize, Serialize, Debug)] -pub struct GitHubRequest { +pub struct GitHubPingEvent { + zen: String, +} + +impl GitHubPingEvent { + pub fn zen(&self) -> &str { + &self.zen + } +} + + +#[derive(Deserialize, Serialize, Debug)] +pub struct GitHubPushEvent { #[serde(rename = "ref")] remote_ref: String, after: String, @@ -33,7 +45,7 @@ pub struct GitHubRequest { repository: Repository, } -impl GitHubRequest { +impl GitHubPushEvent { pub fn remote_ref(&self) -> &str { &self.remote_ref } @@ -54,7 +66,7 @@ impl GitHubRequest { } } -impl std::fmt::Display for GitHubRequest { +impl std::fmt::Display for GitHubPushEvent { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let branch = self.remote_ref().rsplit_once("/").unwrap().1; let git_ref = format!("{}:{}", self.repository(), branch); @@ -161,11 +173,11 @@ impl Response { Self::new(200) } - pub fn reason(status: i64, reason: &str) -> Self { + pub fn reason>(status: i64, reason: T) -> Self { Self { version: env!("CARGO_PKG_VERSION").to_string(), status, - reason: reason.to_string(), + reason: reason.into(), } } } diff --git a/src/main.rs b/src/main.rs index f125326..7268d7c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,7 @@ ** along with this program. If not, see . */ -use crate::datastructures::{GitHubRequest, Response}; +use crate::datastructures::{GitHubPingEvent, GitHubPushEvent, Response}; use crate::Command::Text; use actix_web::http::Method; use actix_web::web::Data; @@ -121,18 +121,40 @@ async fn route_post( } } - let request_body = serde_json::from_slice::(&body)?; - if request_body.after().starts_with("000000000000") - || request_body.before().starts_with("000000000000") - { - return Ok(HttpResponse::NoContent().finish()); + if let Some(event) = request.headers().get("X-GitHub-Event") { + let event = event.to_str(); + if let Err(ref e) = event { + error!("Parse X-GitHub-Event error: {:?}", e); + return Ok(HttpResponse::InternalServerError().finish()) + } + let event = event.unwrap(); + match event { + "ping" => { + let request_body = serde_json::from_slice::(&body)?; + Ok(HttpResponse::Ok().json(Response::reason(200, request_body.zen()))) + } + "push" => { + let request_body = serde_json::from_slice::(&body)?; + if request_body.after().starts_with("000000000000") + || request_body.before().starts_with("000000000000") + { + return Ok(HttpResponse::NoContent().finish()); + } + sender + .bot_tx + .send(Text(request_body.to_string())) + .await + .unwrap(); + Ok(HttpResponse::Ok().json(Response::new_ok())) + } + _ => { + Ok(HttpResponse::BadRequest().json(Response::reason(400, format!( "Unsupported event type {:?}", event)))) + } + } + } else { + error!("Unknown request: {:?}", request); + Ok(HttpResponse::InternalServerError().finish()) } - sender - .bot_tx - .send(Text(request_body.to_string())) - .await - .unwrap(); - Ok(HttpResponse::Ok().json(Response::new_ok())) } async fn async_main>(path: P) -> anyhow::Result<()> {