fj/src/auth/mod.rs

41 lines
1.3 KiB
Rust
Raw Normal View History

//! Token storage. Tokens live in the OS keychain under service `fj`, keyed by
//! hostname. We deliberately do not write tokens to disk.
use anyhow::{Context, Result};
use keyring::Entry;
const SERVICE: &str = "fj";
fn entry(host: &str) -> Result<Entry> {
Entry::new(SERVICE, host).with_context(|| format!("opening keychain entry for {host}"))
}
/// Save a token for `host`. Replaces any existing entry.
pub fn store_token(host: &str, token: &str) -> Result<()> {
let entry = entry(host)?;
entry
.set_password(token)
.with_context(|| format!("writing token for {host} to keychain"))?;
Ok(())
}
/// Look up the stored token for `host`. Returns `Ok(None)` when not present
/// rather than an error so callers can prompt for login.
pub fn load_token(host: &str) -> Result<Option<String>> {
let entry = entry(host)?;
match entry.get_password() {
Ok(token) => Ok(Some(token)),
Err(keyring::Error::NoEntry) => Ok(None),
Err(e) => Err(e).with_context(|| format!("reading token for {host} from keychain")),
}
}
pub fn delete_token(host: &str) -> Result<()> {
let entry = entry(host)?;
match entry.delete_credential() {
Ok(()) => Ok(()),
Err(keyring::Error::NoEntry) => Ok(()),
Err(e) => Err(e).with_context(|| format!("removing token for {host} from keychain")),
}
}