Skip to main content

bitwarden_ipc/rpc/exec/
handler.rs

1use std::future::Future;
2
3use erased_serde::Serialize as ErasedSerialize;
4
5use crate::{
6    endpoint::Source,
7    rpc::{error::RpcError, request::RpcRequest, request_message::RpcRequestPayload},
8    serde_utils,
9};
10
11/// Information about an incoming RPC request that is not part of the request itself.
12///
13/// The IPC client fills this in from the message that carried the request. The source is the one
14/// reported by the [`CommunicationBackend`](crate::traits::CommunicationBackend), so how far it can
15/// be trusted for decisions such as checking which endpoint sent the request depends on that
16/// backend.
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct RpcRequestInfo {
19    /// The endpoint that sent the request, including per-variant metadata such as the origin of
20    /// a web page.
21    pub source: Source,
22}
23
24/// Trait defining a handler for RPC requests.
25/// These can registered with the IPC client and will be used to handle incoming RPC requests.
26pub trait RpcHandler {
27    /// The request type that this handler can process.
28    type Request: RpcRequest;
29
30    /// Handle the request. Any errors that occur should be defined as part of the `RpcRequest`
31    /// type. `info` describes where the request came from, see [`RpcRequestInfo`].
32    fn handle(
33        &self,
34        request: Self::Request,
35        info: RpcRequestInfo,
36    ) -> impl Future<Output = <Self::Request as RpcRequest>::Response> + Send;
37}
38
39pub(crate) trait RpcHandlerExt {
40    type Request: RpcRequest;
41
42    fn serialize_request(&self, request: Self::Request) -> Result<Vec<u8>, RpcError>;
43
44    fn deserialize_request(&self, request: Vec<u8>) -> Result<Self::Request, RpcError>;
45
46    fn serialize_response(
47        &self,
48        request: <Self::Request as RpcRequest>::Response,
49    ) -> Result<Vec<u8>, RpcError>;
50
51    fn deserialize_response(
52        &self,
53        request: Vec<u8>,
54    ) -> Result<<Self::Request as RpcRequest>::Response, RpcError>;
55}
56
57impl<T: RpcHandler> RpcHandlerExt for T
58where
59    T: RpcHandler,
60{
61    type Request = T::Request;
62
63    fn serialize_request(&self, request: Self::Request) -> Result<Vec<u8>, RpcError> {
64        serde_utils::to_vec(&request).map_err(|e| RpcError::RequestSerialization(e.to_string()))
65    }
66
67    fn deserialize_request(&self, request: Vec<u8>) -> Result<Self::Request, RpcError> {
68        serde_utils::from_slice(&request)
69            .map_err(|e| RpcError::RequestDeserialization(e.to_string()))
70    }
71
72    fn serialize_response(
73        &self,
74        request: <Self::Request as RpcRequest>::Response,
75    ) -> Result<Vec<u8>, RpcError> {
76        serde_utils::to_vec(&request).map_err(|e| RpcError::ResponseSerialization(e.to_string()))
77    }
78
79    fn deserialize_response(
80        &self,
81        request: Vec<u8>,
82    ) -> Result<<Self::Request as RpcRequest>::Response, RpcError> {
83        serde_utils::from_slice(&request)
84            .map_err(|e| RpcError::ResponseDeserialization(e.to_string()))
85    }
86}
87
88#[doc(hidden)]
89#[async_trait::async_trait]
90pub trait ErasedRpcHandler: Send + Sync {
91    async fn handle(
92        &self,
93        serialized_request: &RpcRequestPayload,
94        info: RpcRequestInfo,
95    ) -> Result<Box<dyn ErasedSerialize>, RpcError>;
96}
97
98#[async_trait::async_trait]
99impl<H> ErasedRpcHandler for H
100where
101    H: RpcHandler + Send + Sync,
102{
103    async fn handle(
104        &self,
105        serialized_request: &RpcRequestPayload,
106        info: RpcRequestInfo,
107    ) -> Result<Box<dyn ErasedSerialize>, RpcError> {
108        let request: H::Request = serialized_request.deserialize_full()?.request;
109
110        let response = self.handle(request, info).await;
111
112        Ok(Box::new(response) as Box<dyn ErasedSerialize>)
113    }
114}