From 8bf79eadf7aa51f08d7f7d4f0be3f6480352674d Mon Sep 17 00:00:00 2001 From: lowitea Date: Sun, 8 Oct 2023 20:24:53 +0300 Subject: [PATCH] issue-35: add flags for force secure or insecure protocols (#162) --- README.RU.md | 8 ++++++++ README.md | 8 ++++++++ src/cli.rs | 46 +++++++++++++++++++++++++++++++++++++++++++++- src/cloner.rs | 45 ++++++++++++++++++++++++++++++++++++--------- 4 files changed, 97 insertions(+), 10 deletions(-) diff --git a/README.RU.md b/README.RU.md index cc041f2..7eff343 100644 --- a/README.RU.md +++ b/README.RU.md @@ -171,6 +171,14 @@ Options: Enable download by ssh instead of http. An authorized ssh key is required [env: GTLBSTR_DOWNLOAD_SSH=] --upload-ssh Enable upload by ssh instead of http. An authorized ssh key is required [env: GTLBSTR_UPLOAD_SSH=] + --download-force-http + Force download repositories by insecure protocol. Does not work with the download_ssh flag [env: GTLBSTR_DOWNLOAD_FORCE_HTTP=] + --download-force-https + Force download repositories by secure protocol. Does not work with the download_ssh flag [env: GTLBSTR_DOWNLOAD_FORCE_HTTPS=] + --upload-force-http + Force upload repositories by insecure protocol. Does not work with the upload_ssh flag [env: GTLBSTR_UPLOAD_FORCE_HTTP=] + --upload-force-https + Force upload repositories by secure protocol. Does not work with the upload_ssh flag [env: GTLBSTR_UPLOAD_FORCE_HTTPS=] --disable-hierarchy Disable saving the directory hierarchy [env: GTLBSTR_DISABLE_HIERARCHY=] --clear-dst diff --git a/README.md b/README.md index 0a86c09..20342fb 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,14 @@ Options: Enable download by ssh instead of http. An authorized ssh key is required [env: GTLBSTR_DOWNLOAD_SSH=] --upload-ssh Enable upload by ssh instead of http. An authorized ssh key is required [env: GTLBSTR_UPLOAD_SSH=] + --download-force-http + Force download repositories by insecure protocol. Does not work with the download_ssh flag [env: GTLBSTR_DOWNLOAD_FORCE_HTTP=] + --download-force-https + Force download repositories by secure protocol. Does not work with the download_ssh flag [env: GTLBSTR_DOWNLOAD_FORCE_HTTPS=] + --upload-force-http + Force upload repositories by insecure protocol. Does not work with the upload_ssh flag [env: GTLBSTR_UPLOAD_FORCE_HTTP=] + --upload-force-https + Force upload repositories by secure protocol. Does not work with the upload_ssh flag [env: GTLBSTR_UPLOAD_FORCE_HTTPS=] --disable-hierarchy Disable saving the directory hierarchy [env: GTLBSTR_DISABLE_HIERARCHY=] --clear-dst diff --git a/src/cli.rs b/src/cli.rs index 3ff7a7b..8133ed1 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,6 +1,8 @@ use clap::Parser; -use crate::cloner::{clone, BackupGitlabOptions, CloneParams, FetchGitlabOptions, FilterPatterns}; +use crate::cloner::{ + clone, BackupGitlabOptions, CloneParams, FetchGitlabOptions, FilterPatterns, ForceProtocol, +}; use anyhow::{bail, Result}; #[derive(Parser)] @@ -117,6 +119,22 @@ struct Cli { #[arg(long, env = "GTLBSTR_UPLOAD_SSH")] upload_ssh: bool, + /// Force download repositories by insecure protocol. Does not work with the download_ssh flag + #[arg(long, env = "GTLBSTR_DOWNLOAD_FORCE_HTTP")] + download_force_http: bool, + + /// Force download repositories by secure protocol. Does not work with the download_ssh flag + #[arg(long, env = "GTLBSTR_DOWNLOAD_FORCE_HTTPS")] + download_force_https: bool, + + /// Force upload repositories by insecure protocol. Does not work with the upload_ssh flag + #[arg(long, env = "GTLBSTR_UPLOAD_FORCE_HTTP")] + upload_force_http: bool, + + /// Force upload repositories by secure protocol. Does not work with the upload_ssh flag + #[arg(long, env = "GTLBSTR_UPLOAD_FORCE_HTTPS")] + upload_force_https: bool, + /// Disable saving the directory hierarchy #[arg(long, env = "GTLBSTR_DISABLE_HIERARCHY")] disable_hierarchy: bool, @@ -178,6 +196,30 @@ pub fn run() -> Result<()> { bail!(upl_err); } + if cli.download_force_http && cli.download_force_https { + bail!("You cannot use --download-force-http and --download-force-https flags together"); + } + + if cli.upload_force_http && cli.upload_force_https { + bail!("You cannot use --upload-force-http and --upload-force-https flags together"); + } + + let download_force_protocol = if cli.download_force_http { + ForceProtocol::Http + } else if cli.download_force_https { + ForceProtocol::Https + } else { + ForceProtocol::No + }; + + let upload_force_protocol = if cli.upload_force_http { + ForceProtocol::Http + } else if cli.upload_force_https { + ForceProtocol::Https + } else { + ForceProtocol::No + }; + let clone_params = CloneParams { fetch: fetch_gl, dst: cli.dst, @@ -196,6 +238,8 @@ pub fn run() -> Result<()> { only_master: cli.only_master, disable_sync_date: cli.disable_sync_date, gitlab_timeout: cli.gitlab_timeout, + download_force_protocol, + upload_force_protocol, }; clone(clone_params) diff --git a/src/cloner.rs b/src/cloner.rs index 19b012d..5ca2768 100644 --- a/src/cloner.rs +++ b/src/cloner.rs @@ -42,6 +42,7 @@ struct BackupData { client: gitlab::Client, group: Option, git_http_auth: Option, + force_protocol: ForceProtocol, } pub enum FilterPatterns { @@ -84,13 +85,28 @@ fn filter_projects( Ok(projects) } -fn make_git_path(project: &types::Project, git_http_auth: &Option) -> String { +pub enum ForceProtocol { + No, + Http, + Https, +} + +fn make_git_path( + project: &types::Project, + git_http_auth: &Option, + force_protocol: &ForceProtocol, +) -> String { if let Some(auth) = git_http_auth { let parts: Vec<&str> = project.http_url_to_repo.split("://").collect(); if parts.len() != 2 { panic!("project with incorrect http path") } - format!("{}://{}@{}", parts[0], auth, parts[1]) + let protocol = match force_protocol { + ForceProtocol::No => parts[0], + ForceProtocol::Http => "http", + ForceProtocol::Https => "https", + }; + format!("{}://{}@{}", protocol, auth, parts[1]) } else { project.ssh_url_to_repo.clone() } @@ -103,10 +119,11 @@ async fn clone_project( fetch_git_http_auth: &Option, backup: &Option, disable_hierarchy: bool, + fetch_force_protocol: &ForceProtocol, ) -> Result<()> { debug!("project path: {}", &project.path_with_namespace); - let src = make_git_path(project, fetch_git_http_auth); + let src = make_git_path(project, fetch_git_http_auth, fetch_force_protocol); let p_path = if disable_hierarchy { &project.path } else { @@ -115,11 +132,17 @@ async fn clone_project( git::fetch(src, format!("{}/{}", dst, &p_path), only_master).await?; - let (backup_gl, backup_group, backup_git_http_auth) = if let Some(backup) = backup { - (&backup.client, &backup.group, &backup.git_http_auth) - } else { - return Ok(()); - }; + let (backup_gl, backup_group, backup_git_http_auth, backup_force_protocol) = + if let Some(backup) = backup { + ( + &backup.client, + &backup.group, + &backup.git_http_auth, + &backup.force_protocol, + ) + } else { + return Ok(()); + }; info!("start pushing"); @@ -138,7 +161,7 @@ async fn clone_project( .make_project_with_namespace(path, backup_group, project) .await?; - let remote = make_git_path(&backup_project, backup_git_http_auth); + let remote = make_git_path(&backup_project, backup_git_http_auth, backup_force_protocol); git::push_backup(format!("{}/{}", dst, p_path), remote).await } @@ -169,6 +192,8 @@ pub struct CloneParams { pub only_master: bool, pub disable_sync_date: bool, pub gitlab_timeout: Option, + pub download_force_protocol: ForceProtocol, + pub upload_force_protocol: ForceProtocol, } #[tokio::main] @@ -221,6 +246,7 @@ pub async fn clone(p: CloneParams) -> Result<()> { client, group, git_http_auth, + force_protocol: p.upload_force_protocol, }) } else { None @@ -266,6 +292,7 @@ pub async fn clone(p: CloneParams) -> Result<()> { &fetch_git_http_auth, &backup_data, p.disable_hierarchy, + &p.download_force_protocol, ) })) .await?;