diff --git a/credentialsd-common/src/model.rs b/credentialsd-common/src/model.rs index 7b4a8a80..31ad1543 100644 --- a/credentialsd-common/src/model.rs +++ b/credentialsd-common/src/model.rs @@ -46,6 +46,9 @@ pub enum Operation { #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Type)] pub struct PortalBackendOptions { + /// A token that can be used to activate the UI window. + pub activation_token: Optional, + /// Top-level origin of the request if different from the origin. pub top_origin: Optional, diff --git a/credentialsd/src/dbus/flow_control.rs b/credentialsd/src/dbus/flow_control.rs index 5ab0cc3c..7761aaac 100644 --- a/credentialsd/src/dbus/flow_control.rs +++ b/credentialsd/src/dbus/flow_control.rs @@ -25,27 +25,44 @@ use crate::{ dbus::ui_control::UiController, model::{CredentialRequest, CredentialResponse}, }; +pub struct UiRequestContext { + request: CredentialRequest, + app: RequestingApplication, + /// Client window handle + window_handle: Option, + activation_token: Option, + response_channel: oneshot::Sender>, +} pub async fn start_flow_control_service( conn: Connection, - mut listener: Receiver<( - CredentialRequest, - RequestingApplication, - Option, // Client window handle - oneshot::Sender>, - )>, + mut listener: Receiver, device_manager: M, ) -> zbus::Result { let svc = Arc::new(AsyncMutex::new(device_manager)); let svc2 = svc.clone(); let task = tokio::spawn(async move { - while let Some((msg, requesting_app, window_handle, tx)) = listener.recv().await { + while let Some(ui_request_ctx) = listener.recv().await { let svc = svc2.clone(); let ui_control_client = UiControlServiceClient::new(conn.clone()); - if let Err(_) = - tx.send(handle(svc, ui_control_client, msg, requesting_app, window_handle).await) - { + let UiRequestContext { + request, + app, + window_handle, + activation_token, + response_channel, + } = ui_request_ctx; + let response = handle( + svc, + ui_control_client, + request, + app, + window_handle, + activation_token, + ) + .await; + if let Err(_) = response_channel.send(response) { tracing::error!( "Received response to credential request, but failed to forward it to gateway" ); @@ -61,6 +78,7 @@ async fn handle, + activation_token: Option, ) -> Result { let (request_tx, request_rx) = oneshot::channel(); let request_id = svc.lock().await.init_request(&msg, request_tx).await?; @@ -112,6 +130,7 @@ async fn handle, + activation_token: Option, ) -> Result; } pub struct CredentialRequestControllerClient { - pub initiator: Sender<( - CredentialRequest, - RequestingApplication, // Application name sending the request - Option, // Client window handle, - oneshot::Sender>, - )>, + pub initiator: Sender, } #[async_trait] impl CredentialRequestController for CredentialRequestControllerClient { async fn request_credential( &self, - requesting_app: RequestingApplication, + app: RequestingApplication, request: CredentialRequest, window_handle: Option, + activation_token: Option, ) -> Result { let (tx, rx) = oneshot::channel(); self.initiator - .send((request, requesting_app, window_handle, tx)) + .send(UiRequestContext { + request, + app, + window_handle, + activation_token, + response_channel: tx, + }) .await .unwrap(); let response = rx.await.map_err(|_| { diff --git a/credentialsd/src/gateway/dbus.rs b/credentialsd/src/gateway/dbus.rs index 4f8ef8b0..26e03016 100644 --- a/credentialsd/src/gateway/dbus.rs +++ b/credentialsd/src/gateway/dbus.rs @@ -69,7 +69,7 @@ impl CredentialPortalGateway { claimed_app_display_name: Optional, ) -> PortalResult { let CreateCredentialPortalOptions { - activation_token: _, + activation_token, top_origin, public_key, } = options; @@ -114,7 +114,12 @@ impl CredentialPortalGateway { .gateway_service .lock() .await - .handle_create_credential(request, context, parent_window.into()) + .handle_create_credential( + request, + context, + parent_window.into(), + activation_token.into(), + ) .await .map_err(Error::from); @@ -133,7 +138,7 @@ impl CredentialPortalGateway { claimed_app_display_name: Optional, ) -> PortalResult { let GetCredentialPortalOptions { - activation_token: _, + activation_token, top_origin, public_key, } = options; @@ -174,7 +179,12 @@ impl CredentialPortalGateway { .gateway_service .lock() .await - .handle_get_credential(request, context, parent_window.into()) + .handle_get_credential( + request, + context, + parent_window.into(), + activation_token.into(), + ) .await .map_err(Error::from); response.into() diff --git a/credentialsd/src/gateway/mod.rs b/credentialsd/src/gateway/mod.rs index f395986d..d4ec4386 100644 --- a/credentialsd/src/gateway/mod.rs +++ b/credentialsd/src/gateway/mod.rs @@ -84,6 +84,7 @@ impl GatewayService { request: CreateCredentialRequest, context: RequestContext, parent_window: Option, + activation_token: Option, ) -> Result { let request_environment = validate_request(&context)?; @@ -110,7 +111,12 @@ impl GatewayService { let response = self .request_controller - .request_credential(context.into(), cred_request, parent_window) + .request_credential( + context.into(), + cred_request, + parent_window, + activation_token, + ) .await?; if let CredentialResponse::CreatePublicKeyCredentialResponse(cred_response) = response { @@ -142,6 +148,7 @@ impl GatewayService { request: GetCredentialRequest, context: RequestContext, parent_window: Option, + activation_token: Option, ) -> Result { let request_environment = validate_request(&context)?; @@ -166,7 +173,12 @@ impl GatewayService { let response = self .request_controller - .request_credential(context.into(), cred_request, parent_window) + .request_credential( + context.into(), + cred_request, + parent_window, + activation_token, + ) .await?; if let CredentialResponse::GetPublicKeyCredentialResponse(cred_response) = response {