auths_cli/commands/
reset.rs1use anyhow::{Context, Result};
2use clap::Parser;
3
4use crate::adapters::git_config::SystemGitConfigProvider;
5use crate::commands::executable::ExecutableCommand;
6use crate::config::CliConfig;
7use crate::ux::format::Output;
8use auths_sdk::ports::git_config::GitConfigProvider;
9
10const GIT_SIGNING_CONFIG_KEYS: &[&str] = &[
12 "gpg.format",
13 "gpg.ssh.program",
14 "user.signingkey",
15 "commit.gpgsign",
16 "tag.gpgsign",
17 "gpg.ssh.allowedSignersFile",
18];
19
20#[derive(Parser, Debug, Clone)]
32#[command(
33 name = "reset",
34 about = "Remove Auths identity and git signing configuration"
35)]
36pub struct ResetCommand {
37 #[arg(long)]
39 force: bool,
40}
41
42impl ExecutableCommand for ResetCommand {
43 fn execute(&self, ctx: &CliConfig) -> Result<()> {
44 let out = Output::new();
45
46 if !self.force {
47 let confirmed = dialoguer::Confirm::new()
48 .with_prompt("This will remove ~/.auths and git signing config. Continue? [y/N]")
49 .default(false)
50 .interact()
51 .context("Failed to read confirmation")?;
52
53 if !confirmed {
54 out.println("Aborted.");
55 return Ok(());
56 }
57 }
58
59 out.newline();
60 out.print_heading("Resetting Auths...");
61 out.newline();
62
63 remove_auths_directory(&out)?;
64 clear_keychain_keys(&out, &ctx.env_config);
65 unset_git_signing_config(&out)?;
66
67 out.newline();
68 out.print_success("Reset complete. Run 'auths init' to set up again.");
69
70 Ok(())
71 }
72}
73
74fn remove_auths_directory(out: &Output) -> Result<()> {
75 let auths_dir = dirs::home_dir()
76 .ok_or_else(|| anyhow::anyhow!("Cannot determine home directory"))?
77 .join(".auths");
78
79 if auths_dir.exists() {
80 std::fs::remove_dir_all(&auths_dir)
81 .with_context(|| format!("Failed to remove {}", auths_dir.display()))?;
82 out.print_success(&format!("Removed {}", auths_dir.display()));
83 } else {
84 out.print_info(&format!("{} does not exist, skipping", auths_dir.display()));
85 }
86
87 Ok(())
88}
89
90fn unset_git_signing_config(out: &Output) -> Result<()> {
91 let provider = SystemGitConfigProvider::global();
92
93 for key in GIT_SIGNING_CONFIG_KEYS {
94 match provider.unset(key) {
95 Ok(()) => out.print_success(&format!("Unset git config {key}")),
96 Err(e) => out.print_warn(&format!("Could not unset {key}: {e}")),
97 }
98 }
99
100 Ok(())
101}
102
103fn clear_keychain_keys(out: &Output, env_config: &auths_sdk::core_config::EnvironmentConfig) {
105 let keychain = match auths_sdk::keychain::get_platform_keychain_with_config(env_config) {
106 Ok(k) => k,
107 Err(e) => {
108 out.print_warn(&format!("Could not access keychain to clear keys: {e}"));
109 return;
110 }
111 };
112
113 let aliases = match keychain.list_aliases() {
114 Ok(a) => a,
115 Err(e) => {
116 out.print_warn(&format!("Could not list keychain keys: {e}"));
117 return;
118 }
119 };
120
121 if aliases.is_empty() {
122 return;
123 }
124
125 for alias in &aliases {
126 match keychain.delete_key(alias) {
127 Ok(()) => {}
128 Err(e) => {
129 out.print_warn(&format!("Could not delete key '{}': {e}", alias.as_str()));
130 }
131 }
132 }
133
134 out.print_success(&format!(
135 "Cleared {} key(s) from {} keychain",
136 aliases.len(),
137 keychain.backend_name()
138 ));
139}