Repository: bilelmoussaoui/oo7 (language: rust)

Issue:
Add a log feature
When trying the migrate API, it gets stuck forever. From a quick look with bustle, it seems like the calls are properly made and the secrets are properly retrieved from the secret service; I believe something gets stuck in the file backend but there is no way to track the progress or see what is going on without logging. 

Similar to what I have done in ashpd, we could have an optional tracing feature. 


Discussion / hints:

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index 19318d1bd..94fb58fd5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,7 @@ async-std = {version = "1.11", features = ["attributes"], optional = true}
 tokio = {version = "1.17", features = ["sync", "fs", "io-util"], optional = true}
 byteorder = "1.0"
 num = "0.4.0"
+tracing = {version = "0.1", optional = true}
 
 aes = "0.8"
 cbc = "0.1"
diff --git a/src/dbus/service.rs b/src/dbus/service.rs
index 2840e19c3..c6f42b472 100644
--- a/src/dbus/service.rs
+++ b/src/dbus/service.rs
@@ -32,10 +32,14 @@ impl<'a> Service<'a> {
 
         let (aes_key, session) = match algorithm {
             Algorithm::Plain => {
+                #[cfg(feature = "tracing")]
+                tracing::debug!("Starting an unecrypted secret service session");
                 let (_service_key, session) = service.open_session(None).await?;
                 (None, session)
             }
             Algorithm::Encrypted => {
+                #[cfg(feature = "tracing")]
+                tracing::debug!("Starting an encrypted secret service session");
                 let private_key = Key::generate_private_key();
                 let public_key = Key::generate_public_key(&private_key);
                 let (service_key, session) = service.open_session(Some(&public_key)).await?;
diff --git a/src/keyring.rs b/src/keyring.rs
index da9f92cc3..13fc9421d 100644
--- a/src/keyring.rs
+++ b/src/keyring.rs
@@ -31,13 +31,22 @@ impl Keyring {
     /// Create a new instance of the Keyring.
     pub async fn new() -> Result<Self> {
         let is_sandboxed = crate::is_sandboxed();
+
         if is_sandboxed {
+            #[cfg(feature = "tracing")]
+            tracing::debug!("Application is sandboxed, using the file backend");
             Ok(Self::File(portal::Keyring::load_default().await?))
         } else {
+            #[cfg(feature = "tracing")]
+            tracing::debug!(
+                "Application is not sandboxed, falling back to the Sercret Service backend"
+            );
             let service = dbus::Service::new(Algorithm::Encrypted).await?;
             let collection = match service.default_collection().await {
                 Ok(c) => Ok(c),
                 Err(crate::dbus::Error::NotFound(_)) => {
+                    #[cfg(feature = "tracing")]
+                    tracing::debug!("Default collection doesn't exists, trying to create it");
                     service
                         .create_collection("Login", Some(DEFAULT_COLLECTION))
                         .await
diff --git a/src/portal/api/mod.rs b/src/portal/api/mod.rs
index 098bb667d..148f7df99 100644
--- a/src/portal/api/mod.rs
+++ b/src/portal/api/mod.rs
@@ -15,6 +15,8 @@ use async_std::{fs, io, prelude::*};
 #[cfg(not(feature = "async-std"))]
 use tokio::{fs, io, io::AsyncWriteExt};
 
+use std::os::unix::fs::OpenOptionsExt;
+
 use cipher::BlockSizeUser;
 use once_cell::sync::Lazy;
 use rand::Rng;
@@ -97,6 +99,8 @@ impl Keyring {
             tmp_path.push(format!(".tmpkeyring{}", rnd));
 
             if !parent.exists() {
+                #[cfg(feature = "tracing")]
+                tracing::debug!("Parent directory {:?} deosn't exists, creating it", parent);
                 fs::DirBuilder::new().recursive(true).create(parent).await?;
             }
 
@@ -104,16 +108,16 @@ impl Keyring {
         } else {
             Err(Error::NoParentDir(path.as_ref().display().to_string()))
         }?;
+        #[cfg(feature = "tracing")]
+        tracing::debug!(
+            "Created a temporary file to store the keyring on {:?}",
+            tmp_path
+        );
 
         let mut tmpfile_builder = fs::OpenOptions::new();
 
         tmpfile_builder.write(true).create_new(true);
-        #[cfg(unix)]
-        {
-            #[cfg(feature = "async-std")]
-            use std::os::unix::fs::OpenOptionsExt;
-            tmpfile_builder.mode(0o600);
-        }
+        tmpfile_builder.mode(0o600);
         let mut tmpfile = tmpfile_builder.open(&tmp_path).await?;
 
         let blob = self.as_bytes()?;
diff --git a/src/portal/mod.rs b/src/portal/mod.rs
index c1988b0db..eb9d43842 100644
--- a/src/portal/mod.rs
+++ b/src/portal/mod.rs
@@ -66,6 +66,8 @@ pub struct Keyring {
 impl Keyring {
     /// Load from default keyring file
     pub async fn load_default() -> Result<Self, Error> {
+        #[cfg(feature = "tracing")]
+        tracing::debug!("Loading default keyring file");
         let secret = secret::retrieve().await?;
         Self::load(api::Keyring::default_path()?, &secret).await
     }
@@ -77,10 +79,18 @@ impl Keyring {
     /// * `path` - The path to the file backend.
     /// * `secret` - The service key, usually retrieved from the Secrets portal.
     pub async fn load(path: impl AsRef<Path>, secret: &[u8]) -> Result<Self, Error> {
+        #[cfg(feature = "tracing")]
+        tracing::debug!("Tyring to load keyring file at {:?}", path.as_ref());
         let (mtime, keyring) = match fs::File::open(path.as_ref()).await {
-            Err(err) if err.kind() == io::ErrorKind::NotFound => (None, api::Keyring::new()),
+            Err(err) if err.kind() == io::ErrorKind::NotFound => {
+                #[cfg(feature = "tracing")]
+                tracing::debug!("Keyring file not found, creating a new one");
+                (None, api::Keyring::new())
+            }
             Err(err) => return Err(err.into()),
             Ok(mut file) => {
+                #[cfg(feature = "tracing")]
+                tracing::debug!("Keyring file found, loading it content");
                 let mtime = file.metadata().await?.modified().ok();
 
                 let mut content = Vec::new();
@@ -154,11 +164,20 @@ impl Keyring {
             keyring.items.push(encrypted_item);
         }
 
-        self.write().await?;
+        #[cfg(feature = "tracing")]
+        tracing::debug!("Writing keyring back to the file");
+        keyring.dump(&self.path, self.mtime).await?;
         Ok(())
     }
 
     pub async fn write(&self) -> Result<(), Error> {
-        self.keyring.lock().await.dump(&self.path, self.mtime).await
+        #[cfg(feature = "tracing")]
+        tracing::debug!("Writing keyring back to the file {:?}", self.path);
+        self.keyring
+            .lock()
+            .await
+            .dump(&self.path, self.mtime)
+            .await?;
+        Ok(())
     }
 }
diff --git a/src/portal/secret.rs b/src/portal/secret.rs
index 9252f0f5f..b135072b3 100644
--- a/src/portal/secret.rs
+++ b/src/portal/secret.rs
@@ -64,6 +64,11 @@ impl<'a> SecretProxy<'a> {
         ))
         .unwrap();
 
+        #[cfg(feature = "tracing")]
+        tracing::debug!(
+            "Creating a '{}' proxy and listening for a response",
+            path.as_str()
+        );
         let request_proxy: zbus::Proxy = zbus::ProxyBuilder::new_bare(cnx)
             .interface("org.freedesktop.portal.Request")?
             .destination("org.freedesktop.portal.Desktop")?
@@ -96,6 +101,8 @@ impl<'a> SecretProxy<'a> {
 
 pub async fn retrieve() -> Result<Vec<u8>, Error> {
     let connection = zbus::Connection::session().await?;
+    #[cfg(feature = "tracing")]
+    tracing::debug!("Retrieve service key using org.freedesktop.portal.Secrets");
     let proxy = SecretProxy::new(&connection).await?;
 
     let (mut x1, x2) = std::os::unix::net::UnixStream::pair()?;
@@ -104,5 +111,8 @@ pub async fn retrieve() -> Result<Vec<u8>, Error> {
     let mut buf = Vec::new();
     x1.read_to_end(&mut buf)?;
 
+    #[cfg(feature = "tracing")]
+    tracing::debug!("Secret received from the portal successfully");
+
     Ok(buf)
 }


Test patch: