1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use crate::error::{KeyringError, Result};
use secret_service::{EncryptionType, SecretService};
pub struct Keyring<'a> {
attributes: Vec<(&'a str, &'a str)>,
service: &'a str,
username: &'a str,
}
impl<'a> Keyring<'a> {
pub fn new(service: &'a str, username: &'a str) -> Keyring<'a> {
let attributes = vec![("service", service), ("username", username)];
Keyring {
attributes,
service,
username,
}
}
pub fn set_password(&self, password: &str) -> Result<()> {
let ss = SecretService::new(EncryptionType::Dh)?;
let collection = ss.get_default_collection()?;
if collection.is_locked()? {
collection.unlock()?;
}
let mut attrs = self.attributes.clone();
attrs.push(("application", "rust-keyring"));
let label = &format!("Password for {} on {}", self.username, self.service)[..];
collection.create_item(
label,
attrs,
password.as_bytes(),
true,
"text/plain",
)?;
Ok(())
}
pub fn get_password(&self) -> Result<String> {
let ss = SecretService::new(EncryptionType::Dh)?;
let collection = ss.get_default_collection()?;
if collection.is_locked()? {
collection.unlock()?;
}
let search = collection.search_items(self.attributes.clone())?;
let item = search.get(0).ok_or(KeyringError::NoPasswordFound)?;
let secret_bytes = item.get_secret()?;
let secret = String::from_utf8(secret_bytes)?;
Ok(secret)
}
pub fn delete_password(&self) -> Result<()> {
let ss = SecretService::new(EncryptionType::Dh)?;
let collection = ss.get_default_collection()?;
if collection.is_locked()? {
collection.unlock()?;
}
let search = collection.search_items(self.attributes.clone())?;
let item = search.get(0).ok_or(KeyringError::NoPasswordFound)?;
Ok(item.delete()?)
}
}