From b8f114900bb92f13d20d08a4b4297d275130627d Mon Sep 17 00:00:00 2001 From: finga Date: Thu, 18 Nov 2021 17:47:13 +0100 Subject: [PATCH] Compile regex when parsing config The regexes are now compiled when the config is parsed and not each time a new webhook is received. Adapt tests to using parsed regex. --- Cargo.lock | 11 +++++++++++ Cargo.toml | 1 + src/main.rs | 20 +++++++++++--------- src/webhooks.rs | 16 ++++++---------- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e118a9..9c1a7a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1301,6 +1301,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_regex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf" +dependencies = [ + "regex", + "serde", +] + [[package]] name = "serde_yaml" version = "0.8.21" @@ -1931,6 +1941,7 @@ dependencies = [ "run_script", "serde", "serde_json", + "serde_regex", "serde_yaml", "sha2", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index d49ab4e..db4a136 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ rocket = "0.5.0-rc.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" +serde_regex = "1.1" regex = "1.5" dirs = "4.0" anyhow = "1.0" diff --git a/src/main.rs b/src/main.rs index 21f912e..2b7147b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -488,6 +488,7 @@ async fn main() -> Result<()> { mod tests { use super::*; use crate::webhooks::{AddrType, HeaderFilter, JsonFilter}; + use regex::Regex; use rocket::{ http::{ContentType, Header}, local::asynchronous::Client, @@ -507,7 +508,7 @@ mod tests { secrets: vec!["valid".to_string()], filter: FilterType::JsonFilter(JsonFilter { pointer: "*".to_string(), - regex: "*".to_string(), + regex: Regex::new(".*").unwrap(), }), }, ); @@ -693,7 +694,7 @@ mod tests { secrets: vec!["valid".to_string()], filter: FilterType::JsonFilter(JsonFilter { pointer: "/foo".to_string(), - regex: "bar".to_string(), + regex: Regex::new("bar").unwrap(), }), }, ); @@ -708,7 +709,7 @@ mod tests { secrets: vec!["valid".to_string()], filter: FilterType::JsonFilter(JsonFilter { pointer: "/foo".to_string(), - regex: "bar".to_string(), + regex: Regex::new("bar").unwrap(), }), }, ); @@ -723,7 +724,7 @@ mod tests { secrets: vec!["valid".to_string()], filter: FilterType::Not(Box::new(FilterType::JsonFilter(JsonFilter { pointer: "/foobar".to_string(), - regex: "bar".to_string(), + regex: Regex::new("bar").unwrap(), }))), }, ); @@ -781,7 +782,7 @@ mod tests { secrets: vec!["valid".to_string()], filter: FilterType::JsonFilter(JsonFilter { pointer: "/foo".to_string(), - regex: "bar".to_string(), + regex: Regex::new("bar").unwrap(), }), }, ); @@ -877,7 +878,7 @@ hooks: secrets: vec!["secret_key_01".to_string(), "secret_key_02".to_string()], filter: FilterType::JsonFilter(JsonFilter { pointer: "/ref".to_string(), - regex: "refs/heads/master".to_string(), + regex: Regex::new("refs/heads/master").unwrap(), }), } ), @@ -891,11 +892,12 @@ hooks: filter: FilterType::And(vec![ FilterType::JsonFilter(JsonFilter { pointer: "/ref".to_string(), - regex: "refs/heads/master".to_string(), + regex: Regex::new("refs/heads/master").unwrap(), }), FilterType::HeaderFilter(HeaderFilter { field: "X-Gitea-Signature".to_string(), - regex: "f6e5fe4fe37df76629112d55cc210718b6a55e7e".to_string(), + regex: Regex::new("f6e5fe4fe37df76629112d55cc210718b6a55e7e") + .unwrap(), }), ]), } @@ -945,7 +947,7 @@ hooks: secrets: vec!["secret_key_01".to_string(), "secret_key_02".to_string()], filter: FilterType::JsonFilter(JsonFilter { pointer: "/ref".to_string(), - regex: "refs/heads/master".to_string(), + regex: Regex::new("refs/heads/master").unwrap(), }), } ),]) diff --git a/src/webhooks.rs b/src/webhooks.rs index 9bef844..625af56 100644 --- a/src/webhooks.rs +++ b/src/webhooks.rs @@ -21,8 +21,6 @@ pub enum WebhookeyError { Io(std::io::Error), #[error("Serde Error")] Serde(serde_json::Error), - #[error("Regex Error")] - Regex(regex::Error), } #[derive(Debug, Deserialize, Serialize)] @@ -60,7 +58,8 @@ impl IpFilter { #[derive(Debug, Deserialize, Serialize)] pub struct HeaderFilter { pub field: String, - pub regex: String, + #[serde(with = "serde_regex")] + pub regex: Regex, } impl HeaderFilter { @@ -71,10 +70,8 @@ impl HeaderFilter { &self.field, ); - let regex = Regex::new(&self.regex).map_err(WebhookeyError::Regex)?; - if let Some(value) = headers.get_one(&self.field) { - if regex.is_match(value) { + if self.regex.is_match(value) { debug!("Regex `{}` for `{}` matches", &self.regex, &self.field); return Ok(true); @@ -94,7 +91,8 @@ impl HeaderFilter { #[serde(deny_unknown_fields)] pub struct JsonFilter { pub pointer: String, - pub regex: String, + #[serde(with = "serde_regex")] + pub regex: Regex, } impl JsonFilter { @@ -105,10 +103,8 @@ impl JsonFilter { &self.pointer, ); - let regex = Regex::new(&self.regex).map_err(WebhookeyError::Regex)?; - if let Some(value) = data.pointer(&self.pointer) { - if regex.is_match(&get_string(value)?) { + if self.regex.is_match(&get_string(value)?) { debug!("Regex `{}` for `{}` matches", &self.regex, &self.pointer); return Ok(true);