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 40 41 42 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 }, 75 )76 .await?;77 Ok(())78 }79}