mssf_core/client/
connection.rs1use mssf_com::{
7 FabricClient::{
8 IFabricClientConnectionEventHandler, IFabricClientConnectionEventHandler_Impl,
9 IFabricClientConnectionEventHandler2, IFabricClientConnectionEventHandler2_Impl,
10 IFabricGatewayInformationResult,
11 },
12 FabricTypes::FABRIC_CLAIMS_RETRIEVAL_METADATA,
13};
14
15use crate::{WString, types::NodeId};
16
17pub trait ClientConnectionEventHandler: 'static {
20 fn on_connected(&self, info: &GatewayInformationResult) -> crate::Result<()>;
21 fn on_disconnected(&self, info: &GatewayInformationResult) -> crate::Result<()>;
22 fn on_claims_retrieval(&self, metadata: ClaimsRetrievalMetadata) -> crate::Result<WString>;
23}
24
25#[derive(Debug, Clone)]
28pub struct GatewayInformationResult {
29 pub node_address: crate::WString,
30 pub node_id: NodeId,
31 pub node_instance_id: u64,
32 pub node_name: crate::WString,
33}
34
35impl From<&IFabricGatewayInformationResult> for GatewayInformationResult {
36 fn from(com: &IFabricGatewayInformationResult) -> Self {
37 let info = unsafe { com.get_GatewayInformation().as_ref().unwrap() };
38 Self {
39 node_address: WString::from(info.NodeAddress),
40 node_id: info.NodeId.into(),
41 node_instance_id: info.NodeInstanceId,
42 node_name: WString::from(info.NodeName),
43 }
44 }
45}
46
47#[windows_core::implement(IFabricClientConnectionEventHandler2)]
50pub struct ClientConnectionEventHandlerBridge<T>
51where
52 T: ClientConnectionEventHandler,
53{
54 inner: T,
55}
56
57impl<T> ClientConnectionEventHandlerBridge<T>
58where
59 T: ClientConnectionEventHandler,
60{
61 pub fn new(inner: T) -> Self {
62 Self { inner }
63 }
64 pub fn new_com(inner: T) -> IFabricClientConnectionEventHandler {
65 let h1: IFabricClientConnectionEventHandler2 = Self::new(inner).into();
66 use windows_core::Interface;
67 h1.cast().unwrap()
68 }
69}
70
71impl<T> IFabricClientConnectionEventHandler_Impl for ClientConnectionEventHandlerBridge_Impl<T>
72where
73 T: ClientConnectionEventHandler,
74{
75 fn OnConnected(
76 &self,
77 gw_info: windows_core::Ref<IFabricGatewayInformationResult>,
78 ) -> crate::WinResult<()> {
79 let info = GatewayInformationResult::from(gw_info.unwrap());
80 self.inner
81 .on_connected(&info)
82 .map_err(crate::WinError::from)
83 }
84
85 fn OnDisconnected(
86 &self,
87 gw_info: windows_core::Ref<IFabricGatewayInformationResult>,
88 ) -> crate::WinResult<()> {
89 let info = GatewayInformationResult::from(gw_info.unwrap());
90 self.inner
91 .on_disconnected(&info)
92 .map_err(crate::WinError::from)
93 }
94}
95
96impl<T> IFabricClientConnectionEventHandler2_Impl for ClientConnectionEventHandlerBridge_Impl<T>
97where
98 T: ClientConnectionEventHandler,
99{
100 fn OnClaimsRetrieval(
101 &self,
102 metadata: *const mssf_com::Microsoft::ServiceFabric::FabricTypes::FABRIC_CLAIMS_RETRIEVAL_METADATA,
103 ) -> crate::WinResult<mssf_com::Microsoft::ServiceFabric::FabricCommon::IFabricStringResult>
104 {
105 let meta = unsafe { metadata.as_ref().unwrap() };
106 let claims_meta = ClaimsRetrievalMetadata::from(meta);
107 let result = self
108 .inner
109 .on_claims_retrieval(claims_meta)
110 .map_err(crate::WinError::from)?;
111
112 let string_result = crate::strings::StringResult::new(result);
113 Ok(string_result.into())
114 }
115}
116
117pub trait ConnectionNotificationFn:
120 Fn(&GatewayInformationResult) -> crate::Result<()> + 'static
121{
122}
123impl<T: Fn(&GatewayInformationResult) -> crate::Result<()> + 'static> ConnectionNotificationFn
124 for T
125{
126}
127
128pub trait ClaimsRetrievalFn:
129 Fn(ClaimsRetrievalMetadata) -> crate::Result<WString> + 'static
130{
131}
132impl<T: Fn(ClaimsRetrievalMetadata) -> crate::Result<WString> + 'static> ClaimsRetrievalFn for T {}
133
134pub struct LambdaClientConnectionNotificationHandler {
137 f_conn: Option<Box<dyn ConnectionNotificationFn>>,
138 f_disconn: Option<Box<dyn ConnectionNotificationFn>>,
139 f_claims: Option<Box<dyn ClaimsRetrievalFn>>,
140}
141
142impl LambdaClientConnectionNotificationHandler {
143 pub fn new() -> Self {
144 Self {
145 f_conn: None,
146 f_disconn: None,
147 f_claims: None,
148 }
149 }
150
151 pub fn set_f_conn(&mut self, f: impl ConnectionNotificationFn) {
153 self.f_conn = Some(Box::new(f));
154 }
155
156 pub fn set_f_disconn(&mut self, f: impl ConnectionNotificationFn) {
158 self.f_disconn = Some(Box::new(f));
159 }
160
161 pub fn set_f_claims(&mut self, f: impl ClaimsRetrievalFn) {
163 self.f_claims = Some(Box::new(f));
164 }
165}
166
167impl ClientConnectionEventHandler for LambdaClientConnectionNotificationHandler {
168 fn on_connected(&self, info: &GatewayInformationResult) -> crate::Result<()> {
169 if let Some(f) = &self.f_conn {
170 f(info)
171 } else {
172 Ok(())
173 }
174 }
175
176 fn on_disconnected(&self, info: &GatewayInformationResult) -> crate::Result<()> {
177 if let Some(f) = &self.f_disconn {
178 f(info)
179 } else {
180 Ok(())
181 }
182 }
183
184 fn on_claims_retrieval(&self, metadata: ClaimsRetrievalMetadata) -> crate::Result<WString> {
185 if let Some(f) = &self.f_claims {
186 f(metadata)
187 } else {
188 Err(crate::ErrorCode::E_NOTIMPL.into())
190 }
191 }
192}
193
194#[derive(Debug, Clone, PartialEq)]
196pub struct AadClaimsRetrievalMetadata {
197 pub authority: WString,
198 pub tenant_id: WString,
199 pub cluster_application: WString,
200 pub client_application: WString,
201 pub client_redirect: WString,
202 pub login_endpoint: WString,
204}
205
206#[derive(Debug, Clone, PartialEq)]
208pub enum ClaimsRetrievalMetadata {
209 AAD(AadClaimsRetrievalMetadata),
210 None,
211}
212
213impl From<&FABRIC_CLAIMS_RETRIEVAL_METADATA> for ClaimsRetrievalMetadata {
214 fn from(value: &FABRIC_CLAIMS_RETRIEVAL_METADATA) -> Self {
215 match value.Kind {
216 mssf_com::FabricTypes::FABRIC_CLAIMS_RETRIEVAL_METADATA_KIND_AAD => {
217 let aad_meta = unsafe {
218 (value.Value
219 as *const mssf_com::FabricTypes::FABRIC_AAD_CLAIMS_RETRIEVAL_METADATA)
220 .as_ref()
221 .unwrap()
222 };
223 let ex1 = unsafe {
224 (aad_meta.Reserved
225 as *const mssf_com::FabricTypes::FABRIC_AAD_CLAIMS_RETRIEVAL_METADATA_EX1)
226 .as_ref()
227 };
228
229 ClaimsRetrievalMetadata::AAD(AadClaimsRetrievalMetadata {
230 authority: WString::from(aad_meta.Authority),
231 tenant_id: WString::from(aad_meta.TenantId),
232 cluster_application: WString::from(aad_meta.ClusterApplication),
233 client_application: WString::from(aad_meta.ClientApplication),
234 client_redirect: WString::from(aad_meta.ClientRedirect),
235 login_endpoint: ex1.map_or(WString::new(), |v| WString::from(v.LoginEndpoint)),
236 })
237 }
238 mssf_com::FabricTypes::FABRIC_CLAIMS_RETRIEVAL_METADATA_KIND_NONE => {
239 ClaimsRetrievalMetadata::None
240 }
241 _ => ClaimsRetrievalMetadata::None,
242 }
243 }
244}