From 4b9186b10d108c6df14f8de92b487fc931d9a845 Mon Sep 17 00:00:00 2001 From: finga Date: Tue, 16 Nov 2021 14:39:22 +0100 Subject: [PATCH] Fix json parsing bug Increase version for building a new Debian package. --- Cargo.toml | 2 +- src/main.rs | 29 ++++++++++++++++++++++++++--- src/webhooks.rs | 28 +++++++++++++++------------- 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 28246a8..0b63cad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "webhookey" -version = "0.1.3" +version = "0.1.4" authors = ["finga "] edition = "2021" license = "GPL-3.0-or-later" diff --git a/src/main.rs b/src/main.rs index 03c6a78..d0e7eb8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -82,12 +82,35 @@ impl Hook { &self, hook_name: &str, request: &Request, - data: &serde_json::Value, + data: &mut serde_json::Value, ) -> Result { trace!("Replacing parameters for command of hook `{}`", hook_name); + for parameter in self.get_parameter()? { + let parameter = parameter.trim(); + + if let Some(json_value) = data.pointer(parameter) { + *data.pointer_mut(parameter).ok_or_else(|| { + WebhookeyError::InvalidParameterPointer(parameter.to_string()) + })? = serde_json::Value::String(webhooks::get_string(json_value)?); + } + } + replace_parameters(&self.command, request.headers(), data) } + + fn get_parameter(&self) -> Result> { + let parse: IResult<&str, Vec<&str>> = many0(alt(( + delimited(tag("{{"), take_until("}}"), tag("}}")), + take_until("{{"), + )))(&self.command); + + let (_last, result) = parse + .finish() + .map_err(|e| anyhow!("Could not get parameters from command: {}", e))?; + + Ok(result) + } } #[derive(Debug)] @@ -142,11 +165,11 @@ impl Hooks { valid = true; - let data: serde_json::Value = + let mut data: serde_json::Value = serde_json::from_slice(&buffer).map_err(WebhookeyError::Serde)?; match hook.filter.evaluate(&data) { - Ok(true) => match hook.get_command(hook_name, request, &data) { + Ok(true) => match hook.get_command(hook_name, request, &mut data) { Ok(command) => { info!("Filter for `{}` matched", &hook_name); result.insert(hook_name.to_string(), command); diff --git a/src/webhooks.rs b/src/webhooks.rs index f9f8b24..85a52d1 100644 --- a/src/webhooks.rs +++ b/src/webhooks.rs @@ -14,6 +14,8 @@ pub enum WebhookeyError { Unauthorized(IpAddr), #[error("Unmatched hook from `{0}`")] UnmatchedHook(IpAddr), + #[error("Could not find field refered to in parameter `{0}`")] + InvalidParameterPointer(String), #[error("Could not evaluate filter request")] InvalidFilter, #[error("IO Error")] @@ -74,7 +76,7 @@ impl JsonFilter { let regex = Regex::new(&self.regex).map_err(WebhookeyError::Regex)?; if let Some(value) = data.pointer(&self.pointer) { - if regex.is_match(&self.get_string(value)?) { + if regex.is_match(&get_string(value)?) { debug!("Regex `{}` for `{}` matches", &self.regex, &self.pointer); return Ok(true); @@ -88,18 +90,6 @@ impl JsonFilter { Ok(false) } - - fn get_string(&self, data: &serde_json::Value) -> Result { - match &data { - serde_json::Value::Bool(bool) => Ok(bool.to_string()), - serde_json::Value::Number(number) => Ok(number.to_string()), - serde_json::Value::String(string) => Ok(string.as_str().to_string()), - x => { - error!("Could not get string from: {:?}", x); - unimplemented!() - } - } - } } #[derive(Debug, Deserialize, Serialize)] @@ -161,3 +151,15 @@ impl FilterType { } } } + +pub fn get_string(data: &serde_json::Value) -> Result { + match &data { + serde_json::Value::Bool(bool) => Ok(bool.to_string()), + serde_json::Value::Number(number) => Ok(number.to_string()), + serde_json::Value::String(string) => Ok(string.as_str().to_string()), + x => { + error!("Could not get string from: {:?}", x); + unimplemented!() + } + } +}