Always use SecretService asynchronously

This commit is contained in:
Elias Projahn 2021-02-04 22:24:01 +01:00
parent 5d06ec9faf
commit 9256e60122
2 changed files with 71 additions and 62 deletions

View file

@ -74,7 +74,7 @@ impl Backend {
} }
} }
if let Some(data) = secure::load_login_data()? { if let Some(data) = Self::load_login_data().await? {
self.client.set_login_data(data); self.client.set_login_data(data);
} }
@ -95,7 +95,7 @@ impl Backend {
/// Set the user credentials to use. /// Set the user credentials to use.
pub async fn set_login_data(&self, data: LoginData) -> Result<()> { pub async fn set_login_data(&self, data: LoginData) -> Result<()> {
secure::store_login_data(data.clone()).await?; Self::store_login_data(data.clone()).await?;
self.client.set_login_data(data); self.client.set_login_data(data);
Ok(()) Ok(())
} }

View file

@ -1,36 +1,29 @@
use crate::Result; use crate::{Backend, Result};
use musicus_client::LoginData; use musicus_client::LoginData;
use futures_channel::oneshot; use futures_channel::oneshot;
use secret_service::{Collection, EncryptionType, SecretService}; use secret_service::{Collection, EncryptionType, SecretService};
use std::collections::HashMap; use std::collections::HashMap;
use std::thread; use std::thread;
/// Savely store the user's current login credentials. impl Backend {
pub async fn store_login_data(data: LoginData) -> Result<()> { /// Get the login credentials from secret storage.
pub(super) async fn load_login_data() -> Result<Option<LoginData>> {
let (sender, receiver) = oneshot::channel(); let (sender, receiver) = oneshot::channel();
thread::spawn(move || sender.send(store_login_data_priv(data)).unwrap()); thread::spawn(move || sender.send(Self::load_login_data_priv()).unwrap());
receiver.await? receiver.await?
} }
/// Savely store the user's current login credentials. /// Savely store the user's current login credentials.
fn store_login_data_priv(data: LoginData) -> Result<()> { pub(super) async fn store_login_data(data: LoginData) -> Result<()> {
let (sender, receiver) = oneshot::channel();
thread::spawn(move || sender.send(Self::store_login_data_priv(data)).unwrap());
receiver.await?
}
/// Get the login credentials from secret storage.
fn load_login_data_priv() -> Result<Option<LoginData>> {
let ss = SecretService::new(EncryptionType::Dh)?; let ss = SecretService::new(EncryptionType::Dh)?;
let collection = get_collection(&ss)?; let collection = Self::get_collection(&ss)?;
let key = "musicus-login-data";
delete_secrets(&collection, key)?;
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<Option<LoginData>> {
let ss = SecretService::new(EncryptionType::Dh)?;
let collection = get_collection(&ss)?;
let items = collection.get_all_items()?; let items = collection.get_all_items()?;
@ -47,10 +40,25 @@ pub fn load_login_data() -> Result<Option<LoginData>> {
} }
None => None, None => None,
}) })
} }
/// Delete all stored secrets for the provided key. /// Savely store the user's current login credentials.
fn delete_secrets(collection: &Collection, key: &str) -> Result<()> { fn store_login_data_priv(data: LoginData) -> Result<()> {
let ss = SecretService::new(EncryptionType::Dh)?;
let collection = Self::get_collection(&ss)?;
let key = "musicus-login-data";
Self::delete_secrets(&collection, key)?;
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(())
}
/// Delete all stored secrets for the provided key.
fn delete_secrets(collection: &Collection, key: &str) -> Result<()> {
let items = collection.get_all_items()?; let items = collection.get_all_items()?;
for item in items { for item in items {
@ -60,12 +68,13 @@ fn delete_secrets(collection: &Collection, key: &str) -> Result<()> {
} }
Ok(()) Ok(())
} }
/// Get the default SecretService collection and unlock it. /// Get the default SecretService collection and unlock it.
fn get_collection<'a>(ss: &'a SecretService) -> Result<Collection<'a>> { fn get_collection<'a>(ss: &'a SecretService) -> Result<Collection<'a>> {
let collection = ss.get_default_collection()?; let collection = ss.get_default_collection()?;
collection.unlock()?; collection.unlock()?;
Ok(collection) Ok(collection)
}
} }