diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-11-12 08:06:44 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-11-12 11:59:50 +0000 |
| commit | a94c24b177692b8c719fafdaf2728c723657fd39 (patch) | |
| tree | fcd89189ad07f8a19f90512f9c24c5b7cad1df46 /src/lib/login/mod.rs | |
| parent | 98775a626b7a956378b8fa26f60a869d27068538 (diff) | |
fix: get correct nip46 npub in edge case
when there is an npub listed in git config but login was via direct
cli arguments to the current process, the wrong npub would be used.
this is the case for the ngit_init tests.
this can be more eligantly if rust-nostr NostrConnect::new() were
updated to accept user public key as requested here:
https://gitworkshop.dev/r/naddr1qvzqqqrhnypzq6xcz9jerqgqkldy8lpg7lglcyj4g3nwzy2cs6u70wejdaj7csnjqy88wumn8ghj7mn0wvhxcmmv9uqq5un4wd6z6mn0wd68y2z2qh0/issues/note1qa2pty0mnjhsme3thza24u3nv8u7859fqw2qg6fuyx9w00e2gekqvl3yg9
Diffstat (limited to 'src/lib/login/mod.rs')
| -rw-r--r-- | src/lib/login/mod.rs | 95 |
1 files changed, 64 insertions, 31 deletions
diff --git a/src/lib/login/mod.rs b/src/lib/login/mod.rs index de82c01..0e00170 100644 --- a/src/lib/login/mod.rs +++ b/src/lib/login/mod.rs | |||
| @@ -46,7 +46,7 @@ pub async fn launch( | |||
| 46 | change_user: bool, | 46 | change_user: bool, |
| 47 | silent: bool, | 47 | silent: bool, |
| 48 | ) -> Result<(Arc<dyn NostrSigner>, UserRef)> { | 48 | ) -> Result<(Arc<dyn NostrSigner>, UserRef)> { |
| 49 | if let Ok(signer) = match get_signer_without_prompts( | 49 | if let Ok((signer, public_key)) = match get_signer_without_prompts( |
| 50 | git_repo, | 50 | git_repo, |
| 51 | bunker_uri, | 51 | bunker_uri, |
| 52 | bunker_app_key, | 52 | bunker_app_key, |
| @@ -56,7 +56,7 @@ pub async fn launch( | |||
| 56 | ) | 56 | ) |
| 57 | .await | 57 | .await |
| 58 | { | 58 | { |
| 59 | Ok(signer) => Ok(signer), | 59 | Ok((signer, public_key)) => Ok((signer, public_key)), |
| 60 | Err(error) => { | 60 | Err(error) => { |
| 61 | if error | 61 | if error |
| 62 | .to_string() | 62 | .to_string() |
| @@ -85,7 +85,7 @@ pub async fn launch( | |||
| 85 | .password(PromptPasswordParms::default().with_prompt("password")) | 85 | .password(PromptPasswordParms::default().with_prompt("password")) |
| 86 | .context("failed to get password input from interactor.password")?; | 86 | .context("failed to get password input from interactor.password")?; |
| 87 | if let Ok(keys) = get_keys_with_password(git_repo, &password) { | 87 | if let Ok(keys) = get_keys_with_password(git_repo, &password) { |
| 88 | break Ok(Arc::new(keys) as Arc<dyn NostrSigner>); | 88 | break Ok((Arc::new(keys) as Arc<dyn NostrSigner>, None)); |
| 89 | } | 89 | } |
| 90 | eprintln!("incorrect password"); | 90 | eprintln!("incorrect password"); |
| 91 | } | 91 | } |
| @@ -97,18 +97,23 @@ pub async fn launch( | |||
| 97 | } | 97 | } |
| 98 | } | 98 | } |
| 99 | } { | 99 | } { |
| 100 | // get user ref | 100 | let user_ref = get_user_details( |
| 101 | let public_key = if let Ok(public_key) = PublicKey::from_bech32( | 101 | // Note: if rust-nostr NostrConnect::new() were updated to accept user public key as |
| 102 | get_config_item(git_repo, "nostr.npub").unwrap_or("unknown".to_string()), | 102 | // requested then the added complexity added in this commit can be undone |
| 103 | ) { | 103 | &(if let Some(public_key) = public_key { |
| 104 | public_key | 104 | public_key |
| 105 | } else { | 105 | } else { |
| 106 | signer | 106 | signer |
| 107 | .get_public_key() | 107 | .get_public_key() |
| 108 | .await | 108 | .await |
| 109 | .context("cannot get public key from signer")? | 109 | .context("cannot get public key from signer")? |
| 110 | }; | 110 | }), |
| 111 | let user_ref = get_user_details(&public_key, client, git_repo.get_path()?, silent).await?; | 111 | client, |
| 112 | git_repo.get_path()?, | ||
| 113 | silent, | ||
| 114 | ) | ||
| 115 | .await?; | ||
| 116 | |||
| 112 | if !silent { | 117 | if !silent { |
| 113 | print_logged_in_as(&user_ref, client.is_none())?; | 118 | print_logged_in_as(&user_ref, client.is_none())?; |
| 114 | } | 119 | } |
| @@ -139,13 +144,14 @@ async fn get_signer_without_prompts( | |||
| 139 | nsec: &Option<String>, | 144 | nsec: &Option<String>, |
| 140 | password: &Option<String>, | 145 | password: &Option<String>, |
| 141 | save_local: bool, | 146 | save_local: bool, |
| 142 | ) -> Result<Arc<dyn NostrSigner>> { | 147 | ) -> Result<(Arc<dyn NostrSigner>, Option<PublicKey>)> { |
| 143 | if let Some(nsec) = nsec { | 148 | if let Some(nsec) = nsec { |
| 144 | Ok(Arc::new(get_keys_from_nsec( | 149 | Ok(( |
| 145 | git_repo, nsec, password, save_local, | 150 | Arc::new(get_keys_from_nsec(git_repo, nsec, password, save_local)?), |
| 146 | )?)) | 151 | None, |
| 152 | )) | ||
| 147 | } else if let Some(password) = password { | 153 | } else if let Some(password) = password { |
| 148 | Ok(Arc::new(get_keys_with_password(git_repo, password)?)) | 154 | Ok((Arc::new(get_keys_with_password(git_repo, password)?), None)) |
| 149 | } else if let Some(bunker_uri) = bunker_uri { | 155 | } else if let Some(bunker_uri) = bunker_uri { |
| 150 | if let Some(bunker_app_key) = bunker_app_key { | 156 | if let Some(bunker_app_key) = bunker_app_key { |
| 151 | let signer = get_nip46_signer_from_uri_and_key(bunker_uri, bunker_app_key) | 157 | let signer = get_nip46_signer_from_uri_and_key(bunker_uri, bunker_app_key) |
| @@ -161,7 +167,7 @@ async fn get_signer_without_prompts( | |||
| 161 | ) | 167 | ) |
| 162 | .context("failed to save bunker details local git config nostr.bunker-uri and nostr.bunker-app-key")?; | 168 | .context("failed to save bunker details local git config nostr.bunker-uri and nostr.bunker-app-key")?; |
| 163 | } | 169 | } |
| 164 | Ok(signer) | 170 | Ok((signer, None)) |
| 165 | } else { | 171 | } else { |
| 166 | bail!( | 172 | bail!( |
| 167 | "bunker-app-key parameter must be provided alongside bunker-uri. if unknown, login interactively." | 173 | "bunker-app-key parameter must be provided alongside bunker-uri. if unknown, login interactively." |
| @@ -303,7 +309,7 @@ async fn get_nip46_signer_from_uri_and_key( | |||
| 303 | 309 | ||
| 304 | async fn get_signer_with_git_config_nsec_or_bunker_without_prompts( | 310 | async fn get_signer_with_git_config_nsec_or_bunker_without_prompts( |
| 305 | git_repo: &Repo, | 311 | git_repo: &Repo, |
| 306 | ) -> Result<Arc<dyn NostrSigner>> { | 312 | ) -> Result<(Arc<dyn NostrSigner>, Option<PublicKey>)> { |
| 307 | if let Ok(local_nsec) = &git_repo | 313 | if let Ok(local_nsec) = &git_repo |
| 308 | .get_git_config_item("nostr.nsec", Some(false)) | 314 | .get_git_config_item("nostr.nsec", Some(false)) |
| 309 | .context("failed get local git config")? | 315 | .context("failed get local git config")? |
| @@ -312,12 +318,21 @@ async fn get_signer_with_git_config_nsec_or_bunker_without_prompts( | |||
| 312 | if local_nsec.contains("ncryptsec") { | 318 | if local_nsec.contains("ncryptsec") { |
| 313 | bail!("git global config item nostr.nsec is an ncryptsec") | 319 | bail!("git global config item nostr.nsec is an ncryptsec") |
| 314 | } | 320 | } |
| 315 | Ok(Arc::new( | 321 | Ok(( |
| 316 | nostr::Keys::from_str(local_nsec).context("invalid nsec parameter")?, | 322 | Arc::new(nostr::Keys::from_str(local_nsec).context("invalid nsec parameter")?), |
| 323 | None, | ||
| 317 | )) | 324 | )) |
| 318 | } else if let Ok((uri, app_key)) = get_git_config_bunker_uri_and_app_key(git_repo, Some(false)) | 325 | } else if let Ok((uri, app_key, npub)) = |
| 326 | get_git_config_bunker_uri_and_app_key(git_repo, Some(false)) | ||
| 319 | { | 327 | { |
| 320 | get_nip46_signer_from_uri_and_key(&uri, &app_key).await | 328 | Ok(( |
| 329 | get_nip46_signer_from_uri_and_key(&uri, &app_key).await?, | ||
| 330 | if let Ok(pubic_key) = PublicKey::parse(npub) { | ||
| 331 | Some(pubic_key) | ||
| 332 | } else { | ||
| 333 | None | ||
| 334 | }, | ||
| 335 | )) | ||
| 321 | } else if let Ok(global_nsec) = &git_repo | 336 | } else if let Ok(global_nsec) = &git_repo |
| 322 | .get_git_config_item("nostr.nsec", Some(true)) | 337 | .get_git_config_item("nostr.nsec", Some(true)) |
| 323 | .context("failed get global git config")? | 338 | .context("failed get global git config")? |
| @@ -326,11 +341,21 @@ async fn get_signer_with_git_config_nsec_or_bunker_without_prompts( | |||
| 326 | if global_nsec.contains("ncryptsec") { | 341 | if global_nsec.contains("ncryptsec") { |
| 327 | bail!("git global config item nostr.nsec is an ncryptsec") | 342 | bail!("git global config item nostr.nsec is an ncryptsec") |
| 328 | } | 343 | } |
| 329 | Ok(Arc::new( | 344 | Ok(( |
| 330 | nostr::Keys::from_str(global_nsec).context("invalid nsec parameter")?, | 345 | Arc::new(nostr::Keys::from_str(global_nsec).context("invalid nsec parameter")?), |
| 346 | None, | ||
| 347 | )) | ||
| 348 | } else if let Ok((uri, app_key, npub)) = | ||
| 349 | get_git_config_bunker_uri_and_app_key(git_repo, Some(true)) | ||
| 350 | { | ||
| 351 | Ok(( | ||
| 352 | get_nip46_signer_from_uri_and_key(&uri, &app_key).await?, | ||
| 353 | if let Ok(pubic_key) = PublicKey::parse(npub) { | ||
| 354 | Some(pubic_key) | ||
| 355 | } else { | ||
| 356 | None | ||
| 357 | }, | ||
| 331 | )) | 358 | )) |
| 332 | } else if let Ok((uri, app_key)) = get_git_config_bunker_uri_and_app_key(git_repo, Some(true)) { | ||
| 333 | get_nip46_signer_from_uri_and_key(&uri, &app_key).await | ||
| 334 | } else { | 359 | } else { |
| 335 | bail!("cannot get nsec or bunker from git config") | 360 | bail!("cannot get nsec or bunker from git config") |
| 336 | } | 361 | } |
| @@ -339,7 +364,7 @@ async fn get_signer_with_git_config_nsec_or_bunker_without_prompts( | |||
| 339 | fn get_git_config_bunker_uri_and_app_key( | 364 | fn get_git_config_bunker_uri_and_app_key( |
| 340 | git_repo: &Repo, | 365 | git_repo: &Repo, |
| 341 | global: Option<bool>, | 366 | global: Option<bool>, |
| 342 | ) -> Result<(String, String)> { | 367 | ) -> Result<(String, String, String)> { |
| 343 | Ok(( | 368 | Ok(( |
| 344 | git_repo | 369 | git_repo |
| 345 | .get_git_config_item("nostr.bunker-uri", global) | 370 | .get_git_config_item("nostr.bunker-uri", global) |
| @@ -351,6 +376,11 @@ fn get_git_config_bunker_uri_and_app_key( | |||
| 351 | .context("failed get local git config")? | 376 | .context("failed get local git config")? |
| 352 | .context("git local config item nostr.bunker-app-key doesn't exist")? | 377 | .context("git local config item nostr.bunker-app-key doesn't exist")? |
| 353 | .to_string(), | 378 | .to_string(), |
| 379 | git_repo | ||
| 380 | .get_git_config_item("nostr.npub", global) | ||
| 381 | .context("failed get local git config")? | ||
| 382 | .context("git local config item nostr.npub doesn't exist")? | ||
| 383 | .to_string(), | ||
| 354 | )) | 384 | )) |
| 355 | } | 385 | } |
| 356 | 386 | ||
| @@ -796,6 +826,9 @@ async fn get_user_details( | |||
| 796 | } | 826 | } |
| 797 | } | 827 | } |
| 798 | } | 828 | } |
| 829 | |||
| 830 | // None: in the edge case where the user is logged in via cli arguments rather | ||
| 831 | // than from git config this may be wrong. TODO: fix this | ||
| 799 | pub async fn get_logged_in_user(git_repo_path: &Path) -> Result<Option<PublicKey>> { | 832 | pub async fn get_logged_in_user(git_repo_path: &Path) -> Result<Option<PublicKey>> { |
| 800 | let git_repo = Repo::from_path(&git_repo_path.to_path_buf())?; | 833 | let git_repo = Repo::from_path(&git_repo_path.to_path_buf())?; |
| 801 | Ok( | 834 | Ok( |