diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2025-01-16 09:23:05 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2025-10-17 12:18:24 +0100 |
| commit | b126e5b7acfce55bd101b06cb5baf7f251cd0fda (patch) | |
| tree | dd3eb721a49496ce2a686a43ce4d007b26ee7d7c /src/lib/git | |
| parent | 6cb9e1f5071a6dee8f8e5b98c3c2e699cafd2921 (diff) | |
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.
Diffstat (limited to 'src/lib/git')
| -rw-r--r-- | src/lib/git/nostr_url.rs | 289 |
1 files changed, 146 insertions, 143 deletions
diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs index 5e92a84..0a8338a 100644 --- a/src/lib/git/nostr_url.rs +++ b/src/lib/git/nostr_url.rs | |||
| @@ -2,6 +2,7 @@ use core::fmt; | |||
| 2 | use std::{collections::HashMap, str::FromStr}; | 2 | use std::{collections::HashMap, str::FromStr}; |
| 3 | 3 | ||
| 4 | use anyhow::{Context, Error, Result, anyhow, bail}; | 4 | use anyhow::{Context, Error, Result, anyhow, bail}; |
| 5 | use directories::BaseDirs; | ||
| 5 | use nostr::nips::{nip01::Coordinate, nip19::Nip19Coordinate}; | 6 | use nostr::nips::{nip01::Coordinate, nip19::Nip19Coordinate}; |
| 6 | use nostr_sdk::{FromBech32, PublicKey, RelayUrl, ToBech32, Url}; | 7 | use nostr_sdk::{FromBech32, PublicKey, RelayUrl, ToBech32, Url}; |
| 7 | 8 | ||
| @@ -61,7 +62,7 @@ pub struct NostrUrlDecoded { | |||
| 61 | pub original_string: String, | 62 | pub original_string: String, |
| 62 | pub coordinate: Nip19Coordinate, | 63 | pub coordinate: Nip19Coordinate, |
| 63 | pub protocol: Option<ServerProtocol>, | 64 | pub protocol: Option<ServerProtocol>, |
| 64 | pub user: Option<String>, | 65 | pub ssh_key_file: Option<String>, |
| 65 | pub nip05: Option<String>, | 66 | pub nip05: Option<String>, |
| 66 | } | 67 | } |
| 67 | 68 | ||
| @@ -71,8 +72,8 @@ impl fmt::Display for NostrUrlDecoded { | |||
| 71 | return write!(f, "{}", self.original_string); | 72 | return write!(f, "{}", self.original_string); |
| 72 | } | 73 | } |
| 73 | write!(f, "nostr://")?; | 74 | write!(f, "nostr://")?; |
| 74 | if let Some(user) = &self.user { | 75 | if let Some(ssh_key_file) = &self.ssh_key_file { |
| 75 | write!(f, "{user}@")?; | 76 | write!(f, "{ssh_key_file}@")?; |
| 76 | } | 77 | } |
| 77 | if let Some(protocol) = &self.protocol { | 78 | if let Some(protocol) = &self.protocol { |
| 78 | write!(f, "{protocol}/")?; | 79 | write!(f, "{protocol}/")?; |
| @@ -103,7 +104,7 @@ static INCORRECT_NOSTR_URL_FORMAT_ERROR: &str = "incorrect nostr git url format. | |||
| 103 | impl NostrUrlDecoded { | 104 | impl NostrUrlDecoded { |
| 104 | pub async fn parse_and_resolve(url: &str, git_repo: &Option<&Repo>) -> Result<Self> { | 105 | pub async fn parse_and_resolve(url: &str, git_repo: &Option<&Repo>) -> Result<Self> { |
| 105 | let mut protocol = None; | 106 | let mut protocol = None; |
| 106 | let mut user = None; | 107 | let mut ssh_key_file = None; |
| 107 | let mut relays = vec![]; | 108 | let mut relays = vec![]; |
| 108 | let mut nip05 = None; | 109 | let mut nip05 = None; |
| 109 | 110 | ||
| @@ -130,8 +131,8 @@ impl NostrUrlDecoded { | |||
| 130 | "git" => Some(ServerProtocol::Git), | 131 | "git" => Some(ServerProtocol::Git), |
| 131 | _ => None, | 132 | _ => None, |
| 132 | }; | 133 | }; |
| 133 | } else if name == "user" { | 134 | } else if name == "ssh_key_file" { |
| 134 | user = Some(value.to_string()); | 135 | ssh_key_file = Some(value.to_string()); |
| 135 | } | 136 | } |
| 136 | } | 137 | } |
| 137 | 138 | ||
| @@ -148,7 +149,7 @@ impl NostrUrlDecoded { | |||
| 148 | let protocol_str = if part.contains('.') { | 149 | let protocol_str = if part.contains('.') { |
| 149 | part | 150 | part |
| 150 | } else if let Some(at_index) = part.find('@') { | 151 | } else if let Some(at_index) = part.find('@') { |
| 151 | user = Some(part[..at_index].to_string()); | 152 | ssh_key_file = Some(part[..at_index].to_string()); |
| 152 | &part[at_index + 1..] | 153 | &part[at_index + 1..] |
| 153 | } else { | 154 | } else { |
| 154 | part | 155 | part |
| @@ -240,10 +241,30 @@ impl NostrUrlDecoded { | |||
| 240 | original_string: url.to_string(), | 241 | original_string: url.to_string(), |
| 241 | coordinate, | 242 | coordinate, |
| 242 | protocol, | 243 | protocol, |
| 243 | user, | 244 | ssh_key_file, |
| 244 | nip05, | 245 | nip05, |
| 245 | }) | 246 | }) |
| 246 | } | 247 | } |
| 248 | |||
| 249 | pub fn ssh_key_file_path(&self) -> Option<String> { | ||
| 250 | if let Some(ssh_key_file) = &self.ssh_key_file { | ||
| 251 | if !ssh_key_file.is_empty() { | ||
| 252 | // checking if path exists would make unit tests harder | ||
| 253 | if is_absoute_or_relative_path(ssh_key_file) { | ||
| 254 | return Some(ssh_key_file.clone()); | ||
| 255 | } else if let Some(dirs) = BaseDirs::new() { | ||
| 256 | return Some( | ||
| 257 | dirs.home_dir() | ||
| 258 | .join(".ssh") | ||
| 259 | .join(ssh_key_file) | ||
| 260 | .to_string_lossy() | ||
| 261 | .into_owned(), | ||
| 262 | ); | ||
| 263 | } | ||
| 264 | } | ||
| 265 | } | ||
| 266 | None | ||
| 267 | } | ||
| 247 | } | 268 | } |
| 248 | 269 | ||
| 249 | fn resolve_nip05_from_git_config_cache(nip05: &str, git_repo: &Option<&Repo>) -> Result<PublicKey> { | 270 | fn resolve_nip05_from_git_config_cache(nip05: &str, git_repo: &Option<&Repo>) -> Result<PublicKey> { |
| @@ -297,6 +318,13 @@ fn load_nip_cache(git_repo: &Option<&Repo>) -> Result<HashMap<String, PublicKey> | |||
| 297 | Ok(h) | 318 | Ok(h) |
| 298 | } | 319 | } |
| 299 | 320 | ||
| 321 | fn is_absoute_or_relative_path(input: &str) -> bool { | ||
| 322 | ["~", "/", "./", "../", ".\\", "..\\"] | ||
| 323 | .iter() | ||
| 324 | .any(|s| input.starts_with(s)) | ||
| 325 | || input.chars().nth(1).unwrap() == ':' | ||
| 326 | } | ||
| 327 | |||
| 300 | #[derive(Debug, PartialEq, Default)] | 328 | #[derive(Debug, PartialEq, Default)] |
| 301 | pub struct CloneUrl { | 329 | pub struct CloneUrl { |
| 302 | original_string: String, | 330 | original_string: String, |
| @@ -324,7 +352,7 @@ impl FromStr for CloneUrl { | |||
| 324 | let url_str = if s.contains("://") { | 352 | let url_str = if s.contains("://") { |
| 325 | s.to_string() // Use the original string | 353 | s.to_string() // Use the original string |
| 326 | } else { | 354 | } else { |
| 327 | let protocol = // Check for the SSH format user@host:path and convert to ssh:// | 355 | let protocol = // Check for the SSH format git@host:path and convert to ssh:// |
| 328 | if s.contains('@') && s | 356 | if s.contains('@') && s |
| 329 | .split('@') | 357 | .split('@') |
| 330 | .nth(0) | 358 | .nth(0) |
| @@ -395,7 +423,7 @@ fn contains_port(s: &str) -> bool { | |||
| 395 | } | 423 | } |
| 396 | 424 | ||
| 397 | impl CloneUrl { | 425 | impl CloneUrl { |
| 398 | pub fn format_as(&self, protocol: &ServerProtocol, user: &Option<String>) -> Result<String> { | 426 | pub fn format_as(&self, protocol: &ServerProtocol) -> Result<String> { |
| 399 | // Check for incompatible protocol conversions | 427 | // Check for incompatible protocol conversions |
| 400 | if *protocol == ServerProtocol::Filesystem { | 428 | if *protocol == ServerProtocol::Filesystem { |
| 401 | if self.protocol == ServerProtocol::Filesystem { | 429 | if self.protocol == ServerProtocol::Filesystem { |
| @@ -450,10 +478,7 @@ impl CloneUrl { | |||
| 450 | let mut formatted_url = url.to_string(); | 478 | let mut formatted_url = url.to_string(); |
| 451 | 479 | ||
| 452 | if *protocol == ServerProtocol::Ssh { | 480 | if *protocol == ServerProtocol::Ssh { |
| 453 | formatted_url = formatted_url.replace( | 481 | formatted_url = formatted_url.replace("ssh://", "git@"); |
| 454 | "ssh://", | ||
| 455 | format!("{}@", user.as_deref().unwrap_or("git")).as_str(), | ||
| 456 | ); | ||
| 457 | if url.port().is_some() { | 482 | if url.port().is_some() { |
| 458 | formatted_url = format!("ssh://{formatted_url}"); | 483 | formatted_url = format!("ssh://{formatted_url}"); |
| 459 | } else { | 484 | } else { |
| @@ -543,7 +568,7 @@ fn strip_credentials(url: &str) -> String { | |||
| 543 | return format!("{}{}", protocol, rest_parts[1]); | 568 | return format!("{}{}", protocol, rest_parts[1]); |
| 544 | } | 569 | } |
| 545 | } else if let Some(at_pos) = url.find('@') { | 570 | } else if let Some(at_pos) = url.find('@') { |
| 546 | // Handle user@host:path format | 571 | // Handle git@host:path format |
| 547 | let (_, rest) = url.split_at(at_pos); | 572 | let (_, rest) = url.split_at(at_pos); |
| 548 | // This is a git@ syntax | 573 | // This is a git@ syntax |
| 549 | let host_and_repo = &rest[1..]; // Skip the ':' | 574 | let host_and_repo = &rest[1..]; // Skip the ':' |
| @@ -565,52 +590,12 @@ mod tests { | |||
| 565 | mod clone_url_from_str_format_as { | 590 | mod clone_url_from_str_format_as { |
| 566 | use super::*; | 591 | use super::*; |
| 567 | 592 | ||
| 568 | mod when_user_specified { | ||
| 569 | use super::*; | ||
| 570 | |||
| 571 | mod but_not_in_original_url { | ||
| 572 | use super::*; | ||
| 573 | |||
| 574 | #[test] | ||
| 575 | fn https_to_https_ignores_user() { | ||
| 576 | let result = "https://github.com/user/repo.git" | ||
| 577 | .parse::<CloneUrl>() | ||
| 578 | .unwrap() | ||
| 579 | .format_as(&ServerProtocol::Https, &Some("user1".to_string())) | ||
| 580 | .unwrap(); | ||
| 581 | assert_eq!(result, "https://github.com/user/repo.git"); | ||
| 582 | } | ||
| 583 | #[test] | ||
| 584 | fn https_to_ssh_uses_specified_user() { | ||
| 585 | let result = "https://github.com/user/repo.git" | ||
| 586 | .parse::<CloneUrl>() | ||
| 587 | .unwrap() | ||
| 588 | .format_as(&ServerProtocol::Ssh, &Some("user1".to_string())) | ||
| 589 | .unwrap(); | ||
| 590 | assert_eq!(result, "user1@github.com:user/repo.git"); | ||
| 591 | } | ||
| 592 | } | ||
| 593 | mod and_a_different_user_in_original_url { | ||
| 594 | use super::*; | ||
| 595 | |||
| 596 | #[test] | ||
| 597 | fn ssh_uses_specified_user() { | ||
| 598 | let result = "user2@github.com/user/repo.git" | ||
| 599 | .parse::<CloneUrl>() | ||
| 600 | .unwrap() | ||
| 601 | .format_as(&ServerProtocol::Ssh, &Some("user1".to_string())) | ||
| 602 | .unwrap(); | ||
| 603 | assert_eq!(result, "user1@github.com:user/repo.git"); | ||
| 604 | } | ||
| 605 | } | ||
| 606 | } | ||
| 607 | |||
| 608 | #[test] | 593 | #[test] |
| 609 | fn format_as_ssh_defaults_to_git_user() { | 594 | fn format_as_ssh_defaults_to_git_user() { |
| 610 | let result = "https://github.com/user/repo.git" | 595 | let result = "https://github.com/user/repo.git" |
| 611 | .parse::<CloneUrl>() | 596 | .parse::<CloneUrl>() |
| 612 | .unwrap() | 597 | .unwrap() |
| 613 | .format_as(&ServerProtocol::Ssh, &None) | 598 | .format_as(&ServerProtocol::Ssh) |
| 614 | .unwrap(); | 599 | .unwrap(); |
| 615 | assert_eq!(result, "git@github.com:user/repo.git"); | 600 | assert_eq!(result, "git@github.com:user/repo.git"); |
| 616 | } | 601 | } |
| @@ -623,7 +608,7 @@ mod tests { | |||
| 623 | let result = "https://github.com:1000/user/repo.git" | 608 | let result = "https://github.com:1000/user/repo.git" |
| 624 | .parse::<CloneUrl>() | 609 | .parse::<CloneUrl>() |
| 625 | .unwrap() | 610 | .unwrap() |
| 626 | .format_as(&ServerProtocol::Https, &None) | 611 | .format_as(&ServerProtocol::Https) |
| 627 | .unwrap(); | 612 | .unwrap(); |
| 628 | assert_eq!(result, "https://github.com:1000/user/repo.git"); | 613 | assert_eq!(result, "https://github.com:1000/user/repo.git"); |
| 629 | } | 614 | } |
| @@ -633,7 +618,7 @@ mod tests { | |||
| 633 | let result = "https://github.com:1000/user/repo.git" | 618 | let result = "https://github.com:1000/user/repo.git" |
| 634 | .parse::<CloneUrl>() | 619 | .parse::<CloneUrl>() |
| 635 | .unwrap() | 620 | .unwrap() |
| 636 | .format_as(&ServerProtocol::Ssh, &None) | 621 | .format_as(&ServerProtocol::Ssh) |
| 637 | .unwrap(); | 622 | .unwrap(); |
| 638 | assert_eq!(result, "git@github.com:user/repo.git"); | 623 | assert_eq!(result, "git@github.com:user/repo.git"); |
| 639 | } | 624 | } |
| @@ -644,7 +629,7 @@ mod tests { | |||
| 644 | let result = "ssh://git@github.com:29418/user/repo.git" | 629 | let result = "ssh://git@github.com:29418/user/repo.git" |
| 645 | .parse::<CloneUrl>() | 630 | .parse::<CloneUrl>() |
| 646 | .unwrap() | 631 | .unwrap() |
| 647 | .format_as(&ServerProtocol::Ssh, &None) | 632 | .format_as(&ServerProtocol::Ssh) |
| 648 | .unwrap(); | 633 | .unwrap(); |
| 649 | // need this format | 634 | // need this format |
| 650 | assert_eq!(result, "ssh://git@github.com:29418/user/repo.git"); | 635 | assert_eq!(result, "ssh://git@github.com:29418/user/repo.git"); |
| @@ -655,7 +640,7 @@ mod tests { | |||
| 655 | let result = "ssh://git@github.com:29418/user/repo.git" | 640 | let result = "ssh://git@github.com:29418/user/repo.git" |
| 656 | .parse::<CloneUrl>() | 641 | .parse::<CloneUrl>() |
| 657 | .unwrap() | 642 | .unwrap() |
| 658 | .format_as(&ServerProtocol::Https, &None) | 643 | .format_as(&ServerProtocol::Https) |
| 659 | .unwrap(); | 644 | .unwrap(); |
| 660 | // need this format | 645 | // need this format |
| 661 | assert_eq!(result, "https://github.com/user/repo.git"); | 646 | assert_eq!(result, "https://github.com/user/repo.git"); |
| @@ -667,7 +652,7 @@ mod tests { | |||
| 667 | let result = "git@github.com:29418/user/repo.git" | 652 | let result = "git@github.com:29418/user/repo.git" |
| 668 | .parse::<CloneUrl>() | 653 | .parse::<CloneUrl>() |
| 669 | .unwrap() | 654 | .unwrap() |
| 670 | .format_as(&ServerProtocol::Ssh, &None) | 655 | .format_as(&ServerProtocol::Ssh) |
| 671 | .unwrap(); | 656 | .unwrap(); |
| 672 | // need this format | 657 | // need this format |
| 673 | assert_eq!(result, "ssh://git@github.com:29418/user/repo.git"); | 658 | assert_eq!(result, "ssh://git@github.com:29418/user/repo.git"); |
| @@ -679,7 +664,7 @@ mod tests { | |||
| 679 | let result = "https://github.com/user/repo.git" | 664 | let result = "https://github.com/user/repo.git" |
| 680 | .parse::<CloneUrl>() | 665 | .parse::<CloneUrl>() |
| 681 | .unwrap() | 666 | .unwrap() |
| 682 | .format_as(&ServerProtocol::Unspecified, &None) | 667 | .format_as(&ServerProtocol::Unspecified) |
| 683 | .unwrap(); | 668 | .unwrap(); |
| 684 | assert_eq!(result, "github.com/user/repo.git"); | 669 | assert_eq!(result, "github.com/user/repo.git"); |
| 685 | } | 670 | } |
| @@ -692,7 +677,7 @@ mod tests { | |||
| 692 | let result = "https://github.com/user/repo.git" | 677 | let result = "https://github.com/user/repo.git" |
| 693 | .parse::<CloneUrl>() | 678 | .parse::<CloneUrl>() |
| 694 | .unwrap() | 679 | .unwrap() |
| 695 | .format_as(&ServerProtocol::Https, &None) | 680 | .format_as(&ServerProtocol::Https) |
| 696 | .unwrap(); | 681 | .unwrap(); |
| 697 | assert_eq!(result, "https://github.com/user/repo.git"); | 682 | assert_eq!(result, "https://github.com/user/repo.git"); |
| 698 | } | 683 | } |
| @@ -705,7 +690,7 @@ mod tests { | |||
| 705 | let result = "github.com:1000/user/repo.git" | 690 | let result = "github.com:1000/user/repo.git" |
| 706 | .parse::<CloneUrl>() | 691 | .parse::<CloneUrl>() |
| 707 | .unwrap() | 692 | .unwrap() |
| 708 | .format_as(&ServerProtocol::Https, &None) | 693 | .format_as(&ServerProtocol::Https) |
| 709 | .unwrap(); | 694 | .unwrap(); |
| 710 | assert_eq!(result, "https://github.com/user/repo.git"); | 695 | assert_eq!(result, "https://github.com/user/repo.git"); |
| 711 | } | 696 | } |
| @@ -715,7 +700,7 @@ mod tests { | |||
| 715 | let result = "github.com:user/repo.git" | 700 | let result = "github.com:user/repo.git" |
| 716 | .parse::<CloneUrl>() | 701 | .parse::<CloneUrl>() |
| 717 | .unwrap() | 702 | .unwrap() |
| 718 | .format_as(&ServerProtocol::Https, &None) | 703 | .format_as(&ServerProtocol::Https) |
| 719 | .unwrap(); | 704 | .unwrap(); |
| 720 | assert_eq!(result, "https://github.com/user/repo.git"); | 705 | assert_eq!(result, "https://github.com/user/repo.git"); |
| 721 | } | 706 | } |
| @@ -725,7 +710,7 @@ mod tests { | |||
| 725 | let result = "github.com/user/repo.git#readme" | 710 | let result = "github.com/user/repo.git#readme" |
| 726 | .parse::<CloneUrl>() | 711 | .parse::<CloneUrl>() |
| 727 | .unwrap() | 712 | .unwrap() |
| 728 | .format_as(&ServerProtocol::Https, &None) | 713 | .format_as(&ServerProtocol::Https) |
| 729 | .unwrap(); | 714 | .unwrap(); |
| 730 | assert_eq!(result, "https://github.com/user/repo.git#readme"); | 715 | assert_eq!(result, "https://github.com/user/repo.git#readme"); |
| 731 | } | 716 | } |
| @@ -735,7 +720,7 @@ mod tests { | |||
| 735 | let result = "github.com/user/repo.git?ref=main" | 720 | let result = "github.com/user/repo.git?ref=main" |
| 736 | .parse::<CloneUrl>() | 721 | .parse::<CloneUrl>() |
| 737 | .unwrap() | 722 | .unwrap() |
| 738 | .format_as(&ServerProtocol::Https, &None) | 723 | .format_as(&ServerProtocol::Https) |
| 739 | .unwrap(); | 724 | .unwrap(); |
| 740 | assert_eq!(result, "https://github.com/user/repo.git?ref=main"); | 725 | assert_eq!(result, "https://github.com/user/repo.git?ref=main"); |
| 741 | } | 726 | } |
| @@ -745,7 +730,7 @@ mod tests { | |||
| 745 | let result = "github.com:2222/repo.git?version=1.0#section1" | 730 | let result = "github.com:2222/repo.git?version=1.0#section1" |
| 746 | .parse::<CloneUrl>() | 731 | .parse::<CloneUrl>() |
| 747 | .unwrap() | 732 | .unwrap() |
| 748 | .format_as(&ServerProtocol::Https, &None) | 733 | .format_as(&ServerProtocol::Https) |
| 749 | .unwrap(); | 734 | .unwrap(); |
| 750 | assert_eq!(result, "https://github.com/repo.git?version=1.0#section1"); | 735 | assert_eq!(result, "https://github.com/repo.git?version=1.0#section1"); |
| 751 | } | 736 | } |
| @@ -759,7 +744,7 @@ mod tests { | |||
| 759 | let result = "https://username:password@github.com/user/repo.git" | 744 | let result = "https://username:password@github.com/user/repo.git" |
| 760 | .parse::<CloneUrl>() | 745 | .parse::<CloneUrl>() |
| 761 | .unwrap() | 746 | .unwrap() |
| 762 | .format_as(&ServerProtocol::Https, &None) | 747 | .format_as(&ServerProtocol::Https) |
| 763 | .unwrap(); | 748 | .unwrap(); |
| 764 | assert_eq!(result, "https://github.com/user/repo.git"); | 749 | assert_eq!(result, "https://github.com/user/repo.git"); |
| 765 | } | 750 | } |
| @@ -769,7 +754,7 @@ mod tests { | |||
| 769 | let result = "https://github.com:1000/user/repo.git" | 754 | let result = "https://github.com:1000/user/repo.git" |
| 770 | .parse::<CloneUrl>() | 755 | .parse::<CloneUrl>() |
| 771 | .unwrap() | 756 | .unwrap() |
| 772 | .format_as(&ServerProtocol::Https, &None) | 757 | .format_as(&ServerProtocol::Https) |
| 773 | .unwrap(); | 758 | .unwrap(); |
| 774 | assert_eq!(result, "https://github.com:1000/user/repo.git"); | 759 | assert_eq!(result, "https://github.com:1000/user/repo.git"); |
| 775 | } | 760 | } |
| @@ -779,7 +764,7 @@ mod tests { | |||
| 779 | let result = "https://github.com/user/repo.git#readme" | 764 | let result = "https://github.com/user/repo.git#readme" |
| 780 | .parse::<CloneUrl>() | 765 | .parse::<CloneUrl>() |
| 781 | .unwrap() | 766 | .unwrap() |
| 782 | .format_as(&ServerProtocol::Https, &None) | 767 | .format_as(&ServerProtocol::Https) |
| 783 | .unwrap(); | 768 | .unwrap(); |
| 784 | assert_eq!(result, "https://github.com/user/repo.git#readme"); | 769 | assert_eq!(result, "https://github.com/user/repo.git#readme"); |
| 785 | } | 770 | } |
| @@ -789,7 +774,7 @@ mod tests { | |||
| 789 | let result = "https://github.com/user/repo.git?ref=main" | 774 | let result = "https://github.com/user/repo.git?ref=main" |
| 790 | .parse::<CloneUrl>() | 775 | .parse::<CloneUrl>() |
| 791 | .unwrap() | 776 | .unwrap() |
| 792 | .format_as(&ServerProtocol::Https, &None) | 777 | .format_as(&ServerProtocol::Https) |
| 793 | .unwrap(); | 778 | .unwrap(); |
| 794 | assert_eq!(result, "https://github.com/user/repo.git?ref=main"); | 779 | assert_eq!(result, "https://github.com/user/repo.git?ref=main"); |
| 795 | } | 780 | } |
| @@ -799,7 +784,7 @@ mod tests { | |||
| 799 | let result = "https://github.com:2222/repo.git?version=1.0#section1" | 784 | let result = "https://github.com:2222/repo.git?version=1.0#section1" |
| 800 | .parse::<CloneUrl>() | 785 | .parse::<CloneUrl>() |
| 801 | .unwrap() | 786 | .unwrap() |
| 802 | .format_as(&ServerProtocol::Https, &None) | 787 | .format_as(&ServerProtocol::Https) |
| 803 | .unwrap(); | 788 | .unwrap(); |
| 804 | assert_eq!( | 789 | assert_eq!( |
| 805 | result, | 790 | result, |
| @@ -813,7 +798,7 @@ mod tests { | |||
| 813 | let result = "http://github.com/user/repo.git" | 798 | let result = "http://github.com/user/repo.git" |
| 814 | .parse::<CloneUrl>() | 799 | .parse::<CloneUrl>() |
| 815 | .unwrap() | 800 | .unwrap() |
| 816 | .format_as(&ServerProtocol::Https, &None) | 801 | .format_as(&ServerProtocol::Https) |
| 817 | .unwrap(); | 802 | .unwrap(); |
| 818 | assert_eq!(result, "https://github.com/user/repo.git"); | 803 | assert_eq!(result, "https://github.com/user/repo.git"); |
| 819 | } | 804 | } |
| @@ -826,56 +811,47 @@ mod tests { | |||
| 826 | let result = "git@github.com:user/repo.git" | 811 | let result = "git@github.com:user/repo.git" |
| 827 | .parse::<CloneUrl>() | 812 | .parse::<CloneUrl>() |
| 828 | .unwrap() | 813 | .unwrap() |
| 829 | .format_as(&ServerProtocol::Https, &None) | 814 | .format_as(&ServerProtocol::Https) |
| 830 | .unwrap(); | 815 | .unwrap(); |
| 831 | assert_eq!(result, "https://github.com/user/repo.git"); | 816 | assert_eq!(result, "https://github.com/user/repo.git"); |
| 832 | } | 817 | } |
| 833 | 818 | ||
| 834 | #[test] | 819 | #[test] |
| 835 | fn test_user_at_url() { | ||
| 836 | let result = "user1@github.com:user/repo.git" | ||
| 837 | .parse::<CloneUrl>() | ||
| 838 | .unwrap() | ||
| 839 | .format_as(&ServerProtocol::Https, &None) | ||
| 840 | .unwrap(); | ||
| 841 | assert_eq!(result, "https://github.com/user/repo.git"); | ||
| 842 | } | ||
| 843 | #[test] | ||
| 844 | fn path_has_colon_slash_prefix() { | 820 | fn path_has_colon_slash_prefix() { |
| 845 | let result = "user1@github.com:/user/repo.git" | 821 | let result = "git@github.com:/user/repo.git" |
| 846 | .parse::<CloneUrl>() | 822 | .parse::<CloneUrl>() |
| 847 | .unwrap() | 823 | .unwrap() |
| 848 | .format_as(&ServerProtocol::Https, &None) | 824 | .format_as(&ServerProtocol::Https) |
| 849 | .unwrap(); | 825 | .unwrap(); |
| 850 | assert_eq!(result, "https://github.com/user/repo.git"); | 826 | assert_eq!(result, "https://github.com/user/repo.git"); |
| 851 | } | 827 | } |
| 852 | 828 | ||
| 853 | #[test] | 829 | #[test] |
| 854 | fn path_with_fragment() { | 830 | fn path_with_fragment() { |
| 855 | let result = "user1@github.com:/user/repo.git#readme" | 831 | let result = "git@github.com:/user/repo.git#readme" |
| 856 | .parse::<CloneUrl>() | 832 | .parse::<CloneUrl>() |
| 857 | .unwrap() | 833 | .unwrap() |
| 858 | .format_as(&ServerProtocol::Https, &None) | 834 | .format_as(&ServerProtocol::Https) |
| 859 | .unwrap(); | 835 | .unwrap(); |
| 860 | assert_eq!(result, "https://github.com/user/repo.git#readme"); | 836 | assert_eq!(result, "https://github.com/user/repo.git#readme"); |
| 861 | } | 837 | } |
| 862 | 838 | ||
| 863 | #[test] | 839 | #[test] |
| 864 | fn path_with_parameters() { | 840 | fn path_with_parameters() { |
| 865 | let result = "user@github.com:/user/repo.git?ref=main" | 841 | let result = "git@github.com:/user/repo.git?ref=main" |
| 866 | .parse::<CloneUrl>() | 842 | .parse::<CloneUrl>() |
| 867 | .unwrap() | 843 | .unwrap() |
| 868 | .format_as(&ServerProtocol::Https, &None) | 844 | .format_as(&ServerProtocol::Https) |
| 869 | .unwrap(); | 845 | .unwrap(); |
| 870 | assert_eq!(result, "https://github.com/user/repo.git?ref=main"); | 846 | assert_eq!(result, "https://github.com/user/repo.git?ref=main"); |
| 871 | } | 847 | } |
| 872 | 848 | ||
| 873 | #[test] | 849 | #[test] |
| 874 | fn port_with_parameters_and_fragment_ssh() { | 850 | fn port_with_parameters_and_fragment_ssh() { |
| 875 | let result = "user@github.com:2222/repo.git?version=1.0#section1" | 851 | let result = "git@github.com:2222/repo.git?version=1.0#section1" |
| 876 | .parse::<CloneUrl>() | 852 | .parse::<CloneUrl>() |
| 877 | .unwrap() | 853 | .unwrap() |
| 878 | .format_as(&ServerProtocol::Ssh, &None) | 854 | .format_as(&ServerProtocol::Ssh) |
| 879 | .unwrap(); | 855 | .unwrap(); |
| 880 | assert_eq!( | 856 | assert_eq!( |
| 881 | result, | 857 | result, |
| @@ -884,10 +860,10 @@ mod tests { | |||
| 884 | } | 860 | } |
| 885 | #[test] | 861 | #[test] |
| 886 | fn port_with_parameters_and_fragment_https() { | 862 | fn port_with_parameters_and_fragment_https() { |
| 887 | let result = "user@github.com:2222/repo.git?version=1.0#section1" | 863 | let result = "git@github.com:2222/repo.git?version=1.0#section1" |
| 888 | .parse::<CloneUrl>() | 864 | .parse::<CloneUrl>() |
| 889 | .unwrap() | 865 | .unwrap() |
| 890 | .format_as(&ServerProtocol::Https, &None) | 866 | .format_as(&ServerProtocol::Https) |
| 891 | .unwrap(); | 867 | .unwrap(); |
| 892 | assert_eq!(result, "https://github.com/repo.git?version=1.0#section1"); | 868 | assert_eq!(result, "https://github.com/repo.git?version=1.0#section1"); |
| 893 | } | 869 | } |
| @@ -898,7 +874,7 @@ mod tests { | |||
| 898 | let result = "ftp://example.com/repo.git" | 874 | let result = "ftp://example.com/repo.git" |
| 899 | .parse::<CloneUrl>() | 875 | .parse::<CloneUrl>() |
| 900 | .unwrap() | 876 | .unwrap() |
| 901 | .format_as(&ServerProtocol::Https, &None) | 877 | .format_as(&ServerProtocol::Https) |
| 902 | .unwrap(); | 878 | .unwrap(); |
| 903 | assert_eq!(result, "https://example.com/repo.git"); | 879 | assert_eq!(result, "https://example.com/repo.git"); |
| 904 | } | 880 | } |
| @@ -908,7 +884,7 @@ mod tests { | |||
| 908 | let result = "git://example.com/repo.git" | 884 | let result = "git://example.com/repo.git" |
| 909 | .parse::<CloneUrl>() | 885 | .parse::<CloneUrl>() |
| 910 | .unwrap() | 886 | .unwrap() |
| 911 | .format_as(&ServerProtocol::Https, &None) | 887 | .format_as(&ServerProtocol::Https) |
| 912 | .unwrap(); | 888 | .unwrap(); |
| 913 | assert_eq!(result, "https://example.com/repo.git"); | 889 | assert_eq!(result, "https://example.com/repo.git"); |
| 914 | } | 890 | } |
| @@ -925,7 +901,7 @@ mod tests { | |||
| 925 | let result = "/path/to/repo.git" | 901 | let result = "/path/to/repo.git" |
| 926 | .parse::<CloneUrl>() | 902 | .parse::<CloneUrl>() |
| 927 | .unwrap() | 903 | .unwrap() |
| 928 | .format_as(&ServerProtocol::Https, &None); | 904 | .format_as(&ServerProtocol::Https); |
| 929 | assert!(result.is_err()); // Expecting an error when converting to HTTPS | 905 | assert!(result.is_err()); // Expecting an error when converting to HTTPS |
| 930 | } | 906 | } |
| 931 | 907 | ||
| @@ -934,7 +910,7 @@ mod tests { | |||
| 934 | let result = "./path/to/repo.git" | 910 | let result = "./path/to/repo.git" |
| 935 | .parse::<CloneUrl>() | 911 | .parse::<CloneUrl>() |
| 936 | .unwrap() | 912 | .unwrap() |
| 937 | .format_as(&ServerProtocol::Https, &None); | 913 | .format_as(&ServerProtocol::Https); |
| 938 | assert!(result.is_err()); // Expecting an error when converting to HTTPS | 914 | assert!(result.is_err()); // Expecting an error when converting to HTTPS |
| 939 | } | 915 | } |
| 940 | } | 916 | } |
| @@ -972,13 +948,6 @@ mod tests { | |||
| 972 | } | 948 | } |
| 973 | 949 | ||
| 974 | #[test] | 950 | #[test] |
| 975 | fn test_user_at_url() { | ||
| 976 | let url = "user1@github.com:user/repo.git"; | ||
| 977 | let result = convert_clone_url_to_https(url).unwrap(); | ||
| 978 | assert_eq!(result, "https://github.com/user/repo.git"); | ||
| 979 | } | ||
| 980 | |||
| 981 | #[test] | ||
| 982 | fn test_ssh_url() { | 951 | fn test_ssh_url() { |
| 983 | let url = "ssh://github.com/user/repo.git"; | 952 | let url = "ssh://github.com/user/repo.git"; |
| 984 | let result = convert_clone_url_to_https(url).unwrap(); | 953 | let result = convert_clone_url_to_https(url).unwrap(); |
| @@ -1030,7 +999,7 @@ mod tests { | |||
| 1030 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], | 999 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], |
| 1031 | }, | 1000 | }, |
| 1032 | protocol: None, | 1001 | protocol: None, |
| 1033 | user: None, | 1002 | ssh_key_file: None, |
| 1034 | nip05: None, | 1003 | nip05: None, |
| 1035 | }), | 1004 | }), |
| 1036 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit", | 1005 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit", |
| @@ -1055,7 +1024,7 @@ mod tests { | |||
| 1055 | relays: vec![], | 1024 | relays: vec![], |
| 1056 | }, | 1025 | }, |
| 1057 | protocol: None, | 1026 | protocol: None, |
| 1058 | user: None, | 1027 | ssh_key_file: None, |
| 1059 | nip05: None, | 1028 | nip05: None, |
| 1060 | }), | 1029 | }), |
| 1061 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit", | 1030 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit", |
| @@ -1080,7 +1049,7 @@ mod tests { | |||
| 1080 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], | 1049 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], |
| 1081 | }, | 1050 | }, |
| 1082 | protocol: Some(ServerProtocol::Ssh), | 1051 | protocol: Some(ServerProtocol::Ssh), |
| 1083 | user: None, | 1052 | ssh_key_file: None, |
| 1084 | nip05: None, | 1053 | nip05: None, |
| 1085 | }), | 1054 | }), |
| 1086 | "nostr://ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit", | 1055 | "nostr://ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit", |
| @@ -1089,7 +1058,7 @@ mod tests { | |||
| 1089 | } | 1058 | } |
| 1090 | 1059 | ||
| 1091 | #[test] | 1060 | #[test] |
| 1092 | fn with_protocol_and_user() -> Result<()> { | 1061 | fn with_protocol_and_ssh_key_file() -> Result<()> { |
| 1093 | assert_eq!( | 1062 | assert_eq!( |
| 1094 | format!("{}", NostrUrlDecoded { | 1063 | format!("{}", NostrUrlDecoded { |
| 1095 | original_string: String::new(), | 1064 | original_string: String::new(), |
| @@ -1105,7 +1074,7 @@ mod tests { | |||
| 1105 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], | 1074 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], |
| 1106 | }, | 1075 | }, |
| 1107 | protocol: Some(ServerProtocol::Ssh), | 1076 | protocol: Some(ServerProtocol::Ssh), |
| 1108 | user: Some("bla".to_string()), | 1077 | ssh_key_file: Some("bla".to_string()), |
| 1109 | nip05: None, | 1078 | nip05: None, |
| 1110 | }), | 1079 | }), |
| 1111 | "nostr://bla@ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit", | 1080 | "nostr://bla@ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit", |
| @@ -1114,27 +1083,27 @@ mod tests { | |||
| 1114 | } | 1083 | } |
| 1115 | } | 1084 | } |
| 1116 | 1085 | ||
| 1086 | fn get_model_coordinate(relays: bool) -> Nip19Coordinate { | ||
| 1087 | Nip19Coordinate { | ||
| 1088 | coordinate: Coordinate { | ||
| 1089 | identifier: "ngit".to_string(), | ||
| 1090 | public_key: PublicKey::parse( | ||
| 1091 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | ||
| 1092 | ) | ||
| 1093 | .unwrap(), | ||
| 1094 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 1095 | }, | ||
| 1096 | relays: if relays { | ||
| 1097 | vec![RelayUrl::parse("wss://nos.lol").unwrap()] | ||
| 1098 | } else { | ||
| 1099 | vec![] | ||
| 1100 | }, | ||
| 1101 | } | ||
| 1102 | } | ||
| 1103 | |||
| 1117 | mod nostr_url_decoded_paramemters_from_str { | 1104 | mod nostr_url_decoded_paramemters_from_str { |
| 1118 | use super::*; | 1105 | use super::*; |
| 1119 | 1106 | ||
| 1120 | fn get_model_coordinate(relays: bool) -> Nip19Coordinate { | ||
| 1121 | Nip19Coordinate { | ||
| 1122 | coordinate: Coordinate { | ||
| 1123 | identifier: "ngit".to_string(), | ||
| 1124 | public_key: PublicKey::parse( | ||
| 1125 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | ||
| 1126 | ) | ||
| 1127 | .unwrap(), | ||
| 1128 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 1129 | }, | ||
| 1130 | relays: if relays { | ||
| 1131 | vec![RelayUrl::parse("wss://nos.lol").unwrap()] | ||
| 1132 | } else { | ||
| 1133 | vec![] | ||
| 1134 | }, | ||
| 1135 | } | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | #[tokio::test] | 1107 | #[tokio::test] |
| 1139 | async fn from_naddr() -> Result<()> { | 1108 | async fn from_naddr() -> Result<()> { |
| 1140 | let url = "nostr://naddr1qqzxuemfwsqs6amnwvaz7tmwdaejumr0dspzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqvzqqqrhnym0k2qj".to_string(); | 1109 | let url = "nostr://naddr1qqzxuemfwsqs6amnwvaz7tmwdaejumr0dspzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqvzqqqrhnym0k2qj".to_string(); |
| @@ -1155,7 +1124,7 @@ mod tests { | |||
| 1155 | * slash */ | 1124 | * slash */ |
| 1156 | }, | 1125 | }, |
| 1157 | protocol: None, | 1126 | protocol: None, |
| 1158 | user: None, | 1127 | ssh_key_file: None, |
| 1159 | nip05: None, | 1128 | nip05: None, |
| 1160 | }, | 1129 | }, |
| 1161 | ); | 1130 | ); |
| @@ -1176,7 +1145,7 @@ mod tests { | |||
| 1176 | original_string: url.clone(), | 1145 | original_string: url.clone(), |
| 1177 | coordinate: get_model_coordinate(false), | 1146 | coordinate: get_model_coordinate(false), |
| 1178 | protocol: None, | 1147 | protocol: None, |
| 1179 | user: None, | 1148 | ssh_key_file: None, |
| 1180 | nip05: None, | 1149 | nip05: None, |
| 1181 | }, | 1150 | }, |
| 1182 | ); | 1151 | ); |
| @@ -1195,7 +1164,7 @@ mod tests { | |||
| 1195 | original_string: url.clone(), | 1164 | original_string: url.clone(), |
| 1196 | coordinate: get_model_coordinate(true), | 1165 | coordinate: get_model_coordinate(true), |
| 1197 | protocol: None, | 1166 | protocol: None, |
| 1198 | user: None, | 1167 | ssh_key_file: None, |
| 1199 | nip05: None, | 1168 | nip05: None, |
| 1200 | }, | 1169 | }, |
| 1201 | ); | 1170 | ); |
| @@ -1214,7 +1183,7 @@ mod tests { | |||
| 1214 | original_string: url.clone(), | 1183 | original_string: url.clone(), |
| 1215 | coordinate: get_model_coordinate(true), | 1184 | coordinate: get_model_coordinate(true), |
| 1216 | protocol: None, | 1185 | protocol: None, |
| 1217 | user: None, | 1186 | ssh_key_file: None, |
| 1218 | nip05: None, | 1187 | nip05: None, |
| 1219 | }, | 1188 | }, |
| 1220 | ); | 1189 | ); |
| @@ -1247,7 +1216,7 @@ mod tests { | |||
| 1247 | ], | 1216 | ], |
| 1248 | }, | 1217 | }, |
| 1249 | protocol: None, | 1218 | protocol: None, |
| 1250 | user: None, | 1219 | ssh_key_file: None, |
| 1251 | nip05: None, | 1220 | nip05: None, |
| 1252 | }, | 1221 | }, |
| 1253 | ); | 1222 | ); |
| @@ -1263,7 +1232,7 @@ mod tests { | |||
| 1263 | original_string: url.clone(), | 1232 | original_string: url.clone(), |
| 1264 | coordinate: get_model_coordinate(false), | 1233 | coordinate: get_model_coordinate(false), |
| 1265 | protocol: Some(ServerProtocol::Ssh), | 1234 | protocol: Some(ServerProtocol::Ssh), |
| 1266 | user: None, | 1235 | ssh_key_file: None, |
| 1267 | nip05: None, | 1236 | nip05: None, |
| 1268 | }, | 1237 | }, |
| 1269 | ); | 1238 | ); |
| @@ -1271,15 +1240,15 @@ mod tests { | |||
| 1271 | } | 1240 | } |
| 1272 | 1241 | ||
| 1273 | #[tokio::test] | 1242 | #[tokio::test] |
| 1274 | async fn with_server_protocol_and_user() -> Result<()> { | 1243 | async fn with_server_protocol_and_ssh_key_file() -> Result<()> { |
| 1275 | let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?protocol=ssh&user=fred".to_string(); | 1244 | let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?protocol=ssh&ssh_key_file=fred".to_string(); |
| 1276 | assert_eq!( | 1245 | assert_eq!( |
| 1277 | NostrUrlDecoded::parse_and_resolve(&url, &None).await?, | 1246 | NostrUrlDecoded::parse_and_resolve(&url, &None).await?, |
| 1278 | NostrUrlDecoded { | 1247 | NostrUrlDecoded { |
| 1279 | original_string: url.clone(), | 1248 | original_string: url.clone(), |
| 1280 | coordinate: get_model_coordinate(false), | 1249 | coordinate: get_model_coordinate(false), |
| 1281 | protocol: Some(ServerProtocol::Ssh), | 1250 | protocol: Some(ServerProtocol::Ssh), |
| 1282 | user: Some("fred".to_string()), | 1251 | ssh_key_file: Some("fred".to_string()), |
| 1283 | nip05: None, | 1252 | nip05: None, |
| 1284 | }, | 1253 | }, |
| 1285 | ); | 1254 | ); |
| @@ -1299,7 +1268,7 @@ mod tests { | |||
| 1299 | original_string: url.clone(), | 1268 | original_string: url.clone(), |
| 1300 | coordinate: get_model_coordinate(true), | 1269 | coordinate: get_model_coordinate(true), |
| 1301 | protocol: None, | 1270 | protocol: None, |
| 1302 | user: None, | 1271 | ssh_key_file: None, |
| 1303 | nip05: None, | 1272 | nip05: None, |
| 1304 | }, | 1273 | }, |
| 1305 | ); | 1274 | ); |
| @@ -1318,7 +1287,7 @@ mod tests { | |||
| 1318 | original_string: url.clone(), | 1287 | original_string: url.clone(), |
| 1319 | coordinate: get_model_coordinate(true), | 1288 | coordinate: get_model_coordinate(true), |
| 1320 | protocol: None, | 1289 | protocol: None, |
| 1321 | user: None, | 1290 | ssh_key_file: None, |
| 1322 | nip05: None, | 1291 | nip05: None, |
| 1323 | }, | 1292 | }, |
| 1324 | ); | 1293 | ); |
| @@ -1351,7 +1320,7 @@ mod tests { | |||
| 1351 | ], | 1320 | ], |
| 1352 | }, | 1321 | }, |
| 1353 | protocol: None, | 1322 | protocol: None, |
| 1354 | user: None, | 1323 | ssh_key_file: None, |
| 1355 | nip05: None, | 1324 | nip05: None, |
| 1356 | }, | 1325 | }, |
| 1357 | ); | 1326 | ); |
| @@ -1367,7 +1336,7 @@ mod tests { | |||
| 1367 | original_string: url.clone(), | 1336 | original_string: url.clone(), |
| 1368 | coordinate: get_model_coordinate(false), | 1337 | coordinate: get_model_coordinate(false), |
| 1369 | protocol: Some(ServerProtocol::Ssh), | 1338 | protocol: Some(ServerProtocol::Ssh), |
| 1370 | user: None, | 1339 | ssh_key_file: None, |
| 1371 | nip05: None, | 1340 | nip05: None, |
| 1372 | }, | 1341 | }, |
| 1373 | ); | 1342 | ); |
| @@ -1375,7 +1344,7 @@ mod tests { | |||
| 1375 | } | 1344 | } |
| 1376 | 1345 | ||
| 1377 | #[tokio::test] | 1346 | #[tokio::test] |
| 1378 | async fn with_server_protocol_and_user() -> Result<()> { | 1347 | async fn with_server_protocol_and_ssh_key_file() -> Result<()> { |
| 1379 | let url = "nostr://fred@ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit".to_string(); | 1348 | let url = "nostr://fred@ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit".to_string(); |
| 1380 | assert_eq!( | 1349 | assert_eq!( |
| 1381 | NostrUrlDecoded::parse_and_resolve(&url, &None).await?, | 1350 | NostrUrlDecoded::parse_and_resolve(&url, &None).await?, |
| @@ -1383,7 +1352,7 @@ mod tests { | |||
| 1383 | original_string: url.clone(), | 1352 | original_string: url.clone(), |
| 1384 | coordinate: get_model_coordinate(false), | 1353 | coordinate: get_model_coordinate(false), |
| 1385 | protocol: Some(ServerProtocol::Ssh), | 1354 | protocol: Some(ServerProtocol::Ssh), |
| 1386 | user: Some("fred".to_string()), | 1355 | ssh_key_file: Some("fred".to_string()), |
| 1387 | nip05: None, | 1356 | nip05: None, |
| 1388 | }, | 1357 | }, |
| 1389 | ); | 1358 | ); |
| @@ -1392,4 +1361,38 @@ mod tests { | |||
| 1392 | } | 1361 | } |
| 1393 | } | 1362 | } |
| 1394 | } | 1363 | } |
| 1364 | mod nostr_url_ssh_key_file_path { | ||
| 1365 | use super::*; | ||
| 1366 | |||
| 1367 | #[tokio::test] | ||
| 1368 | async fn when_full_file_path_not_detected_default_ssh_dir_is_preppended() -> Result<()> { | ||
| 1369 | let url = "nostr://fred@ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit".to_string(); | ||
| 1370 | let decoded = NostrUrlDecoded { | ||
| 1371 | original_string: url.clone(), | ||
| 1372 | coordinate: get_model_coordinate(false), | ||
| 1373 | protocol: Some(ServerProtocol::Ssh), | ||
| 1374 | ssh_key_file: Some("fred".to_string()), | ||
| 1375 | nip05: None, | ||
| 1376 | }; | ||
| 1377 | assert!(decoded.ssh_key_file_path().unwrap().ends_with("/.ssh/fred")); | ||
| 1378 | Ok(()) | ||
| 1379 | } | ||
| 1380 | |||
| 1381 | #[tokio::test] | ||
| 1382 | async fn when_full_file_path_detected_default_ssh_dir_is_not_preppended() -> Result<()> { | ||
| 1383 | let url = "nostr://~/other/fred@ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit".to_string(); | ||
| 1384 | let decoded = NostrUrlDecoded { | ||
| 1385 | original_string: url.clone(), | ||
| 1386 | coordinate: get_model_coordinate(false), | ||
| 1387 | protocol: Some(ServerProtocol::Ssh), | ||
| 1388 | ssh_key_file: Some("~/other/fred".to_string()), | ||
| 1389 | nip05: None, | ||
| 1390 | }; | ||
| 1391 | assert_eq!( | ||
| 1392 | decoded.ssh_key_file_path(), | ||
| 1393 | Some("~/other/fred".to_string()) | ||
| 1394 | ); | ||
| 1395 | Ok(()) | ||
| 1396 | } | ||
| 1397 | } | ||
| 1395 | } | 1398 | } |