### Get Secret Service Item by Path Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html?search=std%3A%3Avec This example shows how to retrieve an item using its path. It involves creating an item, storing its path, and then fetching it in a separate operation. ```rust let path: OwnedObjectPath; // first create the item on one blocking call, set its label, and get its path { let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = create_test_default_item(&collection); item.set_label("Tester").unwrap(); path = item.item_path.clone(); } // now get the item by path on another blocking call, check its label, and delete it { let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let item = ss.get_item_by_path(path).unwrap(); let label = item.get_label().unwrap(); assert_eq!(label, "Tester"); item.delete().unwrap() ``` -------------------------------- ### Get Attributes Source: https://docs.rs/secret-service/5.1.0/src/secret_service/item.rs.html?search=std%3A%3Avec Retrieves attributes associated with an item. This example checks if a specific attribute provided during creation is returned. ```rust let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); let item = create_test_default_item(&collection).await; let attributes = item.get_attributes().await.unwrap(); // We do not compare exact attributes, since the secret service provider could add its own // at any time. Instead, we only check that the ones we provided are returned back. assert_eq!( attributes .get("test_attributes_in_item_get") .map(String::as_str), Some("test") ); item.delete().await.unwrap(); ``` -------------------------------- ### Get and Set Item Label Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates how to set a new label for an item and then retrieve it to verify the change. ```rust let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = create_test_default_item(&collection); // Set label to test and check item.set_label("Tester").unwrap(); let label = item.get_label().unwrap(); assert_eq!(label, "Tester"); item.delete().unwrap(); ``` -------------------------------- ### Get all collections Source: https://docs.rs/secret-service/5.1.0/src/secret_service/lib.rs.html Retrieves all available collections. Assumes a default collection always exists. ```rust #[tokio::test] async fn should_get_all_collections() { // Assumes that there will always be a default collection let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collections = ss.get_all_collections().await.unwrap(); assert!(!collections.is_empty(), "no collections found"); } ``` -------------------------------- ### Test Get All Items Source: https://docs.rs/secret-service/5.1.0/src/secret_service/collection.rs.html Tests retrieving all items from the default collection. ```rust let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); collection.get_all_items().await.unwrap(); ``` -------------------------------- ### Create and Get Secret (Plain) Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates creating an item with a plain text secret and then retrieving it. Ensure SecretService is connected with EncryptionType::Plain. ```rust let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = create_test_default_item(&collection); let secret = item.get_secret().unwrap(); item.delete().unwrap(); assert_eq!(secret, b"test"); ``` -------------------------------- ### Test Get All Items Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/collection.rs.html Tests retrieving all items from the default Secret Service collection. ```rust let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let collection = ss.get_default_collection().unwrap(); collection.get_all_items().unwrap(); ``` -------------------------------- ### Create and Get Encrypted Secret Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html Demonstrates creating an item with an encrypted secret using DH encryption and retrieving it. The secret is asserted to be 'test'. ```rust #[test] fn should_create_and_get_secret_encrypted() { let ss = SecretService::connect(EncryptionType::Dh).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = create_test_default_item(&collection); let secret = item.get_secret().unwrap(); item.delete().unwrap(); assert_eq!(secret, b"test"); } ``` -------------------------------- ### Get Any Collection Source: https://docs.rs/secret-service/5.1.0/secret_service/blocking/struct.SecretService.html?search=std%3A%3Avec Attempts to retrieve a collection by trying 'default', then 'session', and finally the first available collection if others fail. ```rust pub fn get_any_collection(&'a self) -> Result, Error> ``` -------------------------------- ### Connect to Secret Service Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html Establishes a connection to the Secret Service with a specified encryption type. This is a basic setup function. ```rust SecretService::connect(EncryptionType::Plain).unwrap(); ``` -------------------------------- ### Get and Set SecretService Item Attributes Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html?search= Shows how to set attributes for an item, including handling empty attribute sets, and then retrieve them to verify. ```rust let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = create_test_default_item(&collection); // Also test empty array handling item.set_attributes(HashMap::new()).unwrap(); item.set_attributes(HashMap::from([("test_attributes_in_item_get", "test")])) .unwrap(); let attributes = item.get_attributes().unwrap(); // We do not compare exact attributes, since the secret service provider could add its own // at any time. Instead, we only check that the ones we provided are returned back. assert_eq!( attributes .get("test_attributes_in_item_get") .map(String::as_str), Some("test") ); ``` -------------------------------- ### Get and Set Item Label Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html?search=std%3A%3Avec Demonstrates setting a new label for a Secret Service item and then retrieving it to verify the change. The item is deleted after the test. ```rust let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = create_test_default_item(&collection); // Set label to test and check item.set_label("Tester").unwrap(); let label = item.get_label().unwrap(); assert_eq!(label, "Tester"); item.delete().unwrap() ``` -------------------------------- ### Get and Set Item Attributes Source: https://docs.rs/secret-service/5.1.0/src/secret_service/item.rs.html Demonstrates setting item attributes, including handling an empty HashMap. This snippet focuses on the API call for setting attributes. ```Rust use std::collections::HashMap; #[tokio::test] async fn should_get_and_set_item_attributes() { let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); let item = create_test_default_item(&collection).await; // Also test empty array handling item.set_attributes(HashMap::new()).await.unwrap(); } ``` -------------------------------- ### Create and Delete Collection Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html Demonstrates how to create a new collection and then delete it. Ensure to clean up resources after use. ```rust let test_collection = ss.create_collection("Test", "").unwrap(); assert_eq!( ObjectPath::from(test_collection.collection_path.clone()), ObjectPath::try_from("/org/freedesktop/secrets/collection/Test").unwrap() ); test_collection.delete().unwrap(); ``` -------------------------------- ### Get Secret Content Type Source: https://docs.rs/secret-service/5.1.0/src/secret_service/item.rs.html?search=std%3A%3Avec Retrieves the content type of a secret associated with an item. This example uses plain text encryption. ```rust let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); let item = create_test_default_item(&collection).await; let content_type = item.get_secret_content_type().await.unwrap(); item.delete().await.unwrap(); assert_eq!(content_type, "text/plain".to_owned()); ``` -------------------------------- ### Get and Set Secret Service Item Label Source: https://docs.rs/secret-service/5.1.0/src/secret_service/item.rs.html?search=u32+-%3E+bool Demonstrates how to retrieve and set the label for a Secret Service item. It verifies that the label is correctly updated and retrieved. ```Rust #[tokio::test] async fn should_get_and_set_item_label() { let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); let item = create_test_default_item(&collection).await; // Set label to test and check item.set_label("Tester").await.unwrap(); let label = item.get_label().await.unwrap(); assert_eq!(label, "Tester"); item.delete().await.unwrap(); } ``` -------------------------------- ### Get Item by Path Source: https://docs.rs/secret-service/5.1.0/secret_service/blocking/struct.SecretService.html?search=std%3A%3Avec Retrieves a specific item using its unique object path. Returns the Item object if found. ```rust pub fn get_item_by_path( &'a self, item_path: OwnedObjectPath, ) -> Result, Error> ``` -------------------------------- ### Get Secret Content Type Source: https://docs.rs/secret-service/5.1.0/src/secret_service/item.rs.html?search= Retrieves the content type of a secret associated with an item. This example uses plain encryption and asserts the content type is 'text/plain'. ```rust #[tokio::test] async fn should_get_secret_content_type() { let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); let item = create_test_default_item(&collection).await; let content_type = item.get_secret_content_type().await.unwrap(); item.delete().await.unwrap(); assert_eq!(content_type, "text/plain".to_owned()); } ``` -------------------------------- ### Create and Search Items Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html Shows how to create an item with attributes and a secret, then search for it using various criteria. Handles cases with no results and verifies correct matches. ```rust let ss = SecretService::connect(EncryptionType::Dh).unwrap(); let collection = ss.get_default_collection().unwrap(); // Create an item let item = collection .create_item( "test", HashMap::from([("test_attribute_in_ss", "test_value")]), b"test_secret", false, "text/plain", ) .unwrap(); // handle empty vec search ss.search_items(HashMap::new()).unwrap(); // handle no result let bad_search = ss.search_items(HashMap::from([("test", "test")])).unwrap(); assert_eq!(bad_search.unlocked.len(), 0); assert_eq!(bad_search.locked.len(), 0); // handle correct search for item and compare let search_item = ss .search_items(HashMap::from([("test_attribute_in_ss", "test_value")])) .unwrap(); assert_eq!(item.item_path, search_item.unlocked[0].item_path); assert_eq!(search_item.locked.len(), 0); item.delete().unwrap(); ``` -------------------------------- ### Create and Get Secret (Plain Text) Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html?search=std%3A%3Avec Creates a secret item with a plain text secret and then retrieves it. Verifies that the secret was stored and can be accessed correctly. ```rust #[test] fn should_create_and_get_secret() { let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = create_test_default_item(&collection); let secret = item.get_secret().unwrap(); item.delete().unwrap(); assert_eq!(secret, b"test"); } ``` -------------------------------- ### Create Collection with Prompt Handling Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html?search=std%3A%3Avec Creates a new collection and handles potential prompts for authentication or confirmation. If the created object path is '/', it executes a prompt; otherwise, it returns the created path. ```rust properties.insert(SS_COLLECTION_LABEL, label.into()); let created_collection = self.service_proxy.create_collection(properties, alias)?; // This prompt handling is practically identical to create_collection let collection_path: ObjectPath = { // Get path of created object let created_path = created_collection.collection; // Check if that path is "/", if so should execute a prompt if created_path.as_str() == "/" { let prompt_path = created_collection.prompt; // Exec prompt and parse result let prompt_res = exec_prompt_blocking(self.conn.clone(), &prompt_path)?; prompt_res.try_into()? } else { // if not, just return created path created_path.into() } }; Collection::new( self.conn.clone(), &self.session, &self.service_proxy, collection_path.into(), ) ``` -------------------------------- ### Create and Get Secret (Encrypted) Source: https://docs.rs/secret-service/5.1.0/src/secret_service/item.rs.html?search=std%3A%3Avec Demonstrates creating an item with an encrypted secret and then retrieving it. Ensure SecretService is connected with EncryptionType::Dh. ```rust let ss = SecretService::connect(EncryptionType::Dh).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); let item = create_test_default_item(&collection).await; let secret = item.get_secret().await.unwrap(); item.delete().await.unwrap(); assert_eq!(secret, b"test"); ``` -------------------------------- ### Create Collection with Prompt Handling Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html?search=u32+-%3E+bool Creates a new collection and handles potential prompts for authentication or confirmation. If the created object path is '/', it executes a prompt; otherwise, it returns the created path. ```rust let created_collection = self.service_proxy.create_collection(properties, alias)?; let collection_path: ObjectPath = { let created_path = created_collection.collection; if created_path.as_str() == "/" { let prompt_path = created_collection.prompt; let prompt_res = exec_prompt_blocking(self.conn.clone(), &prompt_path)?; prompt_res.try_into()? } else { created_path.into() } }; Collection::new( self.conn.clone(), &self.session, &self.service_proxy, collection_path.into(), ) ``` -------------------------------- ### Get Any Collection Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Retrieves any available collection from the SecretService. ```rust let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let _ = ss.get_any_collection().unwrap(); ``` -------------------------------- ### Create and Delete Collection Test Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html A test case to verify the functionality of creating and subsequently deleting a collection. This snippet initiates the test setup. ```rust #[test_with::no_env(GITHUB_ACTIONS)] #[test] fn should_create_and_delete_collection() { let ss = SecretService::connect(EncryptionType::Plain).unwrap(); ``` -------------------------------- ### Create Collection with Prompt Handling Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html Creates a new collection and handles potential prompts for authentication or confirmation. This snippet demonstrates how to insert properties, create the collection, and then process the response, including executing a blocking prompt if the created path is the root. ```rust let mut properties: HashMap<&str, Value> = HashMap::new(); properties.insert(SS_COLLECTION_LABEL, label.into()); let created_collection = self.service_proxy.create_collection(properties, alias)?; // This prompt handling is practically identical to create_collection let collection_path: ObjectPath = { // Get path of created object let created_path = created_collection.collection; // Check if that path is "/", if so should execute a prompt if created_path.as_str() == "/" { let prompt_path = created_collection.prompt; // Exec prompt and parse result let prompt_res = exec_prompt_blocking(self.conn.clone(), &prompt_path)?; prompt_res.try_into()? } else { // if not, just return created path created_path.into() } }; Collection::new( self.conn.clone(), &self.session, &self.service_proxy, collection_path.into(), ) ``` -------------------------------- ### Get All Collections Source: https://docs.rs/secret-service/5.1.0/src/secret_service/lib.rs.html?search=std%3A%3Avec Retrieves all available collections from the Secret Service. ```Rust let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collections = ss.get_all_collections().await.unwrap(); assert!(!collections.is_empty(), "no collections found"); ``` -------------------------------- ### Get Collection by Path Source: https://docs.rs/secret-service/5.1.0/src/secret_service/collection.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Shows how to retrieve a specific collection from the SecretService using its unique path. This is useful when you have the path and need to access a collection directly. ```rust let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); let label = collection.get_label().await.unwrap(); // get collection by path let path = collection.collection_path.clone(); let collection_prime = ss.get_collection_by_path(path).await.unwrap(); let label_prime = collection_prime.get_label().await.unwrap(); assert_eq!(label, label_prime); ``` -------------------------------- ### Modify and Get Item Properties Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html Shows how to set a label for an item and retrieve its created and modified timestamps. Ensure the item is deleted after use. ```rust #[test] fn should_get_modified_created_props() { let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = create_test_default_item(&collection); item.set_label("Tester").unwrap(); let _created = item.get_created().unwrap(); let _modified = item.get_modified().unwrap(); item.delete().unwrap(); } ``` -------------------------------- ### Create Encrypted Session (Diffie-Hellman, Async) Source: https://docs.rs/secret-service/5.1.0/src/secret_service/session.rs.html Generates a keypair and opens an encrypted session using Diffie-Hellman asynchronously. The shared secret is then used to derive the AES key. ```rust let keypair = Keypair::generate(); let session = service_proxy .open_session(ALGORITHM_DH, keypair.public.to_bytes_be().into()) .await?; Self::encrypted_session(&keypair, session) ``` -------------------------------- ### Get Collection Label Source: https://docs.rs/secret-service/5.1.0/src/secret_service/collection.rs.html Retrieves the label associated with the collection. ```rust pub async fn get_label(&self) -> Result { Ok(self.collection_proxy.label().await?) } ``` -------------------------------- ### Create Item with Attributes Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates creating a new item and associating it with custom attributes. It verifies that the provided attributes are returned. ```rust let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = collection .create_item( "Test", HashMap::from([("test_attributes_in_item", "test")]), b"test", false, "text/plain", ) .unwrap(); let attributes = item.get_attributes().unwrap(); // We do not compare exact attributes, since the secret service provider could add its own // at any time. Instead, we only check that the ones we provided are returned back. assert_eq!( attributes .get("test_attributes_in_item") .map(String::as_str), Some("test") ); item.delete().unwrap(); ``` -------------------------------- ### Get Default Collection Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Retrieves the default collection from the SecretService. ```rust let ss = SecretService::connect(EncryptionType::Plain).unwrap(); ss.get_default_collection().unwrap(); ``` -------------------------------- ### collections (property) Source: https://docs.rs/secret-service/5.1.0/src/secret_service/proxy/service.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Gets the list of all available collection object paths. ```APIDOC ## collections (property) ### Description Gets the list of all available collection object paths. ### Method (Not specified, likely a D-Bus property getter) ### Endpoint (Not specified, D-Bus interface: org.freedesktop.Secret.Service) ### Parameters None ### Response #### Success Response - **Vec>** - A vector containing the object paths of all collections. #### Response Example (Not specified) ``` -------------------------------- ### Item::new Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html?search=u32+-%3E+bool Creates a new Item instance. This is a constructor for the Item struct, initializing it with connection details, session information, service proxy, and the item's D-Bus object path. ```APIDOC ## Item::new ### Description Constructs a new `Item` instance, establishing a connection to the Secret Service. ### Parameters - `conn` (zbus::blocking::Connection) - The blocking D-Bus connection. - `session` (&'a Session) - A reference to the active session. - `service_proxy` (&'a ServiceProxyBlocking<'a>) - A reference to the blocking service proxy. - `item_path` (OwnedObjectPath) - The D-Bus object path of the item. ### Returns - `Result` - Returns `Ok(Item)` on success, or an `Err(Error)` if initialization fails. ``` -------------------------------- ### Get and Set Secret Service Item Label Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html Demonstrates how to set a new label for a Secret Service item and then retrieve it to verify the change. The item is deleted after the operation. ```rust fn should_get_and_set_item_label() { let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = create_test_default_item(&collection); // Set label to test and check item.set_label("Tester").unwrap(); let label = item.get_label().unwrap(); assert_eq!(label, "Tester"); item.delete().unwrap(); } ``` -------------------------------- ### Create a new Item instance Source: https://docs.rs/secret-service/5.1.0/src/secret_service/item.rs.html Initializes a new `Item` instance. Requires a zbus connection, session details, a service proxy, and the item's object path. ```rust pub(crate) async fn new( conn: zbus::Connection, session: &'a Session, service_proxy: &'a ServiceProxy<'a>, item_path: OwnedObjectPath, ) -> Result, Error> { let item_proxy = ItemProxy::builder(&conn) .destination(SS_DBUS_NAME)? .path(item_path.clone())? .cache_properties(CacheProperties::No) .build() .await?; Ok(Item { conn, session, item_path, item_proxy, service_proxy, }) } ``` -------------------------------- ### Basic Usage of Secret Service Library Source: https://docs.rs/secret-service/5.1.0/index.html Demonstrates the core functionalities of the secret_service library, including connecting, creating items, searching by properties, retrieving secrets, and deleting items. Ensure you have a Secret Service implementation (like GNOME Keyring) running. ```rust use secret_service::SecretService; use secret_service::EncryptionType; use std::collections::HashMap; #[tokio::main(flavor = "current_thread")] async fn main() { // initialize secret service (dbus connection and encryption session) let ss = SecretService::connect(EncryptionType::Dh).await.unwrap(); // get default collection let collection = ss.get_default_collection().await.unwrap(); let mut properties = HashMap::new(); properties.insert("test", "test_value"); //create new item collection.create_item( "test_label", // label properties, b"test_secret", //secret false, // replace item with same attributes "text/plain" // secret content type ).await.unwrap(); // search items by properties let search_items = ss.search_items( HashMap::from([("test", "test_value")]) ).await.unwrap(); // retrieve one item, first by checking the unlocked items let item = match search_items.unlocked.first() { Some(item) => item, None => { // if there aren't any, check the locked items and unlock the first one let locked_item = search_items .locked .first() .expect("Search didn't return any items!"); locked_item.unlock().await.unwrap(); locked_item } }; // retrieve secret from item let secret = item.get_secret().await.unwrap(); assert_eq!(secret, b"test_secret"); // delete item (deletes the dbus object, not the struct instance) item.delete().await.unwrap() } ``` -------------------------------- ### Label Management Source: https://docs.rs/secret-service/5.1.0/src/secret_service/collection.rs.html?search=std%3A%3Avec Operations for getting and setting the label of a secret collection. ```APIDOC ## Label Management Methods for managing the label associated with a secret collection. ### `get_label()` Retrieves the label of the collection. - **Returns**: `Result` - The label of the collection, or an error if retrieval fails. ### `set_label(new_label: &str)` Sets a new label for the collection. - **Parameters**: - `new_label` (&str) - The new label to set for the collection. - **Returns**: `Result<(), Error>` - Ok(()) on successful update, or an error if setting the label fails. ``` -------------------------------- ### Get Item by Path Source: https://docs.rs/secret-service/5.1.0/src/secret_service/item.rs.html Demonstrates retrieving an item from the Secret Service using its unique path. The test sets a label, retrieves the item by path, and verifies the label matches. ```Rust #[tokio::test] async fn should_get_item_by_path() { let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); let item = create_test_default_item(&collection).await; // Set label to test and check item.set_label("Tester").await.unwrap(); let label = item.get_label().await.unwrap(); assert_eq!(label, "Tester"); // get item by path and check label let path = item.item_path.clone(); let item_prime = ss.get_item_by_path(path).await.unwrap(); let label_prime = item_prime.get_label().await.unwrap(); assert_eq!(label_prime, label); item.delete().await.unwrap(); } ``` -------------------------------- ### Get Encrypted Secret Across Connections Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html?search=u32+-%3E+bool Demonstrates creating an encrypted item in one connection and retrieving its secret in a separate connection. Requires items to be searchable by attributes. ```rust { // First connection: create and get secret let ss = SecretService::connect(EncryptionType::Dh).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = collection .create_item( "Test", HashMap::from([("test_attributes_in_item_encrypt", "test")]), b"test_encrypted", false, "text/plain", ) .expect("Error on item creation"); let secret = item.get_secret().unwrap(); assert_eq!(secret, b"test_encrypted"); } { // Second connection: search and get secret let ss = SecretService::connect(EncryptionType::Dh).unwrap(); let collection = ss.get_default_collection().unwrap(); let search_item = collection .search_items(HashMap::from([("test_attributes_in_item_encrypt", "test")])) .unwrap(); let item = search_item.first().unwrap(); assert_eq!(item.get_secret().unwrap(), b"test_encrypted"); item.delete().unwrap(); } ``` -------------------------------- ### Create and Delete Item Source: https://docs.rs/secret-service/5.1.0/src/secret_service/item.rs.html?search= Demonstrates the process of creating an item and then deleting it. Includes a check to ensure the item no longer exists after deletion. ```rust #[tokio::test] async fn should_create_and_delete_item() { let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); let item = create_test_default_item(&collection).await; item.delete().await.unwrap(); // Random operation to prove that path no longer exists if item.get_label().await.is_ok() { panic!("item still existed"); } } ``` -------------------------------- ### Get Default Collection Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html Retrieves the default collection managed by the Secret Service. ```rust let ss = SecretService::connect(EncryptionType::Plain).unwrap(); ss.get_default_collection().unwrap(); ``` -------------------------------- ### Create Plain Session (Async) Source: https://docs.rs/secret-service/5.1.0/src/secret_service/session.rs.html Opens a plain (unencrypted) session with the service asynchronously. No AES key is generated for this session type. ```rust let session = service_proxy .open_session(ALGORITHM_PLAIN, "".into()) .await?; let session_path = session.result; Ok(Session { object_path: session_path, aes_key: None, }) ``` -------------------------------- ### Create a new collection Source: https://docs.rs/secret-service/5.1.0/src/secret_service/lib.rs.html Creates a new collection with a specified label and icon. If the path is '/', it executes a prompt; otherwise, it returns the created path. ```rust let collection_path = if created_path.as_str() == "/" { let prompt_path = created_collection.prompt; // Exec prompt and parse result let prompt_res = exec_prompt(self.conn.clone(), &prompt_path).await?; prompt_res.try_into()? } else { // if not, just return created path created_path.into() }; Collection::new( self.conn.clone(), &self.session, &self.service_proxy, collection_path.into(), ) .await ``` -------------------------------- ### Get Collection By Path Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Retrieves a specific collection using its unique object path. ```APIDOC ## get_collection_by_path ### Description Retrieves a `Collection` object given its `OwnedObjectPath`. ### Method `get_collection_by_path(&'a self, collection_path: OwnedObjectPath) -> Result, Error>` ### Parameters #### Path Parameters - **collection_path** (OwnedObjectPath) - The unique path of the collection to retrieve. ### Response #### Success Response - **Collection<'a>** - The `Collection` object corresponding to the provided path. ### Request Example ```rust let collection_path = OwnedObjectPath::try_from("/org/example/collection/abc").unwrap(); let collection = ss.get_collection_by_path(collection_path)?; ``` ``` -------------------------------- ### Create Item with Prompt Handling Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/collection.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Creates a new item within a collection. If the created item's path is '/', it executes a prompt and parses the result; otherwise, it returns the created item's path. This is useful for collections that require specific prompt interactions upon item creation. ```rust let item_path: ObjectPath = { // Get path of created object let created_path = created_item.item; // Check if that path is "/", if so should execute a prompt if created_path.as_str() == "/" { let prompt_path = created_item.prompt; // Exec prompt and parse result let prompt_res = exec_prompt_blocking(self.conn.clone(), &prompt_path)?; prompt_res.try_into()? } else { // if not, just return created path created_path.into() } }; Item::new( self.conn.clone(), self.session, self.service_proxy, item_path.into(), ) ``` -------------------------------- ### Get Item By Path Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Retrieves a specific item using its unique object path. ```APIDOC ## get_item_by_path ### Description Retrieves an `Item` object given its `OwnedObjectPath`. ### Method `get_item_by_path(&'a self, item_path: OwnedObjectPath) -> Result, Error>` ### Parameters #### Path Parameters - **item_path** (OwnedObjectPath) - The unique path of the item to retrieve. ### Response #### Success Response - **Item<'a>** - The `Item` object corresponding to the provided path. ### Request Example ```rust let item_path = OwnedObjectPath::try_from("/org/example/item/123").unwrap(); let item = ss.get_item_by_path(item_path)?; ``` ``` -------------------------------- ### Get Secret Source: https://docs.rs/secret-service/5.1.0/secret_service/struct.Item.html Asynchronously retrieves the secret data associated with the item as a byte vector. ```rust pub async fn get_secret(&self) -> Result, Error> ``` -------------------------------- ### Create Plaintext Session (Async) Source: https://docs.rs/secret-service/5.1.0/src/secret_service/session.rs.html?search= Asynchronously opens a new session with the service using plaintext encryption. Suitable for non-blocking operations. ```rust pub async fn new( service_proxy: &ServiceProxy<'_>, encryption: EncryptionType, ) -> Result { match encryption { EncryptionType::Plain => { let session = service_proxy .open_session(ALGORITHM_PLAIN, "".into()) .await?; let session_path = session.result; Ok(Session { object_path: session_path, aes_key: None, }) } EncryptionType::Dh => { let keypair = Keypair::generate(); let session = service_proxy .open_session(ALGORITHM_DH, keypair.public.to_bytes_be().into()) .await?; Self::encrypted_session(&keypair, session) } } } ``` -------------------------------- ### Get Default Collection Source: https://docs.rs/secret-service/5.1.0/secret_service/blocking/struct.SecretService.html?search=std%3A%3Avec Retrieves the collection designated as the default. This is the collection with the alias 'default'. ```rust pub fn get_default_collection(&'a self) -> Result, Error> ``` -------------------------------- ### Create and Retrieve Item Secret Source: https://docs.rs/secret-service/5.1.0/src/secret_service/item.rs.html Demonstrates creating a new item and immediately retrieving its encrypted secret. Asserts that the retrieved secret matches the expected encrypted value. ```rust let ss = SecretService::connect(EncryptionType::Dh).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); let item = collection .create_item("test_item_name", b"test_encrypted", HashMap::new()) .await .expect("Error on item creation"); let secret = item.get_secret().await.unwrap(); assert_eq!(secret, b"test_encrypted"); ``` -------------------------------- ### Any::type_id Method Source: https://docs.rs/secret-service/5.1.0/secret_service/blocking/struct.Collection.html Gets the `TypeId` of `self`. This is a standard method for types that implement the `Any` trait. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Create and Search Secret Items Source: https://docs.rs/secret-service/5.1.0/src/secret_service/lib.rs.html Demonstrates creating a secret item with attributes and then searching for it using various criteria. Includes handling of empty searches and no-result scenarios. ```rust let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); // Create an item let item = collection .create_item( "test", HashMap::from([("test_attribute_in_ss", "test_value")]), b"test_secret", false, "text/plain", ) .await .unwrap(); // handle empty vec search ss.search_items(HashMap::new()).await.unwrap(); // handle no result let bad_search = ss .search_items(HashMap::from([("test", "test")])) .await .unwrap(); assert_eq!(bad_search.unlocked.len(), 0); assert_eq!(bad_search.locked.len(), 0); // handle correct search for item and compare let search_item = ss .search_items(HashMap::from([("test_attribute_in_ss", "test_value")])) .await .unwrap(); assert_eq!(item.item_path, search_item.unlocked[0].item_path); assert_eq!(search_item.locked.len(), 0); item.delete().await.unwrap(); ``` -------------------------------- ### Item::new Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html Creates a new Item instance. This is a constructor and not directly callable via the API. ```APIDOC ## Item::new ### Description Constructs a new `Item` instance, which represents a single secret item within the Secret Service. ### Parameters * `conn` (zbus::blocking::Connection) - The blocking ZBus connection. * `session` (&'a Session) - A reference to the active session. * `service_proxy` (&'a ServiceProxyBlocking<'a>) - A reference to the blocking Service proxy. * `item_path` (OwnedObjectPath) - The D-Bus object path of the item. ### Returns * `Result` - Ok containing the new `Item` instance on success, or an `Error` on failure. ``` -------------------------------- ### Get AES Key Source: https://docs.rs/secret-service/5.1.0/src/secret_service/session.rs.html Retrieves a reference to the AES key associated with the session, if one exists. ```rust pub fn get_aes_key(&self) -> Option<&AesKey> { self.aes_key.as_ref() } ``` -------------------------------- ### Prompt Interface Methods Source: https://docs.rs/secret-service/5.1.0/src/secret_service/proxy/prompt.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Provides methods to interact with the Secret Service's Prompt D-Bus interface. These include initiating a prompt, dismissing an existing prompt, and handling the completion signal. ```APIDOC ## Prompt Interface Methods ### Description This section details the methods available for interacting with the Secret Service's Prompt D-Bus interface. Users can initiate a prompt, dismiss an active prompt, and subscribe to completion signals. ### Methods #### `prompt` - **Description**: Initiates a prompt, typically to ask the user for credentials or confirmation. - **Parameters**: - `window_id` (string) - Required - The ID of the window associated with the prompt. - **Return Value**: `zbus::Result<()>` - Indicates success or failure of the operation. #### `dismiss` - **Description**: Dismisses the currently active prompt. - **Parameters**: None. - **Return Value**: `zbus::Result<()>` - Indicates success or failure of the operation. ### Signals #### `completed` - **Description**: Emitted when the prompt operation is completed, either by user interaction or dismissal. - **Parameters**: - `dismissed` (boolean) - Required - True if the prompt was dismissed, false otherwise. - `result` (Value<'_>) - Required - The result of the prompt operation, typically credentials or an error. This corresponds to the D-Bus `VARIANT` type. ``` -------------------------------- ### Get All Collections Source: https://docs.rs/secret-service/5.1.0/src/secret_service/lib.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Retrieves all available collections from the Secret Service. Assumes a default collection exists. ```rust #[tokio::test] async fn should_get_all_collections() { // Assumes that there will always be a default collection let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collections = ss.get_all_collections().await.unwrap(); assert!(!collections.is_empty(), "no collections found"); } ``` -------------------------------- ### Get All Collections Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Retrieves all available collections from the Secret Service. Each collection is returned as a `Collection` struct. ```rust pub fn get_all_collections(&'a self) -> Result>, Error> { let collections = self.service_proxy.collections()?; collections .into_iter() .map(|object_path| { Collection::new( self.conn.clone(), &self.session, &self.service_proxy, object_path.into(), ) }) .collect() ``` -------------------------------- ### Prompt Interface Proxy Definition Source: https://docs.rs/secret-service/5.1.0/src/secret_service/proxy/prompt.rs.html Defines the D-Bus `Prompt` interface proxy using zbus. This includes methods for prompting and dismissing, and a signal for completion. ```rust 1//! A dbus proxy for speaking with secret service's `Prompt` Interface. 2 3use zbus::zvariant::Value; 4 5/// A dbus proxy for speaking with secret service's `Prompt` Interface. 6/// 7/// This will derive PromptProxy 8/// 9/// Note that `Value` in the method signatures corresponds to `VARIANT` dbus type. 10#[zbus::proxy( 11 interface = "org.freedesktop.Secret.Prompt", 12 default_service = "org.freedesktop.Secret.Prompt" 13)] 14pub trait Prompt { 15 fn prompt(&self, window_id: &str) -> zbus::Result<()>; 16 17 fn dismiss(&self) -> zbus::Result<()>; 18 19 #[zbus(signal)] 20 fn completed(&self, dismissed: bool, result: Value<'_>) -> zbus::Result<()>; 21} ``` -------------------------------- ### Get Collection by Path Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html Retrieves a specific collection from the Secret Service using its object path. ```rust Collection::new( self.conn.clone(), &self.session, &self.service_proxy, collection_path, ) ``` -------------------------------- ### Get Item by Path Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/mod.rs.html Retrieves a specific item from the Secret Service using its object path. ```rust Item::new( self.conn.clone(), &self.session, &self.service_proxy, item_path, ) ``` -------------------------------- ### Get All Items in Collection Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/collection.rs.html?search=u32+-%3E+bool Retrieves all items within the collection. Each item is returned as an `Item` struct. ```rust pub fn get_all_items(&'a self) -> Result>, Error> { let items = self.collection_proxy.items()?; let res = items .into_iter() .map(|item_path| { Item::new( self.conn.clone(), self.session, self.service_proxy, item_path.into(), ) }) .collect::>()?; Ok(res) } ``` -------------------------------- ### Create Encrypted Session (Diffie-Hellman, Blocking) Source: https://docs.rs/secret-service/5.1.0/src/secret_service/session.rs.html Generates a keypair and opens an encrypted session using Diffie-Hellman. The shared secret is then used to derive the AES key. ```rust let keypair = Keypair::generate(); let session = service_proxy .open_session(ALGORITHM_DH, keypair.public.to_bytes_be().into())?; Self::encrypted_session(&keypair, session) ``` -------------------------------- ### Create and Delete a Test Item Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html?search=std%3A%3Avec Demonstrates the basic workflow of creating a test item and then deleting it. This is a foundational operation for testing other item functionalities. ```rust #[test] fn should_delete_item() { let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = create_test_default_item(&collection); item.delete().unwrap(); } ``` -------------------------------- ### Get Creation Timestamp Source: https://docs.rs/secret-service/5.1.0/secret_service/struct.Item.html Asynchronously retrieves the creation timestamp of the secret item, represented as a u64. ```rust pub async fn get_created(&self) -> Result ``` -------------------------------- ### Get Secret Content Type Source: https://docs.rs/secret-service/5.1.0/secret_service/struct.Item.html Asynchronously retrieves the content type of the secret stored in the item. ```rust pub async fn get_secret_content_type(&self) -> Result ``` -------------------------------- ### Create Collection Source: https://docs.rs/secret-service/5.1.0/src/secret_service/lib.rs.html?search= Creates a new collection with a specified label and alias. It inserts the label into properties and then calls the service proxy to create the collection. ```rust pub async fn create_collection( &self, label: &str, alias: &str, ) -> Result, Error> { let mut properties: HashMap<&str, Value> = HashMap::new(); properties.insert(SS_COLLECTION_LABEL, label.into()); let created_collection = self .service_proxy .create_collection(properties, alias) .await?; // This prompt handling is practically identical to create_collection let collection_path: ObjectPath = { // Get path of created object let created_path = created_collection.collection; ``` -------------------------------- ### Get All Collections Source: https://docs.rs/secret-service/5.1.0/secret_service/blocking/struct.SecretService.html?search=std%3A%3Avec Retrieves all available collections from the secret service. Returns a vector of Collection objects. ```rust pub fn get_all_collections(&'a self) -> Result>, Error> ``` -------------------------------- ### Prompt Interface Methods and Signals Source: https://docs.rs/secret-service/5.1.0/src/secret_service/proxy/prompt.rs.html?search=std%3A%3Avec This section details the methods and signals available on the Secret Service Prompt D-Bus interface, as exposed by the zbus proxy. ```APIDOC ## Prompt Interface Proxy This documentation describes the methods and signals available for the `org.freedesktop.Secret.Prompt` D-Bus interface, implemented as a proxy. ### Methods #### `prompt` * **Description**: Initiates a prompt to the user, typically for a secret. Requires a window ID for context. * **Signature**: `prompt(window_id: &str) -> zbus::Result<()>` * **Parameters**: * `window_id` (string) - Required - The ID of the window associated with the prompt. #### `dismiss` * **Description**: Dismisses the prompt without providing a secret. * **Signature**: `dismiss() -> zbus::Result<()>` * **Parameters**: None ### Signals #### `completed` * **Description**: Emitted when the prompt operation is completed, either by providing a secret or being dismissed. * **Signature**: `completed(dismissed: bool, result: Value<'_>) -> zbus::Result<()>` * **Parameters**: * `dismissed` (boolean) - Required - Indicates if the prompt was dismissed. * `result` (VARIANT) - Required - The result of the prompt operation. This can be the secret if provided, or an error. The exact type depends on the context. ``` -------------------------------- ### Create Secret Service Item with Attributes Source: https://docs.rs/secret-service/5.1.0/src/secret_service/blocking/item.rs.html?search=std%3A%3Avec Demonstrates creating a new item with specific attributes. It checks if the provided attributes are present in the created item, acknowledging that the provider might add its own. ```rust let ss = SecretService::connect(EncryptionType::Plain).unwrap(); let collection = ss.get_default_collection().unwrap(); let item = collection .create_item( "Test", HashMap::from([("test_attributes_in_item", "test")]), b"test", false, "text/plain", ) .unwrap(); let attributes = item.get_attributes().unwrap(); // We do not compare exact attributes, since the secret service provider could add its own // at any time. Instead, we only check that the ones we provided are returned back. assert_eq!( attributes .get("test_attributes_in_item") .map(String::as_str), Some("test") ); item.delete().unwrap() ``` -------------------------------- ### Get Item Creation Timestamp Source: https://docs.rs/secret-service/5.1.0/secret_service/blocking/struct.Item.html Retrieves the creation timestamp of the item. The timestamp is a u64 value. ```rust pub fn get_created(&self) -> Result ``` -------------------------------- ### Get Item Secret Content Type Source: https://docs.rs/secret-service/5.1.0/secret_service/blocking/struct.Item.html Retrieves the content type of the secret stored in the item. ```rust pub fn get_secret_content_type(&self) -> Result ``` -------------------------------- ### Get Item Attributes Source: https://docs.rs/secret-service/5.1.0/secret_service/blocking/struct.Item.html Retrieves all attributes associated with the secret item. Attributes are returned as a HashMap. ```rust pub fn get_attributes(&self) -> Result, Error> ``` -------------------------------- ### Create and Search Secret Service Items Source: https://docs.rs/secret-service/5.1.0/src/secret_service/lib.rs.html?search= This snippet shows how to create a secret item and then search for it using attributes. It covers searching with no criteria, with non-matching criteria, and with matching criteria, asserting the expected results. ```rust #[tokio::test] async fn should_search_items() { let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); let collection = ss.get_default_collection().await.unwrap(); // Create an item let item = collection .create_item( "test", HashMap::from([("test_attribute_in_ss", "test_value")]), b"test_secret", false, "text/plain", ) .await .unwrap(); // handle empty vec search ss.search_items(HashMap::new()).await.unwrap(); // handle no result let bad_search = ss .search_items(HashMap::from([("test", "test")])) .await .unwrap(); assert_eq!(bad_search.unlocked.len(), 0); assert_eq!(bad_search.locked.len(), 0); // handle correct search for item and compare let search_item = ss .search_items(HashMap::from([("test_attribute_in_ss", "test_value")])) .await .unwrap(); assert_eq!(item.item_path, search_item.unlocked[0].item_path); assert_eq!(search_item.locked.len(), 0); item.delete().await.unwrap(); } } ``` -------------------------------- ### Get collection by alias Source: https://docs.rs/secret-service/5.1.0/src/secret_service/lib.rs.html Retrieves a collection using its alias. This test specifically checks for the 'session' alias. ```rust #[tokio::test] async fn should_get_collection_by_alias() { let ss = SecretService::connect(EncryptionType::Plain).await.unwrap(); ss.get_collection_by_alias("session").await.unwrap(); } ``` -------------------------------- ### Connecting to Secret Service with Plaintext Encryption Source: https://docs.rs/secret-service/5.1.0/index.html Initializes a SecretService instance using plaintext encryption. This is a simpler connection method but offers no encryption for the secrets. ```rust SecretService::connect(EncryptionType::Plain).await.unwrap(); ```