Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

github-on-prem: repos setup #73

Merged
merged 14 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 18 additions & 40 deletions vibi-dpu/src/bitbucket/auth.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::env;
use std::str;
use std::process::Command;
use std::time::{SystemTime, UNIX_EPOCH};
use crate::db::auth::{save_auth_info_to_db, auth_info};
use crate::db::bitbucket::auth::{save_bitbucket_auth_info_to_db, bitbucket_auth_info};
use crate::utils::gitops::set_git_remote_url;
use crate::utils::reqwest_client::get_client;
use crate::utils::auth::AuthInfo;
use crate::utils::bitbucket_auth_info::BitbucketAuthInfo;
use crate::utils::review::Review;

pub async fn get_access_token_from_bitbucket(code: &str) -> Option<AuthInfo> {
pub async fn get_access_token_from_bitbucket(code: &str) -> Option<BitbucketAuthInfo> {
let client = get_client();
let bitbucket_client_id = env::var("BITBUCKET_CLIENT_ID").unwrap();
let bitbucket_client_secret = env::var("BITBUCKET_CLIENT_SECRET").unwrap();
Expand Down Expand Up @@ -39,40 +39,40 @@ pub async fn get_access_token_from_bitbucket(code: &str) -> Option<AuthInfo> {
);
return None;
}
let parse_res = res.json::<AuthInfo>().await ;
let parse_res = res.json::<BitbucketAuthInfo>().await ;
if parse_res.is_err() {
let e = parse_res.expect_err("No error in parse_res for AuthInfo");
eprintln!("error deserializing AuthInfo: {:?}", e);
let e = parse_res.expect_err("No error in parse_res for BitbucketAuthInfo");
eprintln!("error deserializing BitbucketAuthInfo: {:?}", e);
return None;
}
let mut response_json = parse_res.expect("Uncaught error in parse_res for AuthInfo");
save_auth_info_to_db(&mut response_json);
let mut response_json = parse_res.expect("Uncaught error in parse_res for BitbucketAuthInfo");
save_bitbucket_auth_info_to_db(&mut response_json);
return Some(response_json);
}

pub async fn refresh_git_auth(clone_url: &str, directory: &str) -> Option<String>{
let authinfo_opt = auth_info();
let authinfo_opt = bitbucket_auth_info();
if authinfo_opt.is_none() {
return None;
}
let authinfo = authinfo_opt.expect("empty authinfo_opt in refresh_git_auth");
let authinfo_opt = update_access_token(&authinfo, clone_url, directory).await;
if authinfo_opt.is_none() {
eprintln!("Empty authinfo_opt from update_access_token");
eprintln!("Empty authinfo_opt from update_access_token for BitbucketAuthInfo");
return None;
}
let latest_authinfo = authinfo_opt.expect("Empty authinfo_opt");
let access_token = latest_authinfo.access_token().to_string();
return Some(access_token);
}

pub async fn update_access_token(auth_info: &AuthInfo,
clone_url: &str, directory: &str) -> Option<AuthInfo> {
pub async fn update_access_token(auth_info: &BitbucketAuthInfo, clone_url: &str, directory: &str) -> Option<BitbucketAuthInfo> {
let repo_provider = "bitbucket".to_string();
let now = SystemTime::now();
let now_secs = now.duration_since(UNIX_EPOCH).expect("Time went backwards").as_secs();
let timestamp_opt = auth_info.timestamp();
if timestamp_opt.is_none() {
eprintln!("No timestamp in authinfo");
eprintln!("No timestamp in BitbucketAuthInfo");
return None;
}
let timestamp = timestamp_opt.expect("Empty timestamp");
Expand All @@ -88,12 +88,12 @@ pub async fn update_access_token(auth_info: &AuthInfo,
.expect("empty auhtinfo_opt from update_access_token");
println!("New auth info = {:?}", &new_auth_info);
let access_token = new_auth_info.access_token().to_string();
set_git_remote_url(clone_url, directory, &access_token);
save_auth_info_to_db(&mut new_auth_info);
set_git_remote_url(clone_url, directory, &access_token, &repo_provider);
save_bitbucket_auth_info_to_db(&mut new_auth_info);
return new_auth_info_opt;
}

async fn bitbucket_refresh_token(refresh_token: &str) -> Option<AuthInfo> {
async fn bitbucket_refresh_token(refresh_token: &str) -> Option<BitbucketAuthInfo> {
let token_url = "https://bitbucket.org/site/oauth2/access_token";
let client_id = std::env::var("BITBUCKET_CLIENT_ID")
.expect("BITBUCKET_CLIENT_ID must be set");
Expand Down Expand Up @@ -134,30 +134,8 @@ async fn bitbucket_refresh_token(refresh_token: &str) -> Option<AuthInfo> {
return Some(refresh_token_resbody);
}

fn set_git_remote_url(git_url: &str, directory: &str, access_token: &str) {
let clone_url = git_url.to_string()
.replace("git@", format!("https://x-token-auth:{{{access_token}}}@").as_str())
.replace("bitbucket.org:", "bitbucket.org/");
let output = Command::new("git")
.arg("remote").arg("set-url").arg("origin")
.arg(clone_url)
.current_dir(directory)
.output()
.expect("failed to execute git pull");
// Only for debug purposes
match str::from_utf8(&output.stderr) {
Ok(v) => println!("set_git_url stderr = {:?}", v),
Err(e) => eprintln!("set_git_url stderr error: {}", e),
};
match str::from_utf8(&output.stdout) {
Ok(v) => println!("set_git_urll stdout = {:?}", v),
Err(e) => eprintln!("set_git_url stdout error: {}", e),
};
println!("git pull output = {:?}, {:?}", &output.stdout, &output.stderr);
}

pub async fn get_access_token_review(review: &Review) -> Option<String> {
let authinfo_opt = auth_info();
let authinfo_opt = bitbucket_auth_info();
if authinfo_opt.is_none() {
return None;
}
Expand Down
2 changes: 1 addition & 1 deletion vibi-dpu/src/bitbucket/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub async fn get_workspace_repos(workspace: &str, access_token: &str) -> Option<
.expect("Unable to convert clone to array").iter().filter(|clone_val| {
clone_val["name".to_string()].as_str() == Some("ssh")
}).collect::<Vec<&Value>>()[0]["href"].to_string().replace('\"',""),
repo_json["project"]["name"].to_string().trim_matches('"').to_string(),
Some(repo_json["project"]["name"].to_string().trim_matches('"').to_string()),
repo_json["workspace"]["slug"].to_string().trim_matches('"').to_string(),
None,
"bitbucket".to_string(),
Expand Down
9 changes: 3 additions & 6 deletions vibi-dpu/src/bitbucket/user.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use chrono::{DateTime, Utc, FixedOffset};
use crate::db::auth::auth_info;
use crate::db::bitbucket::auth::bitbucket_auth_info;
use crate::db::user::{add_bitbucket_user_to_workspace_user, get_workspace_user_from_db};
use crate::utils::auth::AuthInfo;
use crate::utils::lineitem::LineItem;
use crate::utils::user::{BitbucketUser, User, Provider, ProviderEnum};
use crate::utils::user::BitbucketUser;
use super::config::{bitbucket_base_url, get_api_values, get_api_response};

pub async fn get_and_save_workspace_users(workspace_id: &str, access_token: &str) {
Expand All @@ -22,7 +19,7 @@ pub async fn author_from_commit(commit: &str, repo_name: &str, repo_owner: &str)
let base_url = bitbucket_base_url();
let commits_url = format!("{}/repositories/{}/{}/commit/{}", &base_url, repo_owner, repo_name, commit);
println!("commits url = {}", &commits_url);
let authinfo_opt = auth_info();
let authinfo_opt = bitbucket_auth_info();
if authinfo_opt.is_none() {
return None;
}
Expand Down
12 changes: 4 additions & 8 deletions vibi-dpu/src/core/bitbucket/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@ use crate::bitbucket::prs::{list_prs_bitbucket, get_and_store_pr_info};
use crate::db::repo::save_repo_to_db;
use crate::db::webhook::save_webhook_to_db;
use crate::utils::repo::Repository;

#[derive(Debug, Deserialize, Serialize, Clone)]
struct SetupInfo {
provider: String,
owner: String,
repos: Vec<String>,
}
use crate::utils::setup_info::SetupInfo;

#[derive(Debug, Deserialize, Serialize, Clone)]
struct PublishRequest {
Expand Down Expand Up @@ -89,7 +83,8 @@ pub async fn handle_install_bitbucket(installation_code: &str) {
pubreqs.push(SetupInfo {
provider: "bitbucket".to_owned(),
owner: workspace_slug.clone(),
repos: reponames });
repos: reponames
});
}
send_setup_info(&pubreqs).await;
}
Expand Down Expand Up @@ -123,6 +118,7 @@ async fn send_setup_info(setup_info: &Vec<SetupInfo>) {

async fn clone_git_repo(repo: &mut Repository, access_token: &str) {
let git_url = repo.clone_ssh_url();
// call function for provider specific git url formatting
let clone_url = git_url.to_string()
.replace("git@", format!("https://x-token-auth:{{{access_token}}}@").as_str())
.replace("bitbucket.org:", "bitbucket.org/");
Expand Down
53 changes: 27 additions & 26 deletions vibi-dpu/src/core/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,35 @@ pub async fn process_coverage(hunkmap: &HunkMap, review: &Review, repo_config: &
println!("!coverage_map.is_empty() = {:?}", &coverage_cond);
println!("repo_config.comment() = {:?}", repo_config.comment());
println!("repo_config.auto_assign() = {:?}", repo_config.auto_assign());
if !coverage_map.is_empty() {
if repo_config.comment() {
println!("Inserting comment...");
// create comment text
let comment = comment_text(coverage_map, repo_config.auto_assign());
// add comment
add_comment(&comment, review, &access_token).await;
}
if repo_config.auto_assign() {
let mut author_set: HashSet<String> = HashSet::new();
author_set.insert(prhunk.author().to_string());
for blame in prhunk.blamevec() {
let blame_author_opt = author_from_commit(blame.commit(),
hunkmap.repo_name(), hunkmap.repo_owner()).await;
if blame_author_opt.is_none() {
eprintln!("[process_coverage] Unable to get blame author from bb for commit: {}", &blame.commit());
continue;
}
let blame_author = blame_author_opt.expect("Empty blame_author_opt");
let author_uuid = blame_author.uuid();
if author_set.contains(author_uuid) {
continue;
}
add_reviewers(&blame_author, review, &access_token).await;
author_set.insert(author_uuid.to_string());
if coverage_map.is_empty() {
continue;
}
if repo_config.comment() {
println!("Inserting comment...");
// create comment text
let comment = comment_text(coverage_map, repo_config.auto_assign());
// add comment
add_comment(&comment, review, &access_token).await;
}
if repo_config.auto_assign() {
let mut author_set: HashSet<String> = HashSet::new();
author_set.insert(prhunk.author().to_string());
for blame in prhunk.blamevec() {
let blame_author_opt = author_from_commit(blame.commit(),
hunkmap.repo_name(), hunkmap.repo_owner()).await;
if blame_author_opt.is_none() {
eprintln!("[process_coverage] Unable to get blame author from bb for commit: {}", &blame.commit());
continue;
}
let blame_author = blame_author_opt.expect("Empty blame_author_opt");
let author_uuid = blame_author.uuid();
if author_set.contains(author_uuid) {
continue;
}
add_reviewers(&blame_author, review, &access_token).await;
author_set.insert(author_uuid.to_string());
}
}
}
}
}

Expand Down
36 changes: 18 additions & 18 deletions vibi-dpu/src/core/github/setup.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
// setup_gh.rs

use crate::github::auth::fetch_access_token; // Import shared utilities
use reqwest::Client;
use serde::{Deserialize, Serialize};
use tokio::task;

#[derive(Debug, Deserialize, Serialize, Clone)]
struct SetupInfoGithub {
provider: String,
owner: String,
repos: Vec<String>,
}
use crate::github::auth::fetch_access_token; // Import shared utilities
use crate::utils::setup_info::SetupInfo;
use crate::github::repos::get_github_app_installed_repos;

#[derive(Debug, Deserialize, Serialize, Clone)]
struct PublishRequestGithub {
installationId: String,
info: Vec<SetupInfoGithub>,
info: Vec<SetupInfo>,
}

pub async fn handle_install_github(installation_code: &str) {
// TODO: Implement the logic to handle GitHub installation

// For example:
// 1. Get access token from GitHub using the installation code
let auth_info = fetch_access_token(installation_code).await;
println!("[handle_install_github] auth_info = {:?}", &auth_info);
let authinfo_opt = fetch_access_token(installation_code).await;
println!("[handle_install_github] auth_info = {:?}", &authinfo_opt);
if authinfo_opt.is_none() {
eprintln!("Unable to get authinfo from fetch_access_token in Github setup");;
return;
}
let authinfo = authinfo_opt.expect("Empty authinfo_opt");
let access_token = authinfo.access_token().clone();
let mut pubreqs: Vec<SetupInfo> = Vec::new();

let repos = get_github_app_installed_repos(&access_token).await;
println!("Got repos: {:?}", repos);

// 2. Fetch user repositories and other necessary data
// 3. Process webhooks or other setup tasks
// 4. Send setup info or any other post-processing
}

async fn get_github_repositories(access_token: &str) -> Vec<String> {
// TODO: Implement the logic to fetch user repositories from GitHub
Vec::new()
}

async fn process_webhooks_github(repo_name: String, access_token: String) {
// TODO: Implement the logic to process GitHub webhooks
}

async fn send_setup_info_github(setup_info: &Vec<SetupInfoGithub>) {
async fn send_setup_info_github(setup_info: &Vec<SetupInfo>) {
// TODO: Implement the logic to send setup info for GitHub
}

Expand Down
16 changes: 8 additions & 8 deletions vibi-dpu/src/db/auth.rs → vibi-dpu/src/db/bitbucket/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use std::time::UNIX_EPOCH;
use sled::IVec;

use crate::db::config::get_db;
use crate::utils::auth::AuthInfo;
use crate::utils::bitbucket_auth_info::BitbucketAuthInfo;

pub fn save_auth_info_to_db(auth_info: &mut AuthInfo) {
pub fn save_bitbucket_auth_info_to_db(auth_info: &mut BitbucketAuthInfo) {
let db = get_db();
let now = SystemTime::now();
let since_epoch = now.duration_since(UNIX_EPOCH).expect("Time went backwards");
Expand All @@ -22,13 +22,13 @@ pub fn save_auth_info_to_db(auth_info: &mut AuthInfo) {
let insert_res = db.insert("bitbucket_auth_info", ivec);
if insert_res.is_err() {
let e = insert_res.expect_err("No error in insert_res");
eprintln!("Failed to upsert auth info into sled DB: {e}");
eprintln!("Failed to upsert bitbucket auth info into sled DB: {e}");
return;
}
println!("AuthInfo succesfully upserted: {:?}", auth_info);
println!("BitbucketAuthInfo succesfully upserted: {:?}", auth_info);
}

pub fn auth_info() -> Option<AuthInfo> {
pub fn bitbucket_auth_info() -> Option<BitbucketAuthInfo> {
let db = get_db();
let authinfo_key = "bitbucket_auth_info";
let authinfo_res = db.get(IVec::from(authinfo_key.as_bytes()));
Expand All @@ -46,9 +46,9 @@ pub fn auth_info() -> Option<AuthInfo> {
let authinfo_parse = serde_json::from_slice(&authinfo_ivec);
if authinfo_parse.is_err() {
let e = authinfo_parse.expect_err("No error in authinfo_parse");
eprintln!("Unable to deserialize authinfo_parse: {:?}", e);
eprintln!("Unable to deserialize bitbucket authinfo_parse: {:?}", e);
return None;
}
let authinfo: AuthInfo = authinfo_parse.expect("Uncaught error in authinfo_parse");
return Some(authinfo);
let bitbucket_auth_info: BitbucketAuthInfo = authinfo_parse.expect("Uncaught error in authinfo_parse");
return Some(bitbucket_auth_info);
}
1 change: 1 addition & 0 deletions vibi-dpu/src/db/bitbucket/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod auth;
Loading