Adapt to new versions of rocket and clap

Use clap `3.0.0-beta.5` and rocket `0.5.0-rc.1`.
This commit is contained in:
finga 2021-11-03 13:09:44 +01:00
parent 41d8efe8a8
commit 5a88fb892b
3 changed files with 1169 additions and 437 deletions

1525
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -11,7 +11,7 @@ description = "Trigger scripts via http(s) requests"
tls = ["rocket/tls"]
[dependencies]
rocket = "0.4"
rocket = "0.5.0-rc.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.8"
@ -27,7 +27,7 @@ hex = "0.4"
ipnet = { version = "2.3", features = ["serde"] }
thiserror = "1.0"
run_script = "0.7"
clap = "3.0.0-beta.4"
clap = "3.0.0-beta.5"
[package.metadata.deb]
extended-description = "Webhookey receives requests in form of a so called Webhook as for example sent by Gitea. Those requests are matched against configured filters, if a filter matches, values from the header and the body can be passed to scripts as parameters which are then executed subsequently."

View file

@ -1,7 +1,7 @@
#![feature(proc_macro_hygiene, decl_macro)]
use anyhow::{anyhow, bail, Result};
use clap::{crate_authors, crate_version, AppSettings, Clap};
use clap::{crate_authors, crate_version, AppSettings, Parser};
use hmac::{Hmac, Mac, NewMac};
use ipnet::IpNet;
use log::{debug, error, info, trace, warn};
@ -15,12 +15,13 @@ use nom::{
};
use regex::Regex;
use rocket::{
data::{self, FromDataSimple},
fairing::AdHoc,
data::{FromData, ToByteUnit},
futures::TryFutureExt,
http::{HeaderMap, Status},
post, routes, Data,
Outcome::{Failure, Success},
Request, Response, State,
outcome::Outcome::{self, Failure, Success},
post, routes,
tokio::io::AsyncReadExt,
Data, Request, State,
};
use run_script::ScriptOptions;
use serde::{Deserialize, Serialize};
@ -30,7 +31,7 @@ use thiserror::Error;
use std::{
collections::HashMap,
fs::File,
io::{BufReader, Read},
io::BufReader,
net::{IpAddr, Ipv4Addr, SocketAddr},
};
@ -54,17 +55,16 @@ enum WebhookeyError {
Regex(regex::Error),
}
#[derive(Clap, Debug)]
#[derive(Debug, Parser)]
enum Command {
/// Verifies if the configuration can be parsed without errors
Configtest,
}
#[derive(Clap, Debug)]
#[derive(Debug, Parser)]
#[clap(
version = crate_version!(),
author = crate_authors!(", "),
global_setting = AppSettings::ColoredHelp,
global_setting = AppSettings::InferSubcommands,
global_setting = AppSettings::PropagateVersion,
)]
@ -242,15 +242,16 @@ struct Hooks {
}
impl Hooks {
fn get_commands(request: &Request, data: Data) -> Result<Self, WebhookeyError> {
async fn get_commands(request: &Request<'_>, data: Data<'_>) -> Result<Self, WebhookeyError> {
let mut buffer = Vec::new();
let size = data
.open()
.open(256_i32.kilobytes())
.read_to_end(&mut buffer)
.map_err(WebhookeyError::Io)?;
.map_err(WebhookeyError::Io)
.await?;
info!("Data of size {} received", size);
let config = request.guard::<State<Config>>().unwrap(); // should never fail
let config = request.guard::<&State<Config>>().await.unwrap(); // should never fail
let mut valid = false;
let mut result = HashMap::new();
let client_ip = &request
@ -318,11 +319,15 @@ impl Hooks {
}
}
impl FromDataSimple for Hooks {
#[rocket::async_trait]
impl<'r> FromData<'r> for Hooks {
type Error = WebhookeyError;
fn from_data(request: &Request, data: Data) -> data::Outcome<Self, Self::Error> {
match Hooks::get_commands(request, data) {
async fn from_data(
request: &'r Request<'_>,
data: Data<'r>,
) -> Outcome<Self, (Status, Self::Error), Data<'r>> {
match Hooks::get_commands(request, data).await {
Ok(hooks) => {
if hooks.inner.is_empty() {
let client_ip = &request
@ -440,7 +445,7 @@ fn get_string(value: &serde_json::Value) -> Result<String, WebhookeyError> {
}
#[post("/", format = "json", data = "<hooks>")]
fn receive_hook<'a>(address: SocketAddr, hooks: Hooks) -> Result<Response<'a>> {
async fn receive_hook<'a>(address: SocketAddr, hooks: Hooks) -> Status {
info!("Post request received from: {}", address);
hooks.inner.iter().for_each(|(name, command)| {
@ -458,7 +463,7 @@ fn receive_hook<'a>(address: SocketAddr, hooks: Hooks) -> Result<Response<'a>> {
}
});
Ok(Response::new())
Status::Ok
}
fn get_config() -> Result<File> {
@ -494,7 +499,8 @@ fn get_config() -> Result<File> {
bail!("No configuration file found.");
}
fn main() -> Result<()> {
#[rocket::main]
async fn main() -> Result<()> {
env_logger::init();
let cli: Opts = Opts::parse();
@ -512,12 +518,11 @@ fn main() -> Result<()> {
return Ok(());
}
rocket::ignite()
rocket::build()
.mount("/", routes![receive_hook])
.attach(AdHoc::on_attach("webhookey config", move |rocket| {
Ok(rocket.manage(config))
}))
.launch();
.manage(config)
.launch()
.await?;
Ok(())
}
@ -527,12 +532,12 @@ mod tests {
use super::*;
use rocket::{
http::{ContentType, Header},
local::Client,
local::asynchronous::Client,
};
use serde_json::json;
#[test]
fn secret() {
#[rocket::async_test]
async fn secret() {
let mut hooks = HashMap::new();
hooks.insert(
@ -551,13 +556,11 @@ mod tests {
let config = Config { hooks: hooks };
let rocket = rocket::ignite()
let rocket = rocket::build()
.mount("/", routes![receive_hook])
.attach(AdHoc::on_attach("webhookey config", move |rocket| {
Ok(rocket.manage(config))
}));
.manage(config);
let client = Client::new(rocket).unwrap();
let client = Client::tracked(rocket).await.unwrap();
let response = client
.post("/")
.header(Header::new(
@ -569,7 +572,7 @@ mod tests {
.body(&serde_json::to_string(&json!({ "foo": "bar" })).unwrap())
.dispatch();
assert_eq!(response.status(), Status::NotFound);
assert_eq!(response.await.status(), Status::NotFound);
let response = client
.post("/")
@ -579,7 +582,7 @@ mod tests {
.body(&serde_json::to_string(&json!({ "foo": "bar" })).unwrap())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
assert_eq!(response.await.status(), Status::Unauthorized);
let response = client
.post("/")
@ -592,7 +595,7 @@ mod tests {
.body(r#"{ "not_secret": "invalid" "#)
.dispatch();
assert_eq!(response.status(), Status::BadRequest);
assert_eq!(response.await.status(), Status::BadRequest);
let response = client
.post("/")
@ -601,7 +604,7 @@ mod tests {
.remote("127.0.0.1:8000".parse().unwrap())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
assert_eq!(response.await.status(), Status::Unauthorized);
}
#[test]