use exchange::proxy::{Proxy, ProxyAuth};
const PROXY_KEYCHAIN_SERVICE: &str = "flowsurface.proxy";
fn proxy_entry_for(proxy: &Proxy) -> Result<keyring::Entry, keyring::Error> {
let key = proxy.to_url_string_no_auth();
keyring::Entry::new(PROXY_KEYCHAIN_SERVICE, &key)
}
pub fn load_proxy_auth(proxy: &Proxy) -> Option<ProxyAuth> {
let key = proxy.to_url_string_no_auth();
let entry = match proxy_entry_for(proxy) {
Ok(e) => e,
Err(err) => {
log::warn!(
"Keychain entry init failed for service={PROXY_KEYCHAIN_SERVICE} key={key}: {err}"
);
return None;
}
};
let secret = match entry.get_password() {
Ok(s) => s,
Err(err) => {
log::info!(
"No proxy auth in keychain for service={PROXY_KEYCHAIN_SERVICE} key={key}: {err}"
);
return None;
}
};
match serde_json::from_str::<ProxyAuth>(&secret) {
Ok(auth) => Some(auth),
Err(err) => {
log::warn!(
"Proxy auth in keychain is invalid JSON for service={PROXY_KEYCHAIN_SERVICE} key={key}: {err}"
);
None
}
}
}
pub fn save_proxy_auth(proxy: &Proxy) {
let key = proxy.to_url_string_no_auth();
let Some(auth) = proxy.auth() else {
log::info!(
"Not saving proxy auth: auth is None (service={PROXY_KEYCHAIN_SERVICE} key={key})"
);
return;
};
let entry = match proxy_entry_for(proxy) {
Ok(e) => e,
Err(err) => {
log::warn!(
"Keychain entry init failed for service={PROXY_KEYCHAIN_SERVICE} key={key}: {err}"
);
return;
}
};
let secret = match serde_json::to_string(auth) {
Ok(s) => s,
Err(err) => {
log::warn!(
"Failed to serialize proxy auth for service={PROXY_KEYCHAIN_SERVICE} key={key}: {err}"
);
return;
}
};
match entry.set_password(&secret) {
Ok(()) => {
log::info!("Stored proxy auth in keychain (service={PROXY_KEYCHAIN_SERVICE} key={key})")
}
Err(err) => {
log::warn!(
"Failed to store proxy auth in keychain (service={PROXY_KEYCHAIN_SERVICE} key={key}): {err}"
);
}
}
}
pub fn delete_proxy_auth(proxy: &Proxy) {
let key = proxy.to_url_string_no_auth();
let entry = match proxy_entry_for(proxy) {
Ok(e) => e,
Err(err) => {
log::warn!(
"Keychain entry init failed for service={PROXY_KEYCHAIN_SERVICE} key={key}: {err}"
);
return;
}
};
match entry.delete_credential() {
Ok(()) => log::info!(
"Deleted proxy auth from keychain (service={PROXY_KEYCHAIN_SERVICE} key={key})"
),
Err(keyring::Error::NoEntry) => { }
Err(err) => log::warn!(
"Failed to delete proxy auth from keychain (service={PROXY_KEYCHAIN_SERVICE} key={key}): {err}"
),
}
}
const SERVER_KEYCHAIN_SERVICE: &str = "flowsurface.server";
fn server_entry_for(url: &str) -> Result<keyring::Entry, keyring::Error> {
keyring::Entry::new(SERVER_KEYCHAIN_SERVICE, url)
}
pub fn load_server_token(url: &str) -> Option<String> {
let entry = match server_entry_for(url) {
Ok(e) => e,
Err(err) => {
log::warn!(
"Keychain entry init failed for service={SERVER_KEYCHAIN_SERVICE} key={url}: {err}"
);
return None;
}
};
match entry.get_password() {
Ok(token) => {
log::info!(
"Loaded server auth token from keychain (service={SERVER_KEYCHAIN_SERVICE} key={url})"
);
Some(token)
}
Err(keyring::Error::NoEntry) => {
log::info!(
"No server auth token in keychain for service={SERVER_KEYCHAIN_SERVICE} key={url}"
);
None
}
Err(err) => {
log::warn!(
"Failed to read server auth token from keychain (service={SERVER_KEYCHAIN_SERVICE} key={url}): {err}"
);
None
}
}
}
pub fn save_server_token(url: &str, token: &str) {
let entry = match server_entry_for(url) {
Ok(e) => e,
Err(err) => {
log::warn!(
"Keychain entry init failed for service={SERVER_KEYCHAIN_SERVICE} key={url}: {err}"
);
return;
}
};
match entry.set_password(token) {
Ok(()) => log::info!(
"Stored server auth token in keychain (service={SERVER_KEYCHAIN_SERVICE} key={url})"
),
Err(err) => log::warn!(
"Failed to store server auth token in keychain (service={SERVER_KEYCHAIN_SERVICE} key={url}): {err}"
),
}
}
pub fn delete_server_token(url: &str) {
let entry = match server_entry_for(url) {
Ok(e) => e,
Err(err) => {
log::warn!(
"Keychain entry init failed for service={SERVER_KEYCHAIN_SERVICE} key={url}: {err}"
);
return;
}
};
match entry.delete_credential() {
Ok(()) => log::info!(
"Deleted server auth token from keychain (service={SERVER_KEYCHAIN_SERVICE} key={url})"
),
Err(keyring::Error::NoEntry) => { }
Err(err) => log::warn!(
"Failed to delete server auth token from keychain (service={SERVER_KEYCHAIN_SERVICE} key={url}): {err}"
),
}
}