1use std::collections::HashMap;2use std::marker::PhantomData;34use polkit_shared::{BackendRequest, Identity};5use ui_prompt::dbus::DbusPrompterInterface;6use ui_prompt::Prompter;7use zbus::Connection;89use crate::PolkitHelperProxy;1011use super::Helper;1213struct TemporaryPrompterInterface<P: Prompter + 'static> {14 connection: Connection,15 path: String,16 _marker: PhantomData<P>,17}18impl<P: Prompter + 'static> TemporaryPrompterInterface<P> {19 async fn new(connection: Connection, prompter: P) -> Self {20 let path = format!(21 "/remowt/prompters/{}",22 uuid::Uuid::new_v4().to_string().replace("-", "_")23 );24 let _ = connection25 .object_server()26 .at(path.clone(), DbusPrompterInterface(prompter))27 .await;28 Self {29 connection,30 path,31 _marker: PhantomData,32 }33 }34}35impl<P: Prompter + Send + Sync + 'static> Drop for TemporaryPrompterInterface<P> {36 fn drop(&mut self) {37 38 39 let connection = self.connection.clone();40 let path = std::mem::take(&mut self.path);41 tokio::spawn(async move {42 let _ = connection43 .object_server()44 .remove::<DbusPrompterInterface<P>, String>(path)45 .await;46 });47 }48}4950#[derive(Clone)]51pub struct DbusHelper {52 connection: Connection,53 helper: PolkitHelperProxy<'static>,54}55impl DbusHelper {56 pub async fn new(connection: Connection) -> zbus::Result<Self> {57 let helper = PolkitHelperProxy::new(&connection).await?;58 Ok(Self { connection, helper })59 }60}61impl Helper for DbusHelper {62 async fn help_me<P: Prompter + Send + Sync + 'static>(63 &self,64 cookie: &str,65 prompter: P,66 identity: Identity,67 ) -> anyhow::Result<()> {68 let prompter = TemporaryPrompterInterface::new(self.connection.clone(), prompter).await;69 self.helper70 .init_conversation(71 BackendRequest {72 cookie: cookie.to_owned(),73 environment: HashMap::new(),74 prompter_path: prompter.path.clone(),75 identity,76 }, 77 )78 .await?;79 Ok(())80 }81}