atlassian_cli_auth/
lib.rs1use anyhow::{Context, Result};
2use std::collections::HashMap;
3use std::fs::{self, OpenOptions};
4use std::path::PathBuf;
5
6#[cfg(unix)]
7use std::os::unix::fs::OpenOptionsExt;
8
9pub fn token_key(profile: &str) -> String {
11 profile.to_string()
12}
13
14fn credentials_path() -> Option<PathBuf> {
15 dirs::home_dir().map(|h| h.join(".atlassian-cli").join("credentials"))
16}
17
18pub fn set_secret(account: &str, secret: &str) -> Result<()> {
20 let path = credentials_path().context("Cannot determine home directory")?;
21 if let Some(parent) = path.parent() {
22 fs::create_dir_all(parent)?;
23 }
24
25 let mut creds: HashMap<String, String> = if path.exists() {
26 let content = fs::read_to_string(&path)?;
27 serde_json::from_str(&content).unwrap_or_default()
28 } else {
29 HashMap::new()
30 };
31
32 creds.insert(account.to_string(), secret.to_string());
33
34 #[cfg(unix)]
35 {
36 use std::io::Write;
37 let mut file = OpenOptions::new()
38 .write(true)
39 .create(true)
40 .truncate(true)
41 .mode(0o600)
42 .open(&path)?;
43 let json = serde_json::to_string_pretty(&creds)?;
44 file.write_all(json.as_bytes())?;
45 }
46
47 #[cfg(not(unix))]
48 {
49 let file = OpenOptions::new()
50 .write(true)
51 .create(true)
52 .truncate(true)
53 .open(&path)?;
54 serde_json::to_writer_pretty(file, &creds)?;
55 }
56
57 Ok(())
58}
59
60pub fn get_secret(account: &str) -> Result<Option<String>> {
62 let path = credentials_path().context("Cannot determine home directory")?;
63 if !path.exists() {
64 return Ok(None);
65 }
66 let content = fs::read_to_string(&path)?;
67 let creds: HashMap<String, String> = serde_json::from_str(&content)?;
68 Ok(creds.get(account).cloned())
69}
70
71pub fn delete_secret(account: &str) -> Result<()> {
73 let path = credentials_path().context("Cannot determine home directory")?;
74 if !path.exists() {
75 return Ok(());
76 }
77 let content = fs::read_to_string(&path)?;
78 let mut creds: HashMap<String, String> = serde_json::from_str(&content).unwrap_or_default();
79 creds.remove(account);
80
81 #[cfg(unix)]
82 {
83 use std::io::Write;
84 let mut file = OpenOptions::new()
85 .write(true)
86 .create(true)
87 .truncate(true)
88 .mode(0o600)
89 .open(&path)?;
90 let json = serde_json::to_string_pretty(&creds)?;
91 file.write_all(json.as_bytes())?;
92 }
93
94 #[cfg(not(unix))]
95 {
96 let file = OpenOptions::new()
97 .write(true)
98 .create(true)
99 .truncate(true)
100 .open(&path)?;
101 serde_json::to_writer_pretty(file, &creds)?;
102 }
103
104 Ok(())
105}