|
1 | 1 | use std::sync::Arc; |
2 | 2 |
|
3 | 3 | use async_std::{ |
4 | | - channel::{self, Receiver, Sender}, |
5 | | - stream::StreamExt, |
| 4 | + channel::{self, Sender}, |
6 | 5 | sync::Mutex as AsyncMutex, |
7 | 6 | task::JoinHandle, |
8 | 7 | }; |
9 | 8 | use zbus::{ |
10 | | - Connection, ObjectServer, fdo, interface, |
| 9 | + ObjectServer, fdo, interface, |
11 | 10 | message::Header, |
12 | 11 | names::{BusName, OwnedUniqueName}, |
13 | 12 | object_server::SignalEmitter, |
14 | | - proxy, |
15 | 13 | zvariant::{ObjectPath, Optional}, |
16 | 14 | }; |
17 | 15 |
|
18 | 16 | use credentialsd_common::{ |
19 | | - client::FlowController, |
20 | 17 | model::{ |
21 | 18 | Device, Operation, PortalBackendOptions, RequestId, RequestingApplication, |
22 | 19 | UserInteractedEvent, |
23 | 20 | }, |
24 | 21 | server::{BackgroundEvent, ViewRequest, WindowHandle}, |
25 | 22 | }; |
26 | 23 |
|
27 | | -use crate::client::{DbusCredentialClient, FlowControlClient}; |
28 | | - |
29 | | -#[proxy( |
30 | | - gen_blocking = false, |
31 | | - interface = "xyz.iinuwa.credentialsd.FlowControl1", |
32 | | - default_path = "/xyz/iinuwa/credentialsd/FlowControl", |
33 | | - default_service = "xyz.iinuwa.credentialsd.FlowControl" |
34 | | -)] |
35 | | -pub trait FlowControlService { |
36 | | - async fn subscribe(&self) -> fdo::Result<()>; |
37 | | - |
38 | | - async fn get_available_public_key_devices(&self) -> fdo::Result<Vec<Device>>; |
39 | | - |
40 | | - async fn get_hybrid_credential(&self) -> fdo::Result<()>; |
41 | | - |
42 | | - async fn get_usb_credential(&self) -> fdo::Result<()>; |
43 | | - async fn get_nfc_credential(&self) -> fdo::Result<()>; |
44 | | - |
45 | | - async fn select_device(&self, device_id: String) -> fdo::Result<()>; |
46 | | - async fn enter_client_pin(&self, pin: String) -> fdo::Result<()>; |
47 | | - async fn select_credential(&self, credential_id: String) -> fdo::Result<()>; |
48 | | - async fn cancel_request(&self, request_id: RequestId) -> fdo::Result<()>; |
49 | | - |
50 | | - #[zbus(signal)] |
51 | | - async fn state_changed(update: BackgroundEvent) -> zbus::Result<()>; |
52 | | -} |
53 | | - |
54 | | -pub struct UiControlService { |
55 | | - pub request_tx: Sender<(ViewRequest, Arc<AsyncMutex<FlowControlClient>>)>, |
56 | | -} |
57 | | - |
58 | | -/// These methods are called by the credential service to control the UI. |
59 | | -#[interface(name = "xyz.iinuwa.credentialsd.UiControl1")] |
60 | | -impl UiControlService { |
61 | | - async fn launch_ui( |
62 | | - &self, |
63 | | - #[zbus(connection)] conn: &Connection, |
64 | | - request: ViewRequest, |
65 | | - ) -> fdo::Result<()> { |
66 | | - tracing::debug!("Received UI launch request"); |
67 | | - let mut client = DbusCredentialClient::new(conn.clone()); |
68 | | - let (fc_tx, fc_rx) = async_std::channel::unbounded(); |
69 | | - let (bg_tx, bg_rx) = async_std::channel::unbounded(); |
70 | | - match client.subscribe().await { |
71 | | - Ok(mut bg_event_stream) => async_std::task::spawn(async move { |
72 | | - while let Some(bg_event) = bg_event_stream.next().await { |
73 | | - if let Err(_) = bg_tx.send(bg_event).await { |
74 | | - tracing::debug!("Background event receiver dropped. Stopping."); |
75 | | - break; |
76 | | - } |
77 | | - } |
78 | | - }), |
79 | | - Err(_) => { |
80 | | - tracing::error!( |
81 | | - ?request, |
82 | | - "Failed to subscribe to background events for request" |
83 | | - ); |
84 | | - return Err(fdo::Error::Failed( |
85 | | - "Failed to subscribe to background events for request".to_string(), |
86 | | - )); |
87 | | - } |
88 | | - }; |
89 | | - async_std::task::spawn(async move { |
90 | | - while let Ok(msg) = fc_rx.recv().await { |
91 | | - // UI doesn't get an error if these fail... |
92 | | - let result = match &msg { |
93 | | - UserInteractedEvent::HybridDiscoveryRequested => { |
94 | | - client.get_hybrid_credential().await |
95 | | - } |
96 | | - UserInteractedEvent::NfcDiscoveryRequested => client.get_nfc_credential().await, |
97 | | - UserInteractedEvent::UsbDiscoveryRequested => client.get_usb_credential().await, |
98 | | - UserInteractedEvent::ClientPinEntered(pin) => { |
99 | | - client.enter_client_pin(pin.to_string()).await |
100 | | - } |
101 | | - UserInteractedEvent::CredentialSelected(cred_id) => { |
102 | | - client.select_credential(cred_id.to_string()).await |
103 | | - } |
104 | | - UserInteractedEvent::RequestCancelled => { |
105 | | - client.cancel_request(request.id).await |
106 | | - } |
107 | | - }; |
108 | | - if let Err(err) = result { |
109 | | - tracing::error!("Failed to send {msg:?} to frontend: {err:?}"); |
110 | | - } |
111 | | - } |
112 | | - client |
113 | | - }); |
114 | | - let flow_control_client = FlowControlClient { |
115 | | - tx: fc_tx, |
116 | | - rx: AsyncMutex::new(Some(bg_rx)), |
117 | | - }; |
118 | | - self.request_tx |
119 | | - .send((request, Arc::new(AsyncMutex::new(flow_control_client)))) |
120 | | - .await |
121 | | - .map_err(|_| fdo::Error::Failed("UI failed to launch".to_string())) |
122 | | - } |
123 | | -} |
| 24 | +use crate::client::FlowControlClient; |
124 | 25 |
|
125 | 26 | pub struct CredentialPortalBackend { |
126 | 27 | pub request_tx: Sender<(ViewRequest, Arc<AsyncMutex<FlowControlClient>>)>, |
|
0 commit comments