From b126e5b7acfce55bd101b06cb5baf7f251cd0fda Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Thu, 16 Jan 2025 09:23:05 +0000 Subject: feat!(nostr_url): replace user with ssh_key_file replaces the "user" in the nostr_url format with "ssh_key_file", to support the original intent, which was to allow users to specify different authentication credentials. most git servers always expect the ssh user to be 'git'. the idiumatic way of specifying logging in as a different user is to specify a different ssh key. the idiomatic way of storing non-default ssh keys is in the location `~/.ssh/key_name`. "ssh_key_file" can be specified as `key_name`, for keys in the default location, or as a relative or absolute custom location eg. `/other_keys/.ssh/nym1` or `../.ssh/nym1`. BREAKING CHANGE: in nostr git url nym1@ssh/npub123/identifer, nym1 is now treated as ssh key file location rather than a ssh user. it can be specified as a file within `~/.ssh` eg `~/.ssh/nym1` or a full or relative path. --- src/lib/fetch.rs | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'src/lib/fetch.rs') diff --git a/src/lib/fetch.rs b/src/lib/fetch.rs index 89001d4..eeed8f4 100644 --- a/src/lib/fetch.rs +++ b/src/lib/fetch.rs @@ -1,4 +1,6 @@ use std::{ + path::PathBuf, + str::FromStr, sync::{Arc, Mutex}, time::Instant, }; @@ -44,18 +46,28 @@ pub fn fetch_from_git_server( format!("fetching {} over {protocol}...", server_url.short_name(),).as_str(), )?; - let formatted_url = server_url.format_as(protocol, &decoded_nostr_url.user)?; + let formatted_url = server_url.format_as(protocol)?; let res = fetch_from_git_server_url( &git_repo.git_repo, oids, &formatted_url, [ServerProtocol::UnauthHttps, ServerProtocol::UnauthHttp].contains(protocol), + decoded_nostr_url.ssh_key_file_path().as_ref(), term, ); if let Err(error) = res { - term.write_line( - format!("fetch: {formatted_url} failed over {protocol}: {error}").as_str(), - )?; + term.write_line(&format!( + "fetch: {formatted_url} failed over {protocol}{}: {error}", + if protocol == &ServerProtocol::Ssh { + if let Some(ssh_key_file) = &decoded_nostr_url.ssh_key_file_path() { + format!(" with ssh key from {ssh_key_file}") + } else { + String::new() + } + } else { + String::new() + } + ))?; failed_protocols.push(protocol); } else { success = true; @@ -89,6 +101,7 @@ fn fetch_from_git_server_url( oids: &[String], git_server_url: &str, dont_authenticate: bool, + ssh_key_file: Option<&String>, term: &console::Term, ) -> Result<()> { if git_server_url.parse::()?.protocol() == ServerProtocol::Ssh && !check_ssh_keys() { @@ -96,7 +109,20 @@ fn fetch_from_git_server_url( } let git_config = git_repo.config()?; let mut git_server_remote = git_repo.remote_anonymous(git_server_url)?; - let auth = GitAuthenticator::default(); + let auth = { + if dont_authenticate { + GitAuthenticator::default() + } else if git_server_url.contains("git@") { + if let Some(ssh_key_file) = ssh_key_file { + GitAuthenticator::default() + .add_ssh_key_from_file(PathBuf::from_str(ssh_key_file)?, None) + } else { + GitAuthenticator::default() + } + } else { + GitAuthenticator::default() + } + }; let mut fetch_options = git2::FetchOptions::new(); let mut remote_callbacks = git2::RemoteCallbacks::new(); let fetch_reporter = Arc::new(Mutex::new(FetchReporter::new(term))); -- cgit v1.2.3