Skip to main content

codex_cli/auth/
current.rs

1use anyhow::Result;
2use std::path::Path;
3
4use crate::auth;
5use crate::fs;
6use crate::paths;
7
8pub fn run() -> Result<i32> {
9    let auth_file = match paths::resolve_auth_file() {
10        Some(path) => path,
11        None => return Ok(1),
12    };
13
14    if !auth_file.is_file() {
15        eprintln!("codex: {} not found", auth_file.display());
16        return Ok(1);
17    }
18
19    let auth_key = auth::identity_key_from_auth_file(&auth_file).ok().flatten();
20    let auth_hash = match fs::sha256_file(&auth_file) {
21        Ok(hash) => hash,
22        Err(_) => {
23            eprintln!("codex: failed to hash {}", auth_file.display());
24            return Ok(1);
25        }
26    };
27
28    let secret_dir = paths::resolve_secret_dir();
29    let mut matched: Option<(String, MatchMode)> = None;
30
31    if let Some(secret_dir) = secret_dir
32        && let Ok(entries) = std::fs::read_dir(&secret_dir)
33    {
34        for entry in entries.flatten() {
35            let path = entry.path();
36            if path.extension().and_then(|s| s.to_str()) != Some("json") {
37                continue;
38            }
39
40            if let Some(key) = auth_key.as_deref()
41                && let Ok(Some(candidate_key)) = auth::identity_key_from_auth_file(&path)
42                && candidate_key == key
43            {
44                let candidate_hash = match fs::sha256_file(&path) {
45                    Ok(hash) => hash,
46                    Err(_) => {
47                        eprintln!("codex: failed to hash {}", path.display());
48                        return Ok(1);
49                    }
50                };
51                let mode = if candidate_hash == auth_hash {
52                    MatchMode::Exact
53                } else {
54                    MatchMode::Identity
55                };
56                matched = Some((file_name(&path), mode));
57                break;
58            }
59
60            let candidate_hash = match fs::sha256_file(&path) {
61                Ok(hash) => hash,
62                Err(_) => {
63                    eprintln!("codex: failed to hash {}", path.display());
64                    return Ok(1);
65                }
66            };
67            if candidate_hash == auth_hash {
68                matched = Some((file_name(&path), MatchMode::Exact));
69                break;
70            }
71        }
72    }
73
74    if let Some((secret_name, mode)) = matched {
75        match mode {
76            MatchMode::Exact => {
77                println!("codex: {} matches {}", auth_file.display(), secret_name);
78            }
79            MatchMode::Identity => {
80                println!(
81                    "codex: {} matches {} (identity; secret differs)",
82                    auth_file.display(),
83                    secret_name
84                );
85            }
86        }
87        return Ok(0);
88    }
89
90    println!(
91        "codex: {} does not match any known secret",
92        auth_file.display()
93    );
94    Ok(2)
95}
96
97#[derive(Copy, Clone)]
98enum MatchMode {
99    Exact,
100    Identity,
101}
102
103fn file_name(path: &Path) -> String {
104    path.file_name()
105        .and_then(|name| name.to_str())
106        .unwrap_or_default()
107        .to_string()
108}