diff --git a/server/src/collection.rs b/server/src/collection.rs index 42f4679f..38b1e12f 100644 --- a/server/src/collection.rs +++ b/server/src/collection.rs @@ -111,7 +111,7 @@ impl Collection { #[zbus(signal, name = "ItemChanged")] async fn item_changed( signal_emitter: &SignalEmitter<'_>, - item: OwnedObjectPath, + item: &OwnedObjectPath, ) -> zbus::Result<()>; } @@ -157,6 +157,29 @@ impl Collection { self.alias.lock().await.clone() } + pub async fn set_locked(&self, locked: bool) -> Result<(), ServiceError> { + let items = self.items.lock().await; + + for item in items.iter() { + if !item.is_locked().await { + item.set_locked(true).await?; + } + let manager = self.manager.lock().await; + let signal_emitter = manager.signal_emitter(self.path.clone())?; + Self::item_changed(&signal_emitter, item.path()).await?; + } + + if !self.is_locked().await { + self.locked + .store(locked, std::sync::atomic::Ordering::Relaxed); + 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 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..feb79e4d 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -20,7 +20,7 @@ pub struct Item { locked: Arc, inner: Arc>, // Other attributes - _manager: Arc>, + manager: Arc>, path: OwnedObjectPath, } @@ -94,11 +94,22 @@ impl Item { locked: Arc::new(AtomicBool::new(locked)), inner: Arc::new(Mutex::new(item)), path: OwnedObjectPath::try_from(format!("{}/{}", collection_path, item_index)).unwrap(), - _manager: manager, + manager, } } pub fn path(&self) -> &OwnedObjectPath { &self.path } + + pub async fn set_locked(&self, locked: bool) -> Result<(), ServiceError> { + let manager = self.manager.lock().await; + let signal_emitter = manager.signal_emitter(self.path.clone())?; + + self.locked + .store(locked, std::sync::atomic::Ordering::Relaxed); + self.locked_changed(&signal_emitter).await?; + + Ok(()) + } } diff --git a/server/src/service.rs b/server/src/service.rs index 3fa483b5..59d8d143 100644 --- a/server/src/service.rs +++ b/server/src/service.rs @@ -99,9 +99,27 @@ 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) { + 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 +200,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() }