use regex::Regex;
struct RegexFields;
impl RegexFields {
const GITHUB_URL: &'static str =
r"^((https?|ssh|git|ftps?)://)?(([^/@]+)@)?([^/:]+)[/:]([^/:]+)/(.+)(git)?$";
const GITHUB_URL_PROFILE: &'static str =
r"^((https?|ssh|git|ftps?)://)?(([^/@]+)@)?([^/:]+)[/:]([^/:]+)$";
}
pub fn get_author<'a>(github_url: String) -> Result<String, &'a str> {
match Regex::new(RegexFields::GITHUB_URL) {
Ok(regex) => {
match Regex::new(RegexFields::GITHUB_URL_PROFILE) {
Ok(regex_profile) => {
match regex.captures(github_url.as_str()) {
Some(captures) => {
match captures.get(6) {
Some(item) => Ok(item.as_str().to_string()),
_ => Err("[-] Repository author not found, aborting scan"),
}
}
_ => match regex_profile.captures(github_url.as_str()) {
Some(captures) => match captures.get(6) {
Some(item) => Ok(item.as_str().to_string()),
_ => Err("[-] Author could not be found, aborting scan"),
},
_ => Err("[-] Repository author not found, aborting scan"),
},
}
}
_ => Err("[-] Regex processing went wrong!"),
}
}
_ => Err("[-] Regex processing went wrong!"),
}
}
pub fn get_repository<'a>(github_url: String) -> Result<String, &'a str> {
match Regex::new(RegexFields::GITHUB_URL) {
Ok(regex) => {
match regex.captures(github_url.as_str()) {
Some(captures) => {
match captures.get(7) {
Some(item) => Ok(item.as_str().to_string()),
_ => Err("[-] Repository name not found, aborting scan"),
}
}
_ => {
if !get_author(github_url)?.is_empty() {
Ok("".to_string())
} else {
Err("[-] Repository name not found, aborting scan")
}
}
}
}
_ => Err("[-] Regex processing went wrong!"),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn get_author_git() {
assert_eq!(
get_author("git://github.com/extiop/ctf".to_string()),
Ok("extiop".to_string())
);
}
#[test]
fn get_author_git_at() {
assert_eq!(
get_author("git@github.com/extiop/ctf".to_string()),
Ok("extiop".to_string())
);
}
#[test]
fn get_author_https() {
assert_eq!(
get_author("https://github.com/extiop/ctf".to_string()),
Ok("extiop".to_string())
);
}
#[test]
fn get_author_ssh() {
assert_eq!(
get_author("ssh://github.com/extiop/ctf".to_string()),
Ok("extiop".to_string())
);
}
#[test]
fn get_author_too_short() {
assert_eq!(
get_author("https://github.com".to_string()),
Err("[-] Repository author not found, aborting scan")
);
}
#[test]
fn get_author_too_long() {
assert_eq!(
get_author("https://github.com/github/extiop/ctf".to_string()),
Ok("github".to_string())
);
}
#[test]
fn get_author_swapped() {
assert_eq!(
get_author("https://github.com/ctf/extiop".to_string()),
Ok("ctf".to_string())
);
}
#[test]
fn get_get_repository_git() {
assert_eq!(
get_repository("git://github.com/extiop/ctf".to_string()),
Ok("ctf".to_string())
);
}
#[test]
fn get_get_repository_git_at() {
assert_eq!(
get_repository("git@github.com/extiop/ctf".to_string()),
Ok("ctf".to_string())
);
}
#[test]
fn get_get_repository_https() {
assert_eq!(
get_repository("https://github.com/extiop/ctf".to_string()),
Ok("ctf".to_string())
);
}
#[test]
fn get_get_repository_ssh() {
assert_eq!(
get_repository("ssh://github.com/extiop/ctf".to_string()),
Ok("ctf".to_string())
);
}
#[test]
fn get_repository_no_project() {
assert_eq!(
get_repository("https://github.com/extiop".to_string()),
Ok("".to_string())
);
}
#[test]
fn get_repository_too_long() {
assert_eq!(
get_repository("https://github.com/github/extiop/ctf".to_string()),
Ok("extiop/ctf".to_string())
);
}
#[test]
fn get_repository_swapped() {
assert_eq!(
get_repository("https://github.com/ctf/extiop".to_string()),
Ok("extiop".to_string())
);
}
}