upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2024-11-12 08:06:44 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2024-11-12 11:59:50 +0000
commita94c24b177692b8c719fafdaf2728c723657fd39 (patch)
treefcd89189ad07f8a19f90512f9c24c5b7cad1df46 /src/lib
parent98775a626b7a956378b8fa26f60a869d27068538 (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')
-rw-r--r--src/lib/login/mod.rs95
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
304async fn get_signer_with_git_config_nsec_or_bunker_without_prompts( 310async 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(
339fn get_git_config_bunker_uri_and_app_key( 364fn 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
799pub async fn get_logged_in_user(git_repo_path: &Path) -> Result<Option<PublicKey>> { 832pub 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(