bitbucket_cli/auth/
keyring_store.rs1use anyhow::{Context, Result};
2use keyring::Entry;
3
4use super::Credential;
5
6const SERVICE_NAME: &str = "bitbucket-cli";
7const CREDENTIAL_KEY: &str = "credentials";
8
9pub struct KeyringStore {
11 entry: Entry,
12}
13
14impl KeyringStore {
15 pub fn new() -> Result<Self> {
16 let entry =
17 Entry::new(SERVICE_NAME, CREDENTIAL_KEY).context("Failed to create keyring entry")?;
18 Ok(Self { entry })
19 }
20
21 pub fn store_credential(&self, credential: &Credential) -> Result<()> {
23 let json = serde_json::to_string(credential).context("Failed to serialize credential")?;
24
25 self.entry
26 .set_password(&json)
27 .context("Failed to store credential in keyring")?;
28
29 Ok(())
30 }
31
32 pub fn get_credential(&self) -> Result<Option<Credential>> {
34 match self.entry.get_password() {
35 Ok(json) => {
36 let credential: Credential =
37 serde_json::from_str(&json).context("Failed to parse stored credential")?;
38 Ok(Some(credential))
39 }
40 Err(keyring::Error::NoEntry) => Ok(None),
41 Err(e) => Err(anyhow::anyhow!(
42 "Failed to get credential from keyring: {}",
43 e
44 )),
45 }
46 }
47
48 pub fn delete_credential(&self) -> Result<()> {
50 match self.entry.delete_credential() {
51 Ok(()) => Ok(()),
52 Err(keyring::Error::NoEntry) => Ok(()), Err(e) => Err(anyhow::anyhow!(
54 "Failed to delete credential from keyring: {}",
55 e
56 )),
57 }
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 }