Skip to content

Commit 2b8db7f

Browse files
committed
Add getting items and collections by path (blocking).
- Includes tests. - Includes lifetime declarations that are now required by clippy.
1 parent a36292a commit 2b8db7f

File tree

3 files changed

+79
-17
lines changed

3 files changed

+79
-17
lines changed

src/blocking/collection.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ impl<'a> Collection<'a> {
8888
Ok(())
8989
}
9090

91-
pub fn get_all_items(&self) -> Result<Vec<Item>, Error> {
91+
pub fn get_all_items(&'a self) -> Result<Vec<Item<'a>>, Error> {
9292
let items = self.collection_proxy.items()?;
9393

9494
// map array of item paths to Item
@@ -107,7 +107,7 @@ impl<'a> Collection<'a> {
107107
Ok(res)
108108
}
109109

110-
pub fn search_items(&self, attributes: HashMap<&str, &str>) -> Result<Vec<Item>, Error> {
110+
pub fn search_items(&'a self, attributes: HashMap<&str, &str>) -> Result<Vec<Item<'a>>, Error> {
111111
let items = self.collection_proxy.search_items(attributes)?;
112112

113113
// map array of item paths to Item
@@ -135,13 +135,13 @@ impl<'a> Collection<'a> {
135135
}
136136

137137
pub fn create_item(
138-
&self,
138+
&'a self,
139139
label: &str,
140140
attributes: HashMap<&str, &str>,
141141
secret: &[u8],
142142
replace: bool,
143143
content_type: &str,
144-
) -> Result<Item, Error> {
144+
) -> Result<Item<'a>, Error> {
145145
let secret_struct = format_secret(self.session, secret, content_type)?;
146146

147147
let mut properties: HashMap<&str, Value> = HashMap::new();
@@ -304,4 +304,24 @@ mod test {
304304

305305
collection.lock().unwrap();
306306
}
307+
308+
#[test]
309+
fn should_get_collection_by_path() {
310+
let path: OwnedObjectPath;
311+
let label: String;
312+
// get the default collection on one blocking call, remember its path and label
313+
{
314+
let ss = SecretService::connect(EncryptionType::Plain).unwrap();
315+
let collection = ss.get_default_collection().unwrap();
316+
label = collection.get_label().unwrap();
317+
path = collection.collection_path.clone();
318+
}
319+
// get collection by path on another blocking call, check that the label is the same
320+
{
321+
let ss = SecretService::connect(EncryptionType::Plain).unwrap();
322+
let collection_prime = ss.get_collection_by_path(path).unwrap();
323+
let label_prime = collection_prime.get_label().unwrap();
324+
assert_eq!(label, label_prime);
325+
}
326+
}
307327
}

src/blocking/item.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,27 @@ mod test {
213213
item.delete().unwrap();
214214
}
215215

216+
#[test]
217+
fn should_get_item_by_path() {
218+
let path: OwnedObjectPath;
219+
// first create the item on one blocking call, set its label, and get its path
220+
{
221+
let ss = SecretService::connect(EncryptionType::Plain).unwrap();
222+
let collection = ss.get_default_collection().unwrap();
223+
let item = create_test_default_item(&collection);
224+
item.set_label("Tester").unwrap();
225+
path = item.item_path.clone();
226+
}
227+
// now get the item by path on another blocking call, check its label, and delete it
228+
{
229+
let ss = SecretService::connect(EncryptionType::Plain).unwrap();
230+
let item = ss.get_item_by_path(path).unwrap();
231+
let label = item.get_label().unwrap();
232+
assert_eq!(label, "Tester");
233+
item.delete().unwrap();
234+
}
235+
}
236+
216237
#[test]
217238
fn should_create_with_item_attributes() {
218239
let ss = SecretService::connect(EncryptionType::Plain).unwrap();

src/blocking/mod.rs

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::util;
1616
use crate::{proxy::service::ServiceProxyBlocking, util::exec_prompt_blocking};
1717
use crate::{EncryptionType, Error, SearchItemsResult};
1818
use std::collections::HashMap;
19-
use zbus::zvariant::{ObjectPath, Value};
19+
use zbus::zvariant::{ObjectPath, OwnedObjectPath, Value};
2020

2121
mod collection;
2222
pub use collection::Collection;
@@ -36,7 +36,7 @@ pub struct SecretService<'a> {
3636
service_proxy: ServiceProxyBlocking<'a>,
3737
}
3838

39-
impl SecretService<'_> {
39+
impl<'a> SecretService<'a> {
4040
/// Create a new `SecretService` instance
4141
pub fn connect(encryption: EncryptionType) -> Result<Self, Error> {
4242
let conn = zbus::blocking::Connection::session().map_err(util::handle_conn_error)?;
@@ -52,7 +52,7 @@ impl SecretService<'_> {
5252
}
5353

5454
/// Get all collections
55-
pub fn get_all_collections(&self) -> Result<Vec<Collection>, Error> {
55+
pub fn get_all_collections(&'a self) -> Result<Vec<Collection<'a>>, Error> {
5656
let collections = self.service_proxy.collections()?;
5757
collections
5858
.into_iter()
@@ -72,7 +72,7 @@ impl SecretService<'_> {
7272
/// Most common would be the `default` alias, but there
7373
/// is also a specific method for getting the collection
7474
/// by default alias.
75-
pub fn get_collection_by_alias(&self, alias: &str) -> Result<Collection, Error> {
75+
pub fn get_collection_by_alias(&'a self, alias: &str) -> Result<Collection<'a>, Error> {
7676
let object_path = self.service_proxy.read_alias(alias)?;
7777

7878
if object_path.as_str() == "/" {
@@ -88,16 +88,16 @@ impl SecretService<'_> {
8888
}
8989

9090
/// Get default collection.
91-
/// (The collection whos alias is `default`)
92-
pub fn get_default_collection(&self) -> Result<Collection, Error> {
91+
/// (The collection whose alias is `default`)
92+
pub fn get_default_collection(&'a self) -> Result<Collection<'a>, Error> {
9393
self.get_collection_by_alias("default")
9494
}
9595

9696
/// Get any collection.
9797
/// First tries `default` collection, then `session`
9898
/// collection, then the first collection when it
9999
/// gets all collections.
100-
pub fn get_any_collection(&self) -> Result<Collection, Error> {
100+
pub fn get_any_collection(&'a self) -> Result<Collection<'a>, Error> {
101101
// default first, then session, then first
102102

103103
self.get_default_collection()
@@ -113,7 +113,7 @@ impl SecretService<'_> {
113113
}
114114

115115
/// Creates a new collection with a label and an alias.
116-
pub fn create_collection(&self, label: &str, alias: &str) -> Result<Collection, Error> {
116+
pub fn create_collection(&'a self, label: &str, alias: &str) -> Result<Collection<'a>, Error> {
117117
let mut properties: HashMap<&str, Value> = HashMap::new();
118118
properties.insert(SS_COLLECTION_LABEL, label.into());
119119

@@ -129,7 +129,7 @@ impl SecretService<'_> {
129129
let prompt_path = created_collection.prompt;
130130

131131
// Exec prompt and parse result
132-
let prompt_res = util::exec_prompt_blocking(self.conn.clone(), &prompt_path)?;
132+
let prompt_res = exec_prompt_blocking(self.conn.clone(), &prompt_path)?;
133133
prompt_res.try_into()?
134134
} else {
135135
// if not, just return created path
@@ -147,9 +147,9 @@ impl SecretService<'_> {
147147

148148
/// Searches all items by attributes
149149
pub fn search_items(
150-
&self,
150+
&'a self,
151151
attributes: HashMap<&str, &str>,
152-
) -> Result<SearchItemsResult<Item>, Error> {
152+
) -> Result<SearchItemsResult<Item<'a>>, Error> {
153153
let items = self.service_proxy.search_items(attributes)?;
154154

155155
let object_paths_to_items = |items: Vec<_>| {
@@ -173,7 +173,7 @@ impl SecretService<'_> {
173173
}
174174

175175
/// Unlock all items in a batch
176-
pub fn unlock_all(&self, items: &[&Item<'_>]) -> Result<(), Error> {
176+
pub fn unlock_all(&'a self, items: &[&Item]) -> Result<(), Error> {
177177
let objects = items.iter().map(|i| &*i.item_path).collect();
178178
let lock_action_res = self.service_proxy.unlock(objects)?;
179179

@@ -183,6 +183,27 @@ impl SecretService<'_> {
183183

184184
Ok(())
185185
}
186+
187+
pub fn get_item_by_path(&'a self, item_path: OwnedObjectPath) -> Result<Item<'a>, Error> {
188+
Item::new(
189+
self.conn.clone(),
190+
&self.session,
191+
&self.service_proxy,
192+
item_path,
193+
)
194+
}
195+
196+
pub fn get_collection_by_path(
197+
&'a self,
198+
collection_path: OwnedObjectPath,
199+
) -> Result<Collection<'a>, Error> {
200+
Collection::new(
201+
self.conn.clone(),
202+
&self.session,
203+
&self.service_proxy,
204+
collection_path,
205+
)
206+
}
186207
}
187208

188209
#[cfg(test)]
@@ -215,7 +236,7 @@ mod test {
215236
fn should_return_error_if_collection_doesnt_exist() {
216237
let ss = SecretService::connect(EncryptionType::Plain).unwrap();
217238

218-
match ss.get_collection_by_alias("definitely_defintely_does_not_exist") {
239+
match ss.get_collection_by_alias("definitely_definitely_does_not_exist") {
219240
Err(Error::NoResult) => {}
220241
_ => panic!(),
221242
};

0 commit comments

Comments
 (0)