Skip to main content

lenso_capability_auth/
generated.rs

1// @generated by lenso-contract-codegen; do not edit.
2use std::{fmt, rc::Rc};
3use futures::future::LocalBoxFuture;
4use lenso_kernel::{InvocationContext, NativeRequestEndpoint, NativeRequestFuture, NativeRequestHandle, PluginDependencies, RequestCapability, RuntimeFailure};
5
6use lenso_plugin_authoring::{BoundCapabilityClient, CapabilityClient, CapabilityClientMany};
7pub const CAPABILITY_ID: &str = "lenso.auth@1";
8pub const DESCRIPTOR_VERSION: &str = "1.0.0";
9pub const PORTABLE: bool = true;
10pub const CROSS_LANE_TRANSFER: bool = false;
11pub const AUTH_CAPABILITY_ID: &str = CAPABILITY_ID;
12pub const AUTH_DESCRIPTOR_VERSION: &str = DESCRIPTOR_VERSION;
13
14#[doc(hidden)]
15#[macro_export]
16macro_rules! __lenso_provided_auth { () => { "{\"capability_id\":\"lenso.auth@1\",\"descriptor_version\":\"1.0.0\",\"operations\":[\"authenticate\"],\"operation_kinds\":{},\"default_admission\":{\"queue_capacity\":0,\"max_concurrency\":1},\"operation_admissions\":{},\"event_admission\":null,\"cross_lane_transfer\":false}" }; }
17
18#[doc(hidden)]
19#[macro_export]
20macro_rules! __lenso_required_auth_client { () => { "{\"capability_id\":\"lenso.auth@1\",\"descriptor_version\":\"1.0.0\",\"cardinality\":\"one\"}" }; }
21
22#[doc(hidden)]
23#[macro_export]
24macro_rules! __lenso_required_many_auth_client { () => { "{\"capability_id\":\"lenso.auth@1\",\"descriptor_version\":\"1.0.0\",\"cardinality\":\"many\"}" }; }
25
26pub const AUTHENTICATE_OPERATION: &str = "authenticate";
27
28pub use lenso_contract_runtime::{Timestamp, UnknownDomainError};
29use lenso_contract_runtime::{decode_portable_json, encode_portable_json};
30
31#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
32pub struct AuthenticateRequest {
33    #[serde(rename = "credential")]
34    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
35    pub credential: Option<AuthenticateRequestCredential>,
36}
37
38#[derive(Clone, PartialEq, serde::Serialize, serde::Deserialize)]
39pub struct AuthenticateRequestCredential {
40    #[serde(rename = "scheme")]
41    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
42    pub scheme: String,
43    #[serde(rename = "value")]
44    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
45    pub value: String,
46}
47
48impl fmt::Debug for AuthenticateRequestCredential {
49    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
50        formatter
51            .debug_struct("AuthenticateRequestCredential")
52            .field("scheme", &self.scheme)
53            .field("value", &"<redacted>")
54            .finish()
55    }
56}
57
58#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
59pub struct AuthenticateResponse {
60    #[serde(rename = "assertion")]
61    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
62    pub assertion: Option<AuthenticateResponseAssertion>,
63    #[serde(rename = "kind")]
64    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
65    pub kind: AuthenticateResponseKind,
66}
67
68#[derive(Clone, PartialEq, serde::Serialize, serde::Deserialize)]
69pub struct AuthenticateResponseAssertion {
70    #[serde(rename = "actor_kind")]
71    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
72    pub actor_kind: String,
73    #[serde(rename = "assurance")]
74    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
75    pub assurance: String,
76    #[serde(rename = "audience")]
77    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
78    pub audience: Vec<String>,
79    #[serde(rename = "claims")]
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub claims: Option<std::collections::BTreeMap<String, serde_json::Value>>,
82    #[serde(rename = "expires_at")]
83    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
84    pub expires_at: Timestamp,
85    #[serde(rename = "issued_at")]
86    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
87    pub issued_at: Timestamp,
88    #[serde(rename = "issuer")]
89    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
90    pub issuer: String,
91    #[serde(rename = "parent_provenance")]
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub parent_provenance: Option<String>,
94    #[serde(rename = "proof")]
95    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
96    pub proof: String,
97    #[serde(rename = "subject")]
98    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
99    pub subject: String,
100}
101
102impl fmt::Debug for AuthenticateResponseAssertion {
103    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
104        formatter
105            .debug_struct("AuthenticateResponseAssertion")
106            .field("actor_kind", &self.actor_kind)
107            .field("assurance", &self.assurance)
108            .field("audience", &self.audience)
109            .field("claims", &self.claims)
110            .field("expires_at", &self.expires_at)
111            .field("issued_at", &self.issued_at)
112            .field("issuer", &self.issuer)
113            .field("parent_provenance", &self.parent_provenance)
114            .field("proof", &"<redacted>")
115            .field("subject", &self.subject)
116            .finish()
117    }
118}
119
120#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
121pub enum AuthenticateResponseKind {
122    #[serde(rename = "absent")]
123    Absent,
124    #[serde(rename = "authenticated")]
125    Authenticated,
126}
127
128#[derive(Clone, Debug, PartialEq)]
129pub enum AuthenticateError {
130    Expired,
131    Invalid,
132    Revoked,
133    Unsupported,
134    Unknown(UnknownDomainError),
135}
136
137#[derive(Debug)]
138pub struct Auth;
139impl RequestCapability for Auth {
140    type Request = AuthenticateRequest;
141    type Response = AuthenticateResponse;
142    type DomainError = AuthenticateError;
143    const ID: &'static str = CAPABILITY_ID;
144    const DESCRIPTOR_VERSION: &'static str = DESCRIPTOR_VERSION;
145
146    fn invoke_native(endpoint: &dyn NativeRequestEndpoint, operation: &str, request: Self::Request, context: InvocationContext) -> NativeRequestFuture<Self> {
147        if operation != AUTHENTICATE_OPERATION {
148            return lenso_kernel::invoke_typed_or_erased_native_request::<Self>(endpoint, operation, request, context);
149        }
150        let Some(typed_endpoint) = endpoint
151            .typed_endpoint()
152            .and_then(|endpoint| endpoint.downcast_ref::<AuthRequestEndpoint>())
153        else {
154            return lenso_kernel::invoke_typed_or_erased_native_request::<Self>(endpoint, operation, request, context);
155        };
156        Rc::clone(&typed_endpoint.provider).authenticate(context, request)
157    }
158}
159
160impl serde::Serialize for AuthenticateError {
161    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
162    where
163        S: serde::Serializer,
164    {
165        use serde::ser::SerializeMap;
166        match self {
167            Self::Expired => serializer.serialize_str("expired"),
168            Self::Invalid => serializer.serialize_str("invalid"),
169            Self::Revoked => serializer.serialize_str("revoked"),
170            Self::Unsupported => serializer.serialize_str("unsupported"),
171            Self::Unknown(value) => {
172                let mut map = serializer.serialize_map(Some(1 + usize::from(value.payload.is_some()) + value.extra.len()))?;
173                map.serialize_entry("code", &value.code)?;
174                if let Some(payload) = &value.payload {
175                    map.serialize_entry("payload", payload)?;
176                }
177                for (key, extra) in &value.extra {
178                    map.serialize_entry(key, extra)?;
179                }
180                map.end()
181            },
182        }
183    }
184}
185
186impl<'de> serde::Deserialize<'de> for AuthenticateError {
187    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
188    where
189        D: serde::Deserializer<'de>,
190    {
191        let value = <serde_json::Value as serde::Deserialize>::deserialize(deserializer)?;
192        match value {
193            serde_json::Value::String(code) => match code.as_str() {
194                "expired" => Ok(Self::Expired),
195                "invalid" => Ok(Self::Invalid),
196                "revoked" => Ok(Self::Revoked),
197                "unsupported" => Ok(Self::Unsupported),
198                _ => Ok(Self::Unknown(UnknownDomainError { code, payload: None, extra: std::collections::BTreeMap::new() })),
199            },
200            serde_json::Value::Object(mut object) => {
201                let Some(code) = object.remove("code").and_then(|value| value.as_str().map(ToOwned::to_owned)) else {
202                    return Err(serde::de::Error::custom("Domain Error object is missing a string code"));
203                };
204                let payload = object.remove("payload");
205                let extra = object.into_iter().collect::<std::collections::BTreeMap<_, _>>();
206                Ok(Self::Unknown(UnknownDomainError { code, payload, extra }))
207            }
208            other => Err(serde::de::Error::custom(format!("Domain Error must be a string or object, got {other}"))),
209        }
210    }
211}
212
213pub fn encode_authenticate_request(value: &AuthenticateRequest) -> Result<String, serde_json::Error> { encode_portable_json(value) }
214pub fn decode_authenticate_request(wire: &str) -> Result<AuthenticateRequest, serde_json::Error> { decode_portable_json(wire) }
215pub fn encode_authenticate_response(value: &AuthenticateResponse) -> Result<String, serde_json::Error> { encode_portable_json(value) }
216pub fn decode_authenticate_response(wire: &str) -> Result<AuthenticateResponse, serde_json::Error> { decode_portable_json(wire) }
217pub fn encode_authenticate_error(value: &AuthenticateError) -> Result<String, serde_json::Error> { encode_portable_json(value) }
218pub fn decode_authenticate_error(wire: &str) -> Result<AuthenticateError, serde_json::Error> { decode_portable_json(wire) }
219
220#[doc(hidden)]
221pub trait __LensoIntoAuthAuthenticateResult {
222    fn __lenso_into_result(self) -> Result<Result<AuthenticateResponse, AuthenticateError>, RuntimeFailure>;
223}
224impl __LensoIntoAuthAuthenticateResult for Result<AuthenticateResponse, AuthenticateError> {
225    fn __lenso_into_result(self) -> Result<Result<AuthenticateResponse, AuthenticateError>, RuntimeFailure> { Ok(self) }
226}
227impl __LensoIntoAuthAuthenticateResult for Result<Result<AuthenticateResponse, AuthenticateError>, RuntimeFailure> {
228    fn __lenso_into_result(self) -> Result<Result<AuthenticateResponse, AuthenticateError>, RuntimeFailure> { self }
229}
230impl __LensoIntoAuthAuthenticateResult for Result<AuthenticateResponse, lenso_plugin_authoring::PluginError<AuthenticateError, RuntimeFailure>> {
231    fn __lenso_into_result(self) -> Result<Result<AuthenticateResponse, AuthenticateError>, RuntimeFailure> {
232        match self {
233            Ok(value) => Ok(Ok(value)),
234            Err(lenso_plugin_authoring::PluginError::Domain(error)) => Ok(Err(error)),
235            Err(lenso_plugin_authoring::PluginError::Runtime(error)) => Err(error),
236        }
237    }
238}
239impl __LensoIntoAuthAuthenticateResult for Result<AuthenticateResponse, AuthInvocationError> {
240    fn __lenso_into_result(self) -> Result<Result<AuthenticateResponse, AuthenticateError>, RuntimeFailure> {
241        match self {
242            Ok(value) => Ok(Ok(value)),
243            Err(AuthInvocationError::Domain(error)) => Ok(Err(error)),
244            Err(AuthInvocationError::Runtime(error)) => Err(error),
245        }
246    }
247}
248
249pub trait AuthProvider: fmt::Debug + 'static {
250    fn authenticate(&self, context: InvocationContext, request: AuthenticateRequest) -> NativeRequestFuture<Auth>;
251}
252
253#[doc(hidden)]
254#[macro_export]
255macro_rules! __lenso_native_lower_auth {
256    ($plugin:ty, $support:path) => {
257        use $support as __LensoNativeSupportAuth;
258        impl $crate::AuthProvider for $plugin {
259        fn authenticate(&self, context: __LensoNativeSupportAuth::InvocationContext, request: $crate::AuthenticateRequest) -> __LensoNativeSupportAuth::NativeRequestFuture<$crate::Auth> {
260            let plugin = self.clone();
261            ::std::boxed::Box::pin(async move {
262                let result = <$plugin>::authenticate(&plugin, context, request).await;
263                $crate::__LensoIntoAuthAuthenticateResult::__lenso_into_result(result)
264            })
265        }
266        }
267    };
268}
269
270#[derive(Debug)]
271struct AuthRequestEndpoint { provider: Rc<dyn AuthProvider> }
272
273#[derive(Debug)]
274pub struct AuthEndpoint<P: AuthProvider> { provider: Rc<P>, request_endpoint: AuthRequestEndpoint }
275impl<P: AuthProvider> AuthEndpoint<P> {
276    pub fn new(provider: P) -> Self {
277        let provider = Rc::new(provider);
278        let request_provider: Rc<dyn AuthProvider> = provider.clone();
279        Self { provider, request_endpoint: AuthRequestEndpoint { provider: request_provider } }
280    }
281}
282
283impl<P: AuthProvider> NativeRequestEndpoint for AuthEndpoint<P> {
284    fn capability_id(&self) -> &'static str { CAPABILITY_ID }
285    fn descriptor_version(&self) -> &'static str { DESCRIPTOR_VERSION }
286    fn operations(&self) -> &'static [&'static str] { &[
287        AUTHENTICATE_OPERATION,
288    ] }
289    fn typed_endpoint(&self) -> Option<&dyn std::any::Any> { Some(&self.request_endpoint) }
290    fn invoke(&self, operation: &str, request: Box<dyn std::any::Any>, context: InvocationContext) -> LocalBoxFuture<'static, Result<Result<Box<dyn std::any::Any>, Box<dyn std::any::Any>>, RuntimeFailure>> {
291        match operation {
292            AUTHENTICATE_OPERATION => {
293                let Ok(request) = request.downcast::<AuthenticateRequest>() else {
294                    return Box::pin(futures::future::ready(Err(RuntimeFailure::ProtocolViolation { capability: CAPABILITY_ID })));
295                };
296                let invocation = Rc::clone(&self.provider).authenticate(context, *request);
297                Box::pin(async move {
298                    invocation.await.map(|result| {
299                        result
300                            .map(|value| Box::new(value) as Box<dyn std::any::Any>)
301                            .map_err(|error| Box::new(error) as Box<dyn std::any::Any>)
302                    })
303                })
304            }
305            _ => Box::pin(futures::future::ready(Err(RuntimeFailure::UnknownOperation { capability: CAPABILITY_ID, operation: operation.to_owned() }))),
306        }
307    }
308}
309
310#[doc(hidden)]
311#[macro_export]
312macro_rules! __lenso_native_endpoints_auth {
313    ($provider:expr, $support:path) => {{
314        use $support as __LensoNativeSupport;
315        let endpoint = ::std::rc::Rc::new($crate::AuthEndpoint::new($provider));
316        (
317            vec![endpoint.clone() as ::std::rc::Rc<dyn __LensoNativeSupport::NativeRequestEndpoint>],
318            vec![],
319            vec![],
320        )
321    }};
322}
323
324#[doc(hidden)]
325#[macro_export]
326macro_rules! __lenso_native_provide_auth {
327    ($provider:expr, $lifecycle:expr, $support:path) => {{
328        use $support as __LensoNativeSupport;
329        let (request_endpoints, stream_endpoints, event_endpoints) =
330            $crate::__lenso_native_endpoints_auth!($provider, $support);
331        __LensoNativeSupport::NativePluginInstance::with_all_endpoints(
332            request_endpoints,
333            stream_endpoints,
334            event_endpoints,
335            $lifecycle,
336        )
337    }};
338}
339
340#[derive(Debug)]
341pub struct AuthClient {
342    authenticate: NativeRequestHandle<Auth>,
343}
344impl AuthClient {
345    pub fn new(handle: NativeRequestHandle<Auth>) -> Self {
346        Self { authenticate: handle }
347    }
348
349    pub fn from_dependencies(dependencies: &PluginDependencies) -> Result<Self, RuntimeFailure> {
350        <Self as CapabilityClient>::from_dependencies(dependencies)
351    }
352
353    pub async fn authenticate(&self, request: AuthenticateRequest) -> Result<AuthenticateResponse, AuthInvocationError> {
354        self.authenticate.invoke(AUTHENTICATE_OPERATION, request).await
355            .map_err(AuthInvocationError::Runtime)?
356            .map_err(AuthInvocationError::Domain)
357    }
358
359    pub async fn authenticate_with_context(&self, context: InvocationContext, request: AuthenticateRequest) -> Result<AuthenticateResponse, AuthInvocationError> {
360        self.authenticate.invoke_with_context(AUTHENTICATE_OPERATION, context, request).await
361            .map_err(AuthInvocationError::Runtime)?
362            .map_err(AuthInvocationError::Domain)
363    }
364}
365
366impl CapabilityClient for AuthClient {
367    type Dependencies = PluginDependencies;
368    type Error = RuntimeFailure;
369
370    const CAPABILITY_ID: &'static str = CAPABILITY_ID;
371    const DESCRIPTOR_VERSION: &'static str = DESCRIPTOR_VERSION;
372
373    fn from_dependencies(dependencies: &PluginDependencies) -> Result<Self, RuntimeFailure> {
374        Ok(Self {
375            authenticate: dependencies.one::<Auth>()?,
376        })
377    }
378
379    fn already_connected() -> RuntimeFailure {
380        RuntimeFailure::PluginFailure {
381            detail: format!("Capability Port {CAPABILITY_ID} was connected more than once"),
382        }
383    }
384}
385
386impl CapabilityClientMany for AuthClient {
387    fn many_from_dependencies(
388        dependencies: &PluginDependencies,
389    ) -> Result<Vec<BoundCapabilityClient<Self>>, RuntimeFailure> {
390        dependencies
391            .bindings()
392            .iter()
393            .filter(|binding| binding.capability_id() == CAPABILITY_ID)
394            .map(|binding| {
395                Ok(BoundCapabilityClient::new(
396                    binding.provider_instance(),
397                    Self {
398                    authenticate: binding.handle().ok_or(RuntimeFailure::Unavailable { capability: CAPABILITY_ID })?.typed::<Auth>()?,
399                    },
400                ))
401            })
402            .collect()
403    }
404}
405
406#[derive(Clone, Debug, PartialEq)]
407pub enum AuthInvocationError {
408    Domain(AuthenticateError),
409    Runtime(RuntimeFailure),
410}