use std::fmt;
use ::keyring::Entry;
use secrecy::{ExposeSecret, SecretString};
use crate::AuthError;
pub struct TokenHandle {
service: String,
username: String,
}
impl Clone for TokenHandle {
fn clone(&self) -> Self {
Self {
service: self.service.clone(),
username: self.username.clone(),
}
}
}
impl fmt::Debug for TokenHandle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TokenHandle")
.field("service", &self.service)
.field("username", &self.username)
.finish()
}
}
impl TokenHandle {
pub(crate) fn new(service: impl Into<String>, username: impl Into<String>) -> Self {
Self {
service: service.into(),
username: username.into(),
}
}
fn entry(&self) -> Result<Entry, AuthError> {
Ok(Entry::new(&self.service, &self.username)?)
}
pub(crate) fn store(&self, secret: &SecretString) -> Result<(), AuthError> {
self.entry()?.set_password(secret.expose_secret())?;
Ok(())
}
pub fn read(&self) -> Result<SecretString, AuthError> {
Ok(SecretString::from(self.entry()?.get_password()?))
}
pub fn revoke(&self) -> Result<(), AuthError> {
match self.entry()?.delete_credential() {
Ok(()) => Ok(()),
Err(::keyring::Error::NoEntry) => Ok(()),
Err(e) => Err(e.into()),
}
}
}