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:
parent
41d8efe8a8
commit
5a88fb892b
3 changed files with 1169 additions and 437 deletions
1525
Cargo.lock
generated
1525
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -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."
|
||||
|
|
77
src/main.rs
77
src/main.rs
|
@ -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]
|
||||
|
|
Loading…
Reference in a new issue