diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-11-25 12:31:50 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-11-25 12:31:50 +0000 |
| commit | b09cf3ef8bbb5d31e4c424ff28282f5029f95fb2 (patch) | |
| tree | 7081e193a6dfa0dc076191dcd66ea974df69695b /src | |
| parent | 264c6dfe4229cd73bf017f55be0178d596cf06eb (diff) | |
fix(login): handle git config save errors
to guide the users how to login dispite the git config errors
Diffstat (limited to 'src')
| -rw-r--r-- | src/bin/ngit/sub_commands/login.rs | 56 | ||||
| -rw-r--r-- | src/lib/login/fresh.rs | 83 |
2 files changed, 133 insertions, 6 deletions
diff --git a/src/bin/ngit/sub_commands/login.rs b/src/bin/ngit/sub_commands/login.rs index 1a70118..7bb0906 100644 --- a/src/bin/ngit/sub_commands/login.rs +++ b/src/bin/ngit/sub_commands/login.rs | |||
| @@ -2,7 +2,7 @@ use anyhow::{Context, Result}; | |||
| 2 | use clap; | 2 | use clap; |
| 3 | use ngit::{ | 3 | use ngit::{ |
| 4 | cli_interactor::{Interactor, InteractorPrompt, PromptChoiceParms}, | 4 | cli_interactor::{Interactor, InteractorPrompt, PromptChoiceParms}, |
| 5 | git::remove_git_config_item, | 5 | git::{get_git_config_item, remove_git_config_item}, |
| 6 | login::{existing::load_existing_login, SignerInfoSource}, | 6 | login::{existing::load_existing_login, SignerInfoSource}, |
| 7 | }; | 7 | }; |
| 8 | 8 | ||
| @@ -101,14 +101,39 @@ async fn logout(git_repo: Option<&Repo>, local_only: bool) -> Result<(bool, bool | |||
| 101 | "nostr.bunker-uri", | 101 | "nostr.bunker-uri", |
| 102 | "nostr.bunker-app-key", | 102 | "nostr.bunker-app-key", |
| 103 | ] { | 103 | ] { |
| 104 | remove_git_config_item( | 104 | if let Err(error) = remove_git_config_item( |
| 105 | if source == SignerInfoSource::GitLocal { | 105 | if source == SignerInfoSource::GitLocal { |
| 106 | &git_repo | 106 | &git_repo |
| 107 | } else { | 107 | } else { |
| 108 | &None | 108 | &None |
| 109 | }, | 109 | }, |
| 110 | item, | 110 | item, |
| 111 | )?; | 111 | ) { |
| 112 | eprintln!("{error:?}"); | ||
| 113 | |||
| 114 | eprintln!( | ||
| 115 | "consider manually removing {} git config items: {}", | ||
| 116 | if source == SignerInfoSource::GitGlobal { | ||
| 117 | "global" | ||
| 118 | } else { | ||
| 119 | "local" | ||
| 120 | }, | ||
| 121 | format_items_as_list(&get_global_login_config_items_set()) | ||
| 122 | ); | ||
| 123 | match Interactor::default().choice( | ||
| 124 | PromptChoiceParms::default().with_default(0).with_choices( | ||
| 125 | vec![ | ||
| 126 | "continue with global login to reveal what git config items to manually set".to_string(), | ||
| 127 | "login to this local repository with a different account".to_string(), | ||
| 128 | "cancel".to_string(), | ||
| 129 | ] | ||
| 130 | ), | ||
| 131 | )? { | ||
| 132 | 0 => return Ok((true, false)), | ||
| 133 | 1 => return Ok((true, true)), | ||
| 134 | _ => return Ok((false, local_only)), | ||
| 135 | } | ||
| 136 | } | ||
| 112 | } | 137 | } |
| 113 | } | 138 | } |
| 114 | 1 => return Ok((false, local_only)), | 139 | 1 => return Ok((false, local_only)), |
| @@ -118,3 +143,28 @@ async fn logout(git_repo: Option<&Repo>, local_only: bool) -> Result<(bool, bool | |||
| 118 | } | 143 | } |
| 119 | Ok((true, local_only)) | 144 | Ok((true, local_only)) |
| 120 | } | 145 | } |
| 146 | |||
| 147 | fn get_global_login_config_items_set() -> Vec<&'static str> { | ||
| 148 | [ | ||
| 149 | "nostr.nsec", | ||
| 150 | "nostr.npub", | ||
| 151 | "nostr.bunker-uri", | ||
| 152 | "nostr.bunker-app-key", | ||
| 153 | ] | ||
| 154 | .iter() | ||
| 155 | .copied() | ||
| 156 | .filter(|item| get_git_config_item(&None, item).is_ok_and(|item| item.is_some())) | ||
| 157 | .collect::<Vec<&str>>() | ||
| 158 | } | ||
| 159 | |||
| 160 | fn format_items_as_list(items: &[&str]) -> String { | ||
| 161 | match items.len() { | ||
| 162 | 0 => String::new(), | ||
| 163 | 1 => items[0].to_string(), | ||
| 164 | 2 => format!("{} and {}", items[0], items[1]), | ||
| 165 | _ => { | ||
| 166 | let all_but_last = items[..items.len() - 1].join(", "); | ||
| 167 | format!("{}, and {}", all_but_last, items[items.len() - 1]) | ||
| 168 | } | ||
| 169 | } | ||
| 170 | } | ||
diff --git a/src/lib/login/fresh.rs b/src/lib/login/fresh.rs index e8cfcb8..194f638 100644 --- a/src/lib/login/fresh.rs +++ b/src/lib/login/fresh.rs | |||
| @@ -93,7 +93,7 @@ pub async fn fresh_login_or_signup( | |||
| 93 | } | 93 | } |
| 94 | } | 94 | } |
| 95 | }; | 95 | }; |
| 96 | let _ = save_to_git_config(git_repo, &signer_info, !save_local); | 96 | let _ = save_to_git_config(git_repo, &signer_info, !save_local).await; |
| 97 | let user_ref = get_user_details( | 97 | let user_ref = get_user_details( |
| 98 | &public_key, | 98 | &public_key, |
| 99 | client, | 99 | client, |
| @@ -483,7 +483,7 @@ fn generate_qr(data: &str) -> Result<Vec<String>> { | |||
| 483 | Ok(lines) | 483 | Ok(lines) |
| 484 | } | 484 | } |
| 485 | 485 | ||
| 486 | fn save_to_git_config( | 486 | async fn save_to_git_config( |
| 487 | git_repo: &Option<&Repo>, | 487 | git_repo: &Option<&Repo>, |
| 488 | signer_info: &SignerInfo, | 488 | signer_info: &SignerInfo, |
| 489 | global: bool, | 489 | global: bool, |
| @@ -516,7 +516,64 @@ fn save_to_git_config( | |||
| 516 | } | 516 | } |
| 517 | } | 517 | } |
| 518 | if global { | 518 | if global { |
| 519 | save_to_git_config(git_repo, signer_info, false)? | 519 | loop { |
| 520 | match Interactor::default().choice( | ||
| 521 | PromptChoiceParms::default() | ||
| 522 | .with_default(0) | ||
| 523 | .with_choices(vec![ | ||
| 524 | "i'll update global git config manually with above values".to_string(), | ||
| 525 | "only log into local git repository (save to local git config)" | ||
| 526 | .to_string(), | ||
| 527 | "one time login".to_string(), | ||
| 528 | ]), | ||
| 529 | )? { | ||
| 530 | 0 => { | ||
| 531 | // check | ||
| 532 | if let Ok((_, user_ref, _)) = load_existing_login( | ||
| 533 | git_repo, | ||
| 534 | &None, | ||
| 535 | &None, | ||
| 536 | &Some(SignerInfoSource::GitGlobal), | ||
| 537 | None, | ||
| 538 | true, | ||
| 539 | true, | ||
| 540 | ) | ||
| 541 | .await | ||
| 542 | { | ||
| 543 | if user_ref.public_key == get_pubkey_from_signer_info(signer_info)? { | ||
| 544 | return Ok(()); | ||
| 545 | } else { | ||
| 546 | eprintln!( | ||
| 547 | "global git config hasn't been updated with different npub" | ||
| 548 | ); | ||
| 549 | } | ||
| 550 | } else { | ||
| 551 | eprintln!( | ||
| 552 | "global git config hasn't been updated with nostr login values" | ||
| 553 | ); | ||
| 554 | } | ||
| 555 | } | ||
| 556 | 1 => { | ||
| 557 | if let Err(error) = | ||
| 558 | silently_save_to_git_config(git_repo, signer_info, false).context( | ||
| 559 | format!( | ||
| 560 | "failed to save login details to {} git config", | ||
| 561 | if global { "global" } else { "local" } | ||
| 562 | ), | ||
| 563 | ) | ||
| 564 | { | ||
| 565 | eprintln!("Error: {:?}", error); | ||
| 566 | eprintln!("login details were not saved"); | ||
| 567 | } else { | ||
| 568 | eprintln!( | ||
| 569 | "saved login details to local git config. you are only logged in to this local repository." | ||
| 570 | ); | ||
| 571 | } | ||
| 572 | return Ok(()); | ||
| 573 | } | ||
| 574 | _ => return Ok(()), | ||
| 575 | } | ||
| 576 | } | ||
| 520 | } | 577 | } |
| 521 | Err(error) | 578 | Err(error) |
| 522 | } else { | 579 | } else { |
| @@ -532,6 +589,26 @@ fn save_to_git_config( | |||
| 532 | } | 589 | } |
| 533 | } | 590 | } |
| 534 | 591 | ||
| 592 | fn get_pubkey_from_signer_info(signer_info: &SignerInfo) -> Result<PublicKey> { | ||
| 593 | let npub = match signer_info { | ||
| 594 | SignerInfo::Bunker { | ||
| 595 | bunker_uri: _, | ||
| 596 | bunker_app_key: _, | ||
| 597 | npub, | ||
| 598 | } => npub, | ||
| 599 | SignerInfo::Nsec { | ||
| 600 | nsec: _, | ||
| 601 | password: _, | ||
| 602 | npub, | ||
| 603 | } => npub, | ||
| 604 | }; | ||
| 605 | if let Some(npub) = npub { | ||
| 606 | PublicKey::parse(npub).context("format of npub string in signer_info is invalid") | ||
| 607 | } else { | ||
| 608 | bail!("no npub in signer_info object"); | ||
| 609 | } | ||
| 610 | } | ||
| 611 | |||
| 535 | fn silently_save_to_git_config( | 612 | fn silently_save_to_git_config( |
| 536 | git_repo: &Option<&Repo>, | 613 | git_repo: &Option<&Repo>, |
| 537 | signer_info: &SignerInfo, | 614 | signer_info: &SignerInfo, |