Implement secret functionality
In order to validate requests a field called `secret` has to be sent containing a secret key which validates the request. A hook will be executed only if the secret sent with the request matches the hook's secret.
This commit is contained in:
parent
ea19c7e413
commit
b370d59b40
3 changed files with 33 additions and 12 deletions
|
@ -53,6 +53,7 @@ Right now there is only the configuration parameter for hooks, here
|
||||||
each hook has to be configured, It contains following fields:
|
each hook has to be configured, It contains following fields:
|
||||||
- action: optional string for the action to be executed when all
|
- action: optional string for the action to be executed when all
|
||||||
filters match
|
filters match
|
||||||
|
- secrets: list of secrets
|
||||||
- filters: list of filters
|
- filters: list of filters
|
||||||
|
|
||||||
Each filter has to have following fields:
|
Each filter has to have following fields:
|
||||||
|
|
21
config.yml
21
config.yml
|
@ -1,17 +1,22 @@
|
||||||
---
|
---
|
||||||
hooks:
|
hooks:
|
||||||
hook1:
|
hook1:
|
||||||
action: "echo hookaction1"
|
action: /usr/bin/local/script_xy.sh
|
||||||
|
secrets:
|
||||||
|
- secret_key_01
|
||||||
|
- secret_key_02
|
||||||
filters:
|
filters:
|
||||||
match_ref:
|
match_ref:
|
||||||
pointer: "/ref"
|
pointer: /ref
|
||||||
regex: "refs/heads/master"
|
regex: refs/heads/master
|
||||||
hook2:
|
hook2:
|
||||||
action: "echo hookaction2"
|
action: /usr/bin/local/script_xyz.sh
|
||||||
|
secrets:
|
||||||
|
- secret_key03
|
||||||
filters:
|
filters:
|
||||||
match_ref:
|
match_ref:
|
||||||
pointer: "/ref"
|
pointer: /ref
|
||||||
regex: "refs/heads/master"
|
regex: refs/heads/master
|
||||||
match_after:
|
match_after:
|
||||||
pointer: "/after"
|
pointer: /after
|
||||||
regex: "f6e5fe4fe37df76629112d55cc210718b6a55e7e"
|
regex: f6e5fe4fe37df76629112d55cc210718b6a55e7e
|
||||||
|
|
21
src/main.rs
21
src/main.rs
|
@ -1,7 +1,7 @@
|
||||||
#![feature(proc_macro_hygiene, decl_macro)]
|
#![feature(proc_macro_hygiene, decl_macro)]
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use log::{debug, info, trace};
|
use log::{debug, info, trace, warn};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rocket::{fairing::AdHoc, get, post, routes, State};
|
use rocket::{fairing::AdHoc, get, post, routes, State};
|
||||||
use rocket_contrib::json::Json;
|
use rocket_contrib::json::Json;
|
||||||
|
@ -17,6 +17,7 @@ struct Config {
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
struct Hook {
|
struct Hook {
|
||||||
action: Option<String>,
|
action: Option<String>,
|
||||||
|
secrets: Vec<String>,
|
||||||
filters: HashMap<String, Filter>,
|
filters: HashMap<String, Filter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ fn execute_hook(name: &str, hook: &Hook, data: &serde_json::Value) -> Result<()>
|
||||||
if let Some(action) = &hook.action {
|
if let Some(action) = &hook.action {
|
||||||
info!("Execute `{}` from hook `{}`", action, name);
|
info!("Execute `{}` from hook `{}`", action, name);
|
||||||
|
|
||||||
let action = action.split(" ").collect::<Vec<&str>>();
|
let action = action.split(' ').collect::<Vec<&str>>();
|
||||||
|
|
||||||
let command = Command::new(action[0]).args(&action[1..]).output()?;
|
let command = Command::new(action[0]).args(&action[1..]).output()?;
|
||||||
|
|
||||||
|
@ -91,9 +92,23 @@ fn receive_hook(address: SocketAddr, config: State<Config>, data: Json<Data>) ->
|
||||||
|
|
||||||
trace!("Data received from: {}\n{}", address, data);
|
trace!("Data received from: {}\n{}", address, data);
|
||||||
|
|
||||||
for (hook_name, hook) in config.hooks.iter() {
|
if let Some(secret) = data.pointer("secret") {
|
||||||
|
if let Some(secret) = secret.as_str() {
|
||||||
|
let hooks: HashMap<&String, &Hook> = config
|
||||||
|
.hooks
|
||||||
|
.iter()
|
||||||
|
.filter(|(_hook_name, hook)| hook.secrets.contains(&secret.to_string()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if hooks.is_empty() {
|
||||||
|
warn!("Secret did not match any hook");
|
||||||
|
} else {
|
||||||
|
for (hook_name, hook) in hooks {
|
||||||
execute_hook(&hook_name, &hook, &data)?;
|
execute_hook(&hook_name, &hook, &data)?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok("Request received.".to_string())
|
Ok("Request received.".to_string())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue