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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user