auths_cli/commands/
whoami.rs1use anyhow::{Result, anyhow};
2use auths_sdk::domains::identity::local::{LocalSigner, resolve_local_signer};
3use auths_sdk::storage_layout as layout;
4use clap::Parser;
5use serde::Serialize;
6
7use crate::config::CliConfig;
8use crate::ux::format::{JsonResponse, Output, is_json_mode};
9
10#[derive(Parser, Debug, Clone)]
12#[command(
13 name = "whoami",
14 about = "Show the current identity on this machine",
15 after_help = "Examples:
16 auths whoami # Show the current identity
17 auths whoami --json # JSON output
18
19Related:
20 auths status — Show full identity and device status
21 auths init — Initialize a new identity"
22)]
23pub struct WhoamiCommand {}
24
25#[derive(Debug, Serialize)]
26struct WhoamiResponse {
27 identity_did: String,
28 #[serde(skip_serializing_if = "Option::is_none")]
29 label: Option<String>,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 device_did: Option<String>,
32 #[serde(skip_serializing_if = "Option::is_none")]
35 public_key_hex: Option<String>,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 curve: Option<String>,
38}
39
40fn current_key_hex(repo_path: &std::path::Path, did: &str) -> Option<(String, String)> {
43 let registry = auths_sdk::storage::GitRegistryBackend::from_config_unchecked(
44 auths_sdk::storage::RegistryConfig::single_tenant(repo_path),
45 );
46 let (pk, curve) = auths_sdk::keri::resolve_current_public_key(®istry, did).ok()?;
47 Some((hex::encode(pk), format!("{curve:?}").to_lowercase()))
48}
49
50fn local_signer(repo_path: &std::path::Path) -> Option<LocalSigner> {
53 let env_config = auths_sdk::core_config::EnvironmentConfig::from_env();
54 let ctx = crate::factories::storage::build_auths_context(repo_path, &env_config, None).ok()?;
55 resolve_local_signer(&ctx).ok()
56}
57
58pub fn handle_whoami(_cmd: WhoamiCommand, repo: Option<std::path::PathBuf>) -> Result<()> {
59 let repo_path = layout::resolve_repo_path(repo).map_err(|e| anyhow!(e))?;
60
61 let signer = crate::factories::storage::open_git_repo(&repo_path)
66 .ok()
67 .and_then(|_| local_signer(&repo_path));
68
69 let Some(signer) = signer else {
70 if is_json_mode() {
71 JsonResponse::<()>::error(
72 "whoami",
73 "No identity found. Run `auths init` to get started.",
74 )
75 .print()?;
76 } else {
77 let out = Output::new();
78 out.print_error("No identity found. Run `auths init` to get started.");
79 }
80 return Ok(());
81 };
82
83 let key = current_key_hex(&repo_path, &signer.signer_did);
86 let response = WhoamiResponse {
87 identity_did: signer.root_did.clone(),
88 label: None,
89 device_did: Some(signer.signer_did.clone()),
90 public_key_hex: key.as_ref().map(|(hex, _)| hex.clone()),
91 curve: key.as_ref().map(|(_, curve)| curve.clone()),
92 };
93
94 if is_json_mode() {
95 JsonResponse::success("whoami", &response).print()?;
96 } else {
97 let out = Output::new();
98 out.println(&format!("Identity: {}", out.info(&response.identity_did)));
99 if let Some(ref device) = response.device_did {
100 out.println(&format!("Device: {}", out.dim(device)));
101 }
102 }
103
104 Ok(())
105}
106
107impl crate::commands::executable::ExecutableCommand for WhoamiCommand {
108 fn execute(&self, ctx: &CliConfig) -> Result<()> {
109 handle_whoami(self.clone(), ctx.repo_path.clone())
110 }
111}