diff --git a/server/src/collection.rs b/server/src/collection.rs index 42f4679f..73c70c04 100644 --- a/server/src/collection.rs +++ b/server/src/collection.rs @@ -109,9 +109,9 @@ impl Collection { ) -> zbus::Result<()>; #[zbus(signal, name = "ItemChanged")] - async fn item_changed( + pub async fn item_changed( signal_emitter: &SignalEmitter<'_>, - item: OwnedObjectPath, + item: &OwnedObjectPath, ) -> zbus::Result<()>; } @@ -157,6 +157,26 @@ impl Collection { self.alias.lock().await.clone() } + pub async fn inner_items(&self) -> Vec { + self.items.lock().await.to_vec() + } + + pub async fn locked_updated(&self) -> Result<(), ServiceError> { + let manager = self.manager.lock().await; + let signal_emitter = manager.signal_emitter(self.path.clone())?; + self.locked_changed(&signal_emitter).await?; + + Ok(()) + } + + pub async fn set_locked(&self, locked: bool) -> Result<(), ServiceError> { + self.locked + .store(locked, std::sync::atomic::Ordering::Relaxed); + self.locked_updated().await?; + + Ok(()) + } + pub async fn dispatch_items(&self) -> Result<(), Error> { let keyring_items = self.keyring.items().await; let mut items = self.items.lock().await; diff --git a/server/src/item.rs b/server/src/item.rs index 38b832cf..51f50dd2 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -12,7 +12,7 @@ use oo7::{ use tokio::sync::Mutex; use zbus::zvariant::{ObjectPath, OwnedObjectPath}; -use crate::service_manager::ServiceManager; +use crate::{collection::Collection, service_manager::ServiceManager}; #[derive(Debug, Clone)] pub struct Item { @@ -20,7 +20,8 @@ pub struct Item { locked: Arc, inner: Arc>, // Other attributes - _manager: Arc>, + manager: Arc>, + collection_path: OwnedObjectPath, path: OwnedObjectPath, } @@ -93,12 +94,31 @@ impl Item { Self { locked: Arc::new(AtomicBool::new(locked)), inner: Arc::new(Mutex::new(item)), + collection_path: collection_path.clone(), path: OwnedObjectPath::try_from(format!("{}/{}", collection_path, item_index)).unwrap(), - _manager: manager, + manager, } } pub fn path(&self) -> &OwnedObjectPath { &self.path } + + pub async fn locked_updated(&self) -> Result<(), ServiceError> { + let manager = self.manager.lock().await; + let signal_emitter = manager.signal_emitter(self.path.clone())?; + self.locked_changed(&signal_emitter).await?; + let signal_emitter = manager.signal_emitter(self.collection_path.clone())?; + Collection::item_changed(&signal_emitter, &self.path).await?; + + Ok(()) + } + + pub async fn set_locked(&self, locked: bool) -> Result<(), ServiceError> { + self.locked + .store(locked, std::sync::atomic::Ordering::Relaxed); + self.locked_updated().await?; + + Ok(()) + } } diff --git a/server/src/service.rs b/server/src/service.rs index 3fa483b5..57b3d473 100644 --- a/server/src/service.rs +++ b/server/src/service.rs @@ -99,9 +99,34 @@ impl Service { #[zbus(out_args("locked", "prompt"))] pub async fn lock( &mut self, - _objects: Vec, + objects: Vec, + #[zbus(signal_emitter)] signal_emitter: SignalEmitter<'_>, ) -> Result<(Vec, ObjectPath), ServiceError> { - todo!() + let mut locked: Vec = Vec::new(); + let prompt = ObjectPath::default(); + let collections = self.collections.lock().await; + + for object in &objects { + for collection in collections.iter() { + if object == collection.path() || collection.items().await.contains(object) { + for item in collection.inner_items().await { + if !item.is_locked().await { + item.set_locked(true).await?; + } + } + if !collection.is_locked().await { + collection.set_locked(true).await?; + } + locked.push(object.clone()); + Self::collection_changed(&signal_emitter, collection.path()).await?; + tracing::info!("Object: {} is locked.", object); + break; + } + tracing::info!("Object: {} does not exist.", object); + } + } + + Ok((locked, prompt)) } #[zbus(out_args("secrets"))] @@ -182,7 +207,7 @@ impl Service { #[zbus(signal, name = "CollectionChanged")] async fn collection_changed( signal_emitter: &SignalEmitter<'_>, - collection: OwnedObjectPath, + collection: &OwnedObjectPath, ) -> zbus::Result<()>; } diff --git a/server/src/service_manager.rs b/server/src/service_manager.rs index 5435d8f0..e25512ee 100644 --- a/server/src/service_manager.rs +++ b/server/src/service_manager.rs @@ -25,6 +25,15 @@ impl ServiceManager { self.connection.object_server() } + pub fn signal_emitter( + &self, + path: OwnedObjectPath, + ) -> Result { + let signal_emitter = zbus::object_server::SignalEmitter::new(&self.connection, path)?; + + Ok(signal_emitter) + } + pub fn n_sessions(&self) -> usize { self.sessions.len() }