git.delta.rocks / remowt / refs/commits / a70745c0fb24

difftreelog

source

cmds/remowt-agent/src/helper/dbus.rs2.4 KiBsourcehistory
1use std::collections::HashMap;2use std::marker::PhantomData;34use polkit_shared::{BackendRequest, Identity};5use tokio::runtime::Handle;6use ui_prompt::dbus::DbusPrompterInterface;7use ui_prompt::Prompter;8use zbus::Connection;910use crate::PolkitHelperProxy;1112use super::Helper;131415struct TemporaryPrompterInterface<P: Prompter + 'static> {16    connection: Connection,17    path: String,18    _marker: PhantomData<P>,19}20impl<P: Prompter + 'static> TemporaryPrompterInterface<P> {21    async fn new(connection: Connection, prompter: P) -> Self {22        let path = format!(23            "/remowt/prompters/{}",24            uuid::Uuid::new_v4().to_string().replace("-", "_")25        );26        let _ = connection27            .object_server()28            .at(path.clone(), DbusPrompterInterface(prompter))29            .await;30        Self {31            connection,32            path,33            _marker: PhantomData,34        }35    }36}37impl<P: Prompter + Send + Sync + 'static> Drop for TemporaryPrompterInterface<P> {38    fn drop(&mut self) {39        // FIXME: block_in_place prevents to moving to current_thread runtime40        // There should be a blocking way to remove ObjectServer listener.41        // As far as I can see, it is only async because of async RwLock, shouldn't it be42        // just a sync lock?43        tokio::task::block_in_place(move || {44            Handle::current().block_on(async {45                let _ = self46                    .connection47                    .object_server()48                    .remove::<DbusPrompterInterface<P>, String>(self.path.clone())49                    .await;50            });51        });52    }53}5455pub struct DbusHelper {56    connection: Connection,57    helper: PolkitHelperProxy<'static>,58}59impl Helper for DbusHelper {60    async fn help_me<P: Prompter + Send + Sync + 'static>(61        &self,62        cookie: &str,63        prompter: P,64        identity: Identity,65    ) -> anyhow::Result<()> {66        let prompter = TemporaryPrompterInterface::new(self.connection.clone(), prompter).await;67        self.helper68            .init_conversation(69                BackendRequest {70                    cookie: cookie.to_owned(),71                    environment: HashMap::new(),72                    prompter_path: prompter.path.clone(),73                    identity,74                }, // cookie.to_owned(), HashMap::new(), prompter.path.clone()75            )76            .await?;77        Ok(())78    }79}