about to port to actix-web
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
72c88f45a6
commit
0f9110b36c
135
src/main.rs
135
src/main.rs
@ -10,9 +10,10 @@ extern crate staticfile;
|
|||||||
// point your browser to http://127.0.0.1:3000/doc/
|
// point your browser to http://127.0.0.1:3000/doc/
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
use iron::{Iron, IronResult, status};
|
|
||||||
use iron::prelude::{Chain, Request, Response};
|
use iron::prelude::{Chain, Request, Response};
|
||||||
|
use iron::{status, Iron, IronResult};
|
||||||
use mount::Mount;
|
use mount::Mount;
|
||||||
use staticfile::Static;
|
use staticfile::Static;
|
||||||
|
|
||||||
@ -24,51 +25,120 @@ struct WebHookConfig {
|
|||||||
repo_prefixes: Vec<String>,
|
repo_prefixes: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn redeploy_repo(url: &str, path: &Path) -> Result<(), ()> {
|
fn redeploy_repo(url: &str, path: &Path, name: &str) -> Result<(), git2::Error> {
|
||||||
eprintln!("Cloning {}", url);
|
let mut new_path = path.to_path_buf();
|
||||||
let repo = match Repository::clone(url, path) {
|
new_path.push(name);
|
||||||
|
eprintln!("Cloning {} into {:?} ({:?} / {})", url, new_path, path, name);
|
||||||
|
|
||||||
|
let repo = match Repository::open(&new_path) {
|
||||||
Ok(repo) => repo,
|
Ok(repo) => repo,
|
||||||
Err(e) => panic!("failed to clone: {}", e),
|
Err(e) => {
|
||||||
|
eprintln!("can't open repo, going to try cloning it: {}", e.description());
|
||||||
|
match Repository::clone(url, &new_path) {
|
||||||
|
Ok(repo) => repo,
|
||||||
|
Err(e) => panic!("failed to clone: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
repo.set_head("FETCH_HEAD")?;
|
||||||
|
|
||||||
|
// repo.checkout_tree(&branch.into_reference(), Some(git2::build::CheckoutBuilder::new().force().use_theirs(true)))?;
|
||||||
|
repo.checkout_head(Some(git2::build::CheckoutBuilder::new().force().use_theirs(true)))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn webhook(req: &mut Request, config: &WebHookConfig) -> IronResult<Response> {
|
fn webhook(req: &mut Request, config: &WebHookConfig) -> IronResult<Response> {
|
||||||
eprintln!("Webhook Request: {:?}", req);
|
eprintln!("Webhook Request: {:?}", req);
|
||||||
let v: serde_json::Value = serde_json::from_reader(&mut req.body).unwrap();
|
let wh: serde_json::Value = serde_json::from_reader(&mut req.body).unwrap();
|
||||||
|
|
||||||
if let Some(found_secret) = v.get("secret") {
|
// Ensure we have a "Secret" parameter, and that it matches the config.
|
||||||
if found_secret != &config.secret {
|
let found_secret = wh.get("secret");
|
||||||
return Ok(Response::with(status::Unauthorized));
|
if found_secret.is_none() {
|
||||||
}
|
return Ok(Response::with(status::Unauthorized));
|
||||||
}
|
}
|
||||||
else {
|
let found_secret = found_secret.unwrap();
|
||||||
|
if found_secret != &config.secret {
|
||||||
return Ok(Response::with(status::Unauthorized));
|
return Ok(Response::with(status::Unauthorized));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(repository) = v.get("repository") {
|
// Ensure the repo is valid.
|
||||||
if let Some(html_url) = repository.get("html_url") {
|
let repository = wh.get("repository");
|
||||||
if let Some(html_url_str) = html_url.as_str() {
|
if repository.is_none() {
|
||||||
if html_url_str.starts_with("https://git.xobs.io/xobs") {
|
eprintln!("No 'repository' key found");
|
||||||
redeploy_repo(html_url_str, &Path::new("C:\\Code\\talkserved"));
|
return Ok(Response::with(status::PreconditionRequired));
|
||||||
}
|
}
|
||||||
else {
|
let repository = repository.unwrap();
|
||||||
eprintln!("HTML URL isn't a string");
|
|
||||||
}
|
// Ensure there's an HTML URL that's a valid string
|
||||||
}
|
let html_url = match repository.get("html_url") {
|
||||||
else {
|
None => {
|
||||||
eprintln!("URL doesn't start with match");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
eprintln!("No HTML URL found");
|
eprintln!("No HTML URL found");
|
||||||
|
return Ok(Response::with(status::PreconditionRequired));
|
||||||
|
}
|
||||||
|
Some(s) => match s.as_str() {
|
||||||
|
None => {
|
||||||
|
eprintln!("HTML URL isn't a string");
|
||||||
|
return Ok(Response::with(status::PreconditionRequired));
|
||||||
|
}
|
||||||
|
Some(s) => s,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check to make sure the repo prefix is one we recognize
|
||||||
|
let mut found_match = false;
|
||||||
|
for prefix in &config.repo_prefixes {
|
||||||
|
if html_url.starts_with(prefix) {
|
||||||
|
found_match = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
if !found_match {
|
||||||
eprintln!("No repository key found");
|
eprintln!("URL doesn't start with match");
|
||||||
|
return Ok(Response::with(status::PreconditionRequired));
|
||||||
}
|
}
|
||||||
// eprintln!("Value: {:?}", v);
|
|
||||||
|
// And ensure the URL is a string
|
||||||
|
let website_url = match repository.get("website") {
|
||||||
|
None => {
|
||||||
|
eprintln!("The website isn't configured for this repo");
|
||||||
|
return Ok(Response::with(status::PreconditionRequired));
|
||||||
|
}
|
||||||
|
Some(s) => match s.as_str() {
|
||||||
|
None => {
|
||||||
|
eprintln!("Website URL isn't a string");
|
||||||
|
return Ok(Response::with(status::PreconditionRequired));
|
||||||
|
}
|
||||||
|
Some(s) => match iron::Url::parse(s) {
|
||||||
|
Ok(u) => u,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Unable to parse URL: {:?}", e);
|
||||||
|
return Ok(Response::with(status::PreconditionFailed));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let target_path = match website_url.path().last() {
|
||||||
|
Some(s) => {
|
||||||
|
if s.is_empty() {
|
||||||
|
eprintln!("No website URL path was found -- defaulting to \"current\"");
|
||||||
|
"current".to_owned()
|
||||||
|
} else {
|
||||||
|
s.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
eprintln!("No website URL path was found");
|
||||||
|
return Ok(Response::with(status::PreconditionFailed));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
eprintln!("Final path: {:?} / {:?}", config.repo_root, target_path);
|
||||||
|
|
||||||
|
if let Err(e) = redeploy_repo(html_url, &config.repo_root, &target_path) {
|
||||||
|
eprintln!("unable to clone/update repo: {}", e.description());
|
||||||
|
return Ok(Response::with(status::NotModified));
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Response::with(status::Ok))
|
Ok(Response::with(status::Ok))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,9 +155,10 @@ fn main() {
|
|||||||
mount.mount("/", Static::new(config.repo_root.clone()));
|
mount.mount("/", Static::new(config.repo_root.clone()));
|
||||||
|
|
||||||
// Listen for calls to "/webhook" and process accordingly
|
// Listen for calls to "/webhook" and process accordingly
|
||||||
mount.mount("/webhook", Chain::new(move |req: &mut Request| {
|
mount.mount(
|
||||||
webhook(req, &config)
|
"/webhook",
|
||||||
}));
|
Chain::new(move |req: &mut Request| webhook(req, &config)),
|
||||||
|
);
|
||||||
|
|
||||||
println!("Doc server running on http://{}", hostaddr);
|
println!("Doc server running on http://{}", hostaddr);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user