diff --git a/Cargo.lock b/Cargo.lock index 74983ea..94213b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -786,7 +786,7 @@ dependencies = [ [[package]] name = "github-webhook-notification" -version = "0.1.1" +version = "0.1.2" dependencies = [ "actix", "actix-rt", diff --git a/Cargo.toml b/Cargo.toml index 48805ab..a94226c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "github-webhook-notification" -version = "0.1.1" +version = "0.1.2" edition = "2021" [dependencies] diff --git a/data/config.toml.default b/data/config.toml.default index c0f600b..cea8a00 100644 --- a/data/config.toml.default +++ b/data/config.toml.default @@ -5,4 +5,4 @@ secrets = "" [telegram] bot_token = "" -owner = 0 \ No newline at end of file +send_to = 0 \ No newline at end of file diff --git a/src/configure.rs b/src/configure.rs index dd35fb4..2de31d4 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -15,7 +15,7 @@ ** along with this program. If not, see . */ -use log::warn; +use log::{error, warn}; use serde_derive::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use std::path::Path; @@ -26,12 +26,26 @@ pub struct TomlConfig { telegram: Telegram, } +impl TryFrom<&str> for TomlConfig { + type Error = anyhow::Error; + + fn try_from(value: &str) -> Result { + Ok(toml::from_str(value)?) + } +} + impl TomlConfig { pub fn new>(path: P) -> anyhow::Result { - let contents = std::fs::read_to_string(&path)?; - let contents_str = contents.as_str(); - - Ok(toml::from_str(contents_str)?) + let contents = std::fs::read_to_string(&path); + if let Err(ref e) = contents { + error!( + "Unable read file {}, Error: {:?}", + path.as_ref().display(), + e + ); + }; + let contents = contents?; + Self::try_from(contents.as_str()) } pub fn server(&self) -> &TomlServer { @@ -46,7 +60,7 @@ impl TomlConfig { pub struct Telegram { bot_token: String, api_server: Option, - owner: i64, + send_to: i64, } impl Telegram { @@ -56,8 +70,8 @@ impl Telegram { pub fn api_server(&self) -> &Option { &self.api_server } - pub fn owner(&self) -> i64 { - self.owner + pub fn send_to(&self) -> i64 { + self.send_to } } @@ -96,7 +110,7 @@ impl From<&TomlConfig> for Config { pub struct TomlServer { bind: String, port: u16, - secrets: String, + secrets: Option, } impl TomlServer { @@ -106,7 +120,7 @@ impl TomlServer { pub fn port(&self) -> u16 { self.port } - pub fn secrets(&self) -> &str { + pub fn secrets(&self) -> &Option { &self.secrets } } @@ -119,14 +133,15 @@ pub struct Server { impl From<&TomlServer> for Server { fn from(s: &TomlServer) -> Self { - let secrets = if !s.secrets().is_empty() { + let secrets = if s.secrets().is_none() || s.secrets().as_ref().unwrap().is_empty() { + //warn!("You should set a token to protect your webhook server"); + "".to_string() + } else { + warn!("This feature not fully implement yet, please leave secret to blank"); let mut hasher = Sha256::new(); - hasher.update(s.secrets()); + hasher.update(s.secrets().as_ref().unwrap()); let result = hasher.finalize(); format!("sha256={:x}", result).to_lowercase() - } else { - warn!("You should set a token to protect your webhook server"); - "".to_string() }; Self { bind: format!("{}:{}", s.bind(), s.port()), diff --git a/src/datastructures.rs b/src/datastructures.rs index a5bde71..1dc99be 100644 --- a/src/datastructures.rs +++ b/src/datastructures.rs @@ -23,15 +23,17 @@ use std::fmt::Formatter; use std::ops::Index; #[derive(Deserialize, Serialize, Debug)] -pub struct Request { +pub struct GitHubRequest { #[serde(rename = "ref")] remote_ref: String, + after: String, + before: String, commits: Vec, compare: String, repository: Repository, } -impl Request { +impl GitHubRequest { pub fn remote_ref(&self) -> &str { &self.remote_ref } @@ -44,9 +46,15 @@ impl Request { pub fn repository(&self) -> &Repository { &self.repository } + pub fn after(&self) -> &str { + &self.after + } + pub fn before(&self) -> &str { + &self.before + } } -impl std::fmt::Display for Request { +impl std::fmt::Display for GitHubRequest { 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); diff --git a/src/main.rs b/src/main.rs index 17b5d78..c297c96 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,6 +18,7 @@ use crate::datastructures::Response; use crate::Command::Text; use actix_web::http::Method; +use actix_web::web::Data; use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer}; use log::{debug, error, info, warn}; use std::path::Path; @@ -45,7 +46,7 @@ struct ExtraData { async fn process_send_message( bot_token: String, api_server: Option, - owner: i64, + send_to: i64, mut rx: mpsc::Receiver, ) -> anyhow::Result<()> { if bot_token.is_empty() { @@ -67,7 +68,7 @@ async fn process_send_message( while let Some(cmd) = rx.recv().await { match cmd { Command::Text(text) => { - let mut payload = bot.send_message(owner, text); + let mut payload = bot.send_message(send_to, text); payload.disable_web_page_preview = Option::from(true); if let Err(e) = payload.send().await { error!("Got error in send message {:?}", e); @@ -82,11 +83,15 @@ async fn process_send_message( async fn route_post( _req: HttpRequest, - payload: web::Json, + payload: web::Json, data: web::Data>>, ) -> actix_web::Result { - let d = data.lock().await; - d.bot_tx.send(Text(payload.to_string())).await.unwrap(); + let sender = data.lock().await; + if payload.after().starts_with("000000000000") || payload.before().starts_with("000000000000") { + //return Ok(HttpResponse::Ok().json()); + return Ok(HttpResponse::NoContent().finish()) + } + sender.bot_tx.send(Text(payload.to_string())).await.unwrap(); Ok(HttpResponse::Ok().json(Response::new_ok())) } @@ -104,7 +109,7 @@ async fn async_main>(path: P) -> anyhow::Result<()> { let msg_sender = tokio::spawn(process_send_message( config.telegram().bot_token().to_string(), config.telegram().api_server().clone(), - config.telegram().owner(), + config.telegram().send_to(), bot_rx, )); @@ -118,7 +123,7 @@ async fn async_main>(path: P) -> anyhow::Result<()> { web::scope("/") .guard(authorization_guard.to_owned()) // TODO: - .data(extra_data.clone()) + .app_data(Data::new(extra_data.clone())) .route("", web::method(Method::POST).to(route_post)), ) .service(web::scope("/").route( @@ -148,6 +153,7 @@ fn main() -> anyhow::Result<()> { clap::Arg::with_name("cfg") .long("cfg") .short("c") + .default_value("data/config.toml") .help("Specify configure file location") .takes_value(true), ) @@ -157,11 +163,7 @@ fn main() -> anyhow::Result<()> { let system = actix::System::new(); info!("Server version: {}", SERVER_VERSION); - system.block_on(async_main( - arg_matches - .value_of("cfg") - .unwrap_or("data/probe_client.toml"), - ))?; + system.block_on(async_main(arg_matches.value_of("cfg").unwrap()))?; system.run()?;