Enable command parser to parse all values
To be able to parse other values than `serde_json::Value::String(String)` we parse the pointer parameters and replace all those values in the JSON data with strings.
This commit is contained in:
parent
ea3121a985
commit
6af7d29833
2 changed files with 54 additions and 22 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1041,9 +1041,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinyvec"
|
name = "tinyvec"
|
||||||
version = "1.1.1"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023"
|
checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"tinyvec_macros",
|
"tinyvec_macros",
|
||||||
]
|
]
|
||||||
|
|
72
src/main.rs
72
src/main.rs
|
@ -149,6 +149,19 @@ fn validate_request(secret: &str, signature: &str, data: &[u8]) -> Result<()> {
|
||||||
mac.verify(&raw_signature).map_err(|e| anyhow!("{}", e))
|
mac.verify(&raw_signature).map_err(|e| anyhow!("{}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_parameter(input: &str) -> Result<Vec<&str>> {
|
||||||
|
let parse: IResult<&str, Vec<&str>> = many0(alt((
|
||||||
|
delimited(tag("{{"), take_until("}}"), tag("}}")),
|
||||||
|
take_until("{{"),
|
||||||
|
)))(&input);
|
||||||
|
|
||||||
|
let (_last, result) = parse
|
||||||
|
.finish()
|
||||||
|
.map_err(|e| anyhow!("Could not get parameters from command: {}", e))?;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
fn replace_parameter(input: &str, headers: &HeaderMap, data: &serde_json::Value) -> Result<String> {
|
fn replace_parameter(input: &str, headers: &HeaderMap, data: &serde_json::Value) -> Result<String> {
|
||||||
let parse: IResult<&str, Vec<&str>> = many0(alt((
|
let parse: IResult<&str, Vec<&str>> = many0(alt((
|
||||||
map_res(
|
map_res(
|
||||||
|
@ -189,13 +202,15 @@ fn replace_parameter(input: &str, headers: &HeaderMap, data: &serde_json::Value)
|
||||||
Ok(result.join(""))
|
Ok(result.join(""))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn number_to_string(number: &serde_json::Number) -> String {
|
fn get_string(value: &serde_json::Value) -> Result<String> {
|
||||||
if number.is_f64() {
|
match &value {
|
||||||
return number.as_f64().unwrap().to_string();
|
serde_json::Value::Null => unimplemented!(),
|
||||||
} else if number.is_i64() {
|
serde_json::Value::Bool(_bool) => unimplemented!(),
|
||||||
return number.as_i64().unwrap().to_string();
|
serde_json::Value::Number(number) => Ok(number.to_string()),
|
||||||
|
serde_json::Value::String(string) => Ok(string.as_str().to_string()),
|
||||||
|
serde_json::Value::Array(_array) => unimplemented!(),
|
||||||
|
serde_json::Value::Object(_object) => unimplemented!(),
|
||||||
}
|
}
|
||||||
number.as_u64().unwrap().to_string()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_match(
|
fn filter_match(
|
||||||
|
@ -204,27 +219,45 @@ fn filter_match(
|
||||||
filter_name: &str,
|
filter_name: &str,
|
||||||
filter: &Filter,
|
filter: &Filter,
|
||||||
request: &Request,
|
request: &Request,
|
||||||
data: &serde_json::Value,
|
data: &mut serde_json::Value,
|
||||||
) -> Result<Option<String>> {
|
) -> Result<Option<String>> {
|
||||||
trace!("Matching filter `{}` of hook `{}`", filter_name, hook_name);
|
trace!("Matching filter `{}` of hook `{}`", filter_name, hook_name);
|
||||||
|
|
||||||
let regex = Regex::new(&filter.regex)?;
|
let regex = Regex::new(&filter.regex)?;
|
||||||
|
|
||||||
|
let parameters = hook.command.clone();
|
||||||
|
let parameters = get_parameter(¶meters)?;
|
||||||
|
|
||||||
|
for parameter in parameters {
|
||||||
|
let parameter = parameter.trim();
|
||||||
|
trace!("Replacing parameter `{}`", parameter);
|
||||||
|
trace!("Pointer parameter `{:?}`", data.pointer(parameter));
|
||||||
|
if let Some(json_value) = data.pointer(parameter) {
|
||||||
|
*data.pointer_mut(parameter).unwrap() = match json_value {
|
||||||
|
serde_json::Value::String(string) => {
|
||||||
|
serde_json::Value::String(string.to_string())
|
||||||
|
}
|
||||||
|
serde_json::Value::Number(number) => {
|
||||||
|
serde_json::Value::String(number.to_string())
|
||||||
|
}
|
||||||
|
x => {
|
||||||
|
error!("Could not get string from: {:?}", x);
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
trace!("Ignoring parameter `{}`", parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(value) = data.pointer(&filter.pointer) {
|
if let Some(value) = data.pointer(&filter.pointer) {
|
||||||
let value = match &value {
|
let value = get_string(value)?;
|
||||||
serde_json::Value::Null => unimplemented!(),
|
|
||||||
serde_json::Value::Bool(_bool) => unimplemented!(),
|
|
||||||
serde_json::Value::Number(number) => number_to_string(number),
|
|
||||||
serde_json::Value::String(string) => string.as_str().to_string(),
|
|
||||||
serde_json::Value::Array(_array) => unimplemented!(),
|
|
||||||
serde_json::Value::Object(_object) => unimplemented!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if regex.is_match(&value) {
|
if regex.is_match(&value) {
|
||||||
debug!("Filter `{}` of hook `{}` matched", filter_name, hook_name);
|
debug!("Filter `{}` of hook `{}` matched", filter_name, hook_name);
|
||||||
|
|
||||||
return Ok(Some(replace_parameter(
|
return Ok(Some(replace_parameter(
|
||||||
&hook.command.to_string(),
|
&hook.command,
|
||||||
&request.headers(),
|
&request.headers(),
|
||||||
data,
|
data,
|
||||||
)?));
|
)?));
|
||||||
|
@ -233,8 +266,7 @@ fn filter_match(
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"Filter `{}` of hook `{}` did not match",
|
"Filter `{}` of hook `{}` did not match",
|
||||||
filter_name,
|
filter_name, hook_name
|
||||||
hook_name
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
@ -265,7 +297,7 @@ fn execute_hooks(request: &Request, data: Data) -> Result<Hooks, WebhookeyError>
|
||||||
|
|
||||||
valid = true;
|
valid = true;
|
||||||
|
|
||||||
let data: serde_json::Value =
|
let mut data: serde_json::Value =
|
||||||
serde_json::from_slice(&buffer).map_err(WebhookeyError::Serde)?;
|
serde_json::from_slice(&buffer).map_err(WebhookeyError::Serde)?;
|
||||||
|
|
||||||
for (filter_name, filter) in &hook.filters {
|
for (filter_name, filter) in &hook.filters {
|
||||||
|
@ -275,7 +307,7 @@ fn execute_hooks(request: &Request, data: Data) -> Result<Hooks, WebhookeyError>
|
||||||
&filter_name,
|
&filter_name,
|
||||||
&filter,
|
&filter,
|
||||||
&request,
|
&request,
|
||||||
&data,
|
&mut data,
|
||||||
) {
|
) {
|
||||||
Ok(Some(command)) => {
|
Ok(Some(command)) => {
|
||||||
hooks.insert(hook_name.to_string(), command);
|
hooks.insert(hook_name.to_string(), command);
|
||||||
|
|
Loading…
Reference in a new issue