diff --git a/Cargo.toml b/Cargo.toml index b2ec831..ee06113 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ gstreamer-player = "0.16.3" isahc = "0.9.12" once_cell = "1.5.2" rand = "0.7.3" -secret-service = "1.1.1" +secret-service = "2.0.1" serde = { version = "1.0.117", features = ["derive"] } serde_json = "1.0.59" uuid = { version = "0.8", features = ["v4"] } diff --git a/src/backend/secure.rs b/src/backend/secure.rs index d52bada..508541d 100644 --- a/src/backend/secure.rs +++ b/src/backend/secure.rs @@ -1,71 +1,47 @@ -use super::LoginData; -use anyhow::{anyhow, Result}; +use crate::backend::LoginData; +use anyhow::Result; use futures_channel::oneshot; use secret_service::{Collection, EncryptionType, SecretService}; +use std::collections::HashMap; +use std::thread; /// Savely store the user's current login credentials. pub async fn store_login_data(data: LoginData) -> Result<()> { - let (sender, receiver) = oneshot::channel::>(); - std::thread::spawn(move || sender.send(store_login_data_priv(data))); + let (sender, receiver) = oneshot::channel(); + thread::spawn(move || sender.send(store_login_data_priv(data)).unwrap()); receiver.await? } /// Savely store the user's current login credentials. fn store_login_data_priv(data: LoginData) -> Result<()> { - let ss = get_ss()?; + let ss = SecretService::new(EncryptionType::Dh)?; let collection = get_collection(&ss)?; let key = "musicus-login-data"; delete_secrets(&collection, key)?; - collection - .create_item( - key, - vec![("username", &data.username)], - data.password.as_bytes(), - true, - "text/plain", - ) - .or(Err(anyhow!( - "Failed to save login data using SecretService!" - )))?; + let mut attributes = HashMap::new(); + attributes.insert("username", data.username.as_str()); + collection.create_item(key, attributes, data.password.as_bytes(), true, "text/plain")?; Ok(()) } /// Get the login credentials from secret storage. pub fn load_login_data() -> Result> { - let ss = get_ss()?; + let ss = SecretService::new(EncryptionType::Dh)?; let collection = get_collection(&ss)?; - let items = collection.get_all_items().or(Err(anyhow!( - "Failed to get items from SecretService collection!" - )))?; + let items = collection.get_all_items()?; let key = "musicus-login-data"; - let item = items - .iter() - .find(|item| item.get_label().unwrap_or_default() == key); + let item = items.iter().find(|item| item.get_label().unwrap_or_default() == key); Ok(match item { Some(item) => { - let attrs = item.get_attributes().or(Err(anyhow!( - "Failed to get attributes for ScretService item!" - )))?; - - let username = attrs - .iter() - .find(|attr| attr.0 == "username") - .ok_or(anyhow!("No username in login data!"))? - .1 - .clone(); - - let password = std::str::from_utf8( - &item - .get_secret() - .or(Err(anyhow!("Failed to get secret from SecretService!")))?, - )? - .to_string(); + // TODO: Delete the item when malformed. + let username = item.get_attributes()?.get("username").unwrap().to_owned(); + let password = std::str::from_utf8(&item.get_secret()?)?.to_owned(); Some(LoginData { username, password }) } @@ -75,34 +51,21 @@ pub fn load_login_data() -> Result> { /// Delete all stored secrets for the provided key. fn delete_secrets(collection: &Collection, key: &str) -> Result<()> { - let items = collection.get_all_items().or(Err(anyhow!( - "Failed to get items from SecretService collection!" - )))?; + let items = collection.get_all_items()?; for item in items { if item.get_label().unwrap_or_default() == key { - item.delete() - .or(Err(anyhow!("Failed to delete SecretService item!")))?; + item.delete()?; } } Ok(()) } -/// Get the SecretService interface. -fn get_ss() -> Result { - SecretService::new(EncryptionType::Dh).or(Err(anyhow!("Failed to get SecretService!"))) -} - /// Get the default SecretService collection and unlock it. -fn get_collection(ss: &SecretService) -> Result { - let collection = ss - .get_default_collection() - .or(Err(anyhow!("Failed to get SecretService connection!")))?; - - collection - .unlock() - .or(Err(anyhow!("Failed to unclock SecretService collection!")))?; +fn get_collection<'a>(ss: &'a SecretService) -> Result> { + let collection = ss.get_default_collection()?; + collection.unlock()?; Ok(collection) }