cadmus_core/github/
device_flow.rs1use crate::device::CURRENT_DEVICE;
2use secrecy::{ExposeSecret, SecretString};
3use std::fs::{self, File};
4use std::io::{Read, Write};
5use std::path::PathBuf;
6
7const TOKEN_FILENAME: &str = ".github_token";
8
9pub fn save_token(token: &SecretString) -> Result<(), String> {
17 let path = token_path();
18 tracing::debug!(path = %path.display(), "Saving GitHub token");
19
20 if let Some(parent) = path.parent() {
21 fs::create_dir_all(parent).map_err(|e| format!("Failed to create token dir: {}", e))?;
22 }
23
24 let mut file =
25 File::create(&path).map_err(|e| format!("Failed to create token file: {}", e))?;
26 file.write_all(token.expose_secret().as_bytes())
27 .map_err(|e| format!("Failed to write token: {}", e))?;
28
29 #[cfg(unix)]
30 {
31 use std::os::unix::fs::PermissionsExt;
32 fs::set_permissions(&path, fs::Permissions::from_mode(0o600))
33 .map_err(|e| format!("Failed to set token file permissions: {}", e))?;
34 }
35
36 tracing::info!("GitHub token saved");
37 Ok(())
38}
39
40pub fn load_token() -> Result<Option<SecretString>, String> {
48 let path = token_path();
49 tracing::debug!(path = %path.display(), "Loading GitHub token");
50
51 if !path.exists() {
52 tracing::debug!("No saved token found");
53 return Ok(None);
54 }
55
56 let mut contents = String::new();
57 File::open(&path)
58 .map_err(|e| format!("Failed to open token file: {}", e))?
59 .read_to_string(&mut contents)
60 .map_err(|e| format!("Failed to read token file: {}", e))?;
61
62 let token = contents.trim().to_owned();
63 if token.is_empty() {
64 tracing::warn!("Token file exists but is empty");
65 return Ok(None);
66 }
67
68 tracing::info!("GitHub token loaded from disk");
69 Ok(Some(SecretString::from(token)))
70}
71
72pub fn delete_token() -> Result<(), String> {
83 let path = token_path();
84 tracing::debug!(path = %path.display(), "Deleting GitHub token");
85
86 if !path.exists() {
87 return Ok(());
88 }
89
90 fs::remove_file(&path).map_err(|e| format!("Failed to delete token file: {}", e))?;
91 tracing::info!("GitHub token deleted");
92 Ok(())
93}
94
95fn token_path() -> PathBuf {
96 CURRENT_DEVICE.install_path(TOKEN_FILENAME)
97}