diff --git a/server/src/collection.rs b/server/src/collection.rs index a05f818e..cccd32ef 100644 --- a/server/src/collection.rs +++ b/server/src/collection.rs @@ -17,13 +17,13 @@ use tokio::sync::{Mutex, RwLock}; use zbus::{interface, object_server::SignalEmitter, zvariant}; use zvariant::{ObjectPath, OwnedObjectPath}; -use crate::{item, service_manager::ServiceManager}; +use crate::{error::Error, item, service_manager::ServiceManager}; #[derive(Debug)] #[allow(unused)] pub struct Collection { // Properties - items: Mutex>, + items: Mutex>, label: Mutex, locked: AtomicBool, created: Duration, @@ -33,7 +33,7 @@ pub struct Collection { #[allow(unused)] keyring: Arc, manager: Arc>, - n_items: RwLock, + item_index: RwLock, path: OwnedObjectPath, } @@ -64,12 +64,7 @@ impl Collection { #[zbus(property, name = "Items")] pub async fn items(&self) -> Vec { - self.items - .lock() - .await - .iter() - .map(|item| OwnedObjectPath::from(item.path())) - .collect() + self.items.lock().await.clone() } #[zbus(property, name = "Label")] @@ -120,6 +115,7 @@ impl Collection { pub fn new( label: &str, alias: &str, + locked: bool, manager: Arc>, keyring: Arc, ) -> Self { @@ -130,10 +126,10 @@ impl Collection { Self { items: Default::default(), label: Mutex::new(label.to_owned()), - locked: AtomicBool::new(true), + locked: AtomicBool::new(locked), modified: Mutex::new(created), alias: Mutex::new(alias.to_owned()), - n_items: RwLock::new(0), + item_index: RwLock::new(0), path: OwnedObjectPath::try_from(format!( "/org/freedesktop/secrets/collection/{}", label @@ -156,4 +152,28 @@ impl Collection { pub async fn alias(&self) -> String { self.alias.lock().await.clone() } + + pub async fn dispatch_items(&self, object_server: &zbus::ObjectServer) -> Result<(), Error> { + let keyring_items = self.keyring.items().await; + let mut items = self.items.lock().await; + let mut n_items = 1; + + for keyring_item in keyring_items { + let item = item::Item::new( + keyring_item.map_err(Error::InvalidItem)?, + self.is_locked().await, + Arc::clone(&self.manager), + self.path.clone(), + n_items, + ); + n_items += 1; + + items.push(item.path().clone()); + object_server.at(item.path().clone(), item).await?; + } + + *self.item_index.write().await = n_items; + + Ok(()) + } } diff --git a/server/src/error.rs b/server/src/error.rs index 38a922de..07143cb0 100644 --- a/server/src/error.rs +++ b/server/src/error.rs @@ -10,6 +10,8 @@ pub enum Error { IO(std::io::Error), // Empty password error EmptyPassword, + // Invalid item error + InvalidItem(oo7::portal::InvalidItemError), } impl From for Error { @@ -37,6 +39,7 @@ impl fmt::Display for Error { Self::Zbus(err) => write!(f, "Zbus error {err}"), Self::IO(err) => write!(f, "IO error {err}"), Self::EmptyPassword => write!(f, "Login password can't be empty"), + Self::InvalidItem(err) => write!(f, "Item cannot be decrypted {err}"), } } } diff --git a/server/src/item.rs b/server/src/item.rs index 10ab8549..0b93f422 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -1,15 +1,27 @@ // org.freedesktop.Secret.Item -use std::{collections::HashMap, sync::atomic::AtomicBool}; +use std::{ + collections::HashMap, + sync::{atomic::AtomicBool, Arc}, +}; -use oo7::dbus::{api::SecretInner, ServiceError}; +use oo7::{ + dbus::{api::SecretInner, ServiceError}, + portal, +}; use tokio::sync::Mutex; use zbus::zvariant::{ObjectPath, OwnedObjectPath}; +use crate::service_manager::ServiceManager; + #[derive(Debug)] +#[allow(unused)] pub struct Item { + // Properties locked: AtomicBool, inner: Mutex, + // Other attributes + manager: Arc>, path: OwnedObjectPath, } @@ -72,7 +84,22 @@ impl Item { } impl Item { - pub fn path(&self) -> ObjectPath<'_> { - self.path.as_ref() + pub fn new( + item: portal::Item, + locked: bool, + manager: Arc>, + collection_path: OwnedObjectPath, + item_index: u32, + ) -> Self { + Self { + locked: AtomicBool::new(locked), + inner: Mutex::new(item), + path: OwnedObjectPath::try_from(format!("{}/{}", collection_path, item_index)).unwrap(), + manager, + } + } + + pub fn path(&self) -> &OwnedObjectPath { + &self.path } } diff --git a/server/src/service.rs b/server/src/service.rs index 76d58405..090a443c 100644 --- a/server/src/service.rs +++ b/server/src/service.rs @@ -220,10 +220,12 @@ impl Service { let collection = Collection::new( "login", "default", + false, Arc::clone(&service.manager), Arc::new(Keyring::open("login", secret).await?), ); collections.push(collection.path().clone()); + collection.dispatch_items(object_server).await?; object_server .at(collection.path().clone(), collection) .await?; @@ -232,6 +234,7 @@ impl Service { let collection = Collection::new( "session", "session", + false, Arc::clone(&service.manager), Arc::new(Keyring::temporary(Secret::random()).await?), ); @@ -240,8 +243,6 @@ impl Service { .at(collection.path().clone(), collection) .await?; - drop(collections); - Ok(()) } }