Arbitrary header fields in commands

Adopt the parser to be able to parse header fields.
This commit is contained in:
finga 2021-03-30 01:16:15 +02:00
parent 2c00441b34
commit 8099bf773f
2 changed files with 39 additions and 21 deletions

View file

@ -55,16 +55,26 @@ Configuration syntax is YAML and has to be done in following order:
Right now there is only the configuration parameter for hooks, here
each hook has to be configured, It contains following fields:
- command: String for a command to be executed when all filters
match. Pointers ([RFC 6901](https://tools.ietf.org/html/rfc6901)) to
JSON fields may be used to be replaced with data from the JSON data
with `{{ /field/pointed/to }}`. Further `{{ event }}` and `{{
signature }}` are valid variables as they contain the values from
the regarding header fields of the http request.
- command: A command to be executed if a filter matches
- signature: Name of the HTTP header field containing the signature.
- secrets: List of secrets.
- filters: List of filters.
### Command
To pass data to a command following two different methods can be used.
#### JSON Pointers
Use JSON pointers ([RFC 6901](https://tools.ietf.org/html/rfc6901))
point to values of a JSON field from the JSON data.
Example: `{{ /field/pointed/to }}`.
#### Header
Use values from header fields sent with the HTTP request.
Example: `{{ header X-Gitea-Event }}`.
### Filter
Each filter must have following fields:
- pointer: pointer to the JSON field according to [RFC
6901](https://tools.ietf.org/html/rfc6901)

View file

@ -67,21 +67,29 @@ fn replace_parameter(input: &str, headers: &HeaderMap, data: &serde_json::Value)
let parse: IResult<&str, Vec<&str>> = many0(alt((
map_res(
delimited(tag("{{"), take_until("}}"), tag("}}")),
|param: &str| match param.trim() {
"event" => {
if let Some(event) = headers.get_one("X-Gitea-Event") {
Ok(event)
} else {
bail!("Could not extract event parameter from header");
|param: &str| {
let expr = param.trim().split(' ').collect::<Vec<&str>>();
match expr.get(0) {
Some(&"header") => {
if let Some(field) = expr.get(1) {
match headers.get_one(field) {
Some(value) => Ok(value),
_ => bail!("Could not extract event parameter from header"),
}
} else {
bail!("Missing parameter for `header` expression");
}
}
}
pointer => match data.pointer(pointer) {
Some(value) => match value.as_str() {
Some(value) => Ok(value),
_ => bail!("Could not convert value `{}` to string", value),
Some(pointer) => match data.pointer(pointer) {
Some(value) => match value.as_str() {
Some(value) => Ok(value),
_ => bail!("Could not convert value `{}` to string", value),
},
_ => bail!("Could not convert field `{}` to string", param.trim()),
},
_ => bail!("Could not convert field `{}` to string", param.trim()),
},
None => bail!("Missing expression in `{}`", input),
}
},
),
take_until("{{"),
@ -297,7 +305,7 @@ fn get_config() -> Result<File> {
return Ok(config);
}
bail!("No configuration files found.");
bail!("No configuration file found.");
}
fn main() -> Result<()> {
@ -471,7 +479,7 @@ mod tests {
assert_eq!(
replace_parameter(
" {{ event }} command",
" {{ header X-Gitea-Event }} command",
&map,
&json!({ "field1": { "foo": "bar" } })
)