Skip to main content

smart_id_rust_client/models/api/
authentication_session.rs

1use crate::config::SmartIDConfig;
2use crate::error::Result;
3use crate::error::SmartIdClientError;
4use crate::models::api::response::SmartIdAPIResponse;
5use crate::models::common::{CertificateLevel, RequestProperties, VCCodeType};
6use crate::models::interaction::{encode_interactions_base_64, Interaction};
7use crate::models::signature::{
8    HashingAlgorithm, SignatureAlgorithm, SignatureProtocol, SignatureProtocolParameters,
9};
10use serde::{Deserialize, Serialize};
11use serde_with::skip_serializing_none;
12// region AuthenticationDeviceLinkSessionRequest
13
14/// Authentication Device Link Request
15///
16/// This struct represents a request for authentication using a device link or qr code with the Smart ID service.
17/// It includes various parameters required for the authentication process.
18///
19/// # Properties
20///
21/// * `relying_party_uuid` - The UUID of the relying party, provided by Smart ID.
22/// * `relying_party_name` - The name of the relying party, provided by Smart ID.
23/// * `certificate_level` - The level of the certificate required for authentication.
24/// * `signature_protocol` - The protocol used for the signature, currently only ACSP_V2 is supported.
25/// * `signature_protocol_parameters` - The parameters for the signature protocol.
26/// * `signature_algorithm_parameters` - The parameters for the signature algorithm.
27/// * `interactions` - A vector of interactions allowed during the authentication session. At least one interaction is required.
28/// * `request_properties` - Optional properties for the request.
29/// * `capabilities` - Used only when agreed with Smart-ID provider. When omitted request capabilities are derived from certificateLevel parameter.
30///
31/// # Example
32///
33/// ```rust
34/// use smart_id_rust_client::error::Result;
35/// use smart_id_rust_client::config::SmartIDConfig;
36/// use smart_id_rust_client::models::api::authentication_session::{AuthenticationCertificateLevel, AuthenticationDeviceLinkRequest};
37/// use smart_id_rust_client::models::interaction::Interaction;
38/// use smart_id_rust_client::models::signature::{HashingAlgorithm, SignatureAlgorithm};
39///
40/// fn create_authentication_request(cfg: &SmartIDConfig) -> Result<AuthenticationDeviceLinkRequest> {
41///     let interactions = vec![Interaction::DisplayTextAndPIN {
42///         display_text_60: "Authenticate to Application: Test".to_string(),
43///     }];
44///     AuthenticationDeviceLinkRequest::new(
45///         cfg,
46///         interactions,
47///         SignatureAlgorithm::RsassaPss,
48///         AuthenticationCertificateLevel::QUALIFIED,
49///        Some("https://example.com/callback".to_string()),
50///        HashingAlgorithm::sha_256
51///     )
52/// }
53/// ```
54#[skip_serializing_none]
55#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
56#[serde(rename_all = "camelCase")]
57pub struct AuthenticationDeviceLinkRequest {
58    #[serde(rename = "relyingPartyUUID")]
59    pub relying_party_uuid: String,
60    pub relying_party_name: String,
61    pub initial_callback_url: Option<String>,
62    pub certificate_level: AuthenticationCertificateLevel,
63    pub signature_protocol: SignatureProtocol,
64    pub signature_protocol_parameters: SignatureProtocolParameters,
65    pub interactions: String,
66    pub request_properties: Option<RequestProperties>,
67    pub capabilities: Option<Vec<String>>,
68}
69
70/// Creates a new `AuthenticationDeviceLinkRequest`.
71///
72/// # Arguments
73///
74/// * `cfg` - The configuration for the Smart-ID service.
75/// * `interactions` - A vector of interactions allowed during the authentication session. At least one interaction is required.
76/// * `signature_algorithm` - The algorithm used for the signature.
77/// * `authentication_certificate_level` - The level of the certificate required for authentication.
78/// * `initial_callback_url` - The initial callback URL for the authentication request, provided by Smart ID.
79/// * `hash_algorithm` - The hashing algorithm used for the signature request.
80///
81/// # Errors
82///
83/// Returns an error if no interactions are defined or if any interaction has invalid text length.
84///
85/// # Example
86///
87/// ```rust
88/// use smart_id_rust_client::error::Result;
89/// use smart_id_rust_client::config::SmartIDConfig;
90/// use smart_id_rust_client::models::api::authentication_session::{AuthenticationDeviceLinkRequest, AuthenticationCertificateLevel};
91/// use smart_id_rust_client::models::interaction::Interaction;
92/// use smart_id_rust_client::models::signature::{HashingAlgorithm, SignatureAlgorithm};
93///
94/// fn create_authentication_request(cfg: &SmartIDConfig) -> Result<AuthenticationDeviceLinkRequest> {
95///     let interactions = vec![Interaction::DisplayTextAndPIN {
96///         display_text_60: "Authenticate to Application: Test".to_string(),
97///     }];
98///     AuthenticationDeviceLinkRequest::new(
99///         cfg,
100///         interactions,
101///         SignatureAlgorithm::RsassaPss,
102///         AuthenticationCertificateLevel::QUALIFIED,
103///         Some("https://example.com/callback".to_string()),
104///         HashingAlgorithm::sha_256
105///     )
106/// }
107/// ```
108impl AuthenticationDeviceLinkRequest {
109    pub fn new(
110        cfg: &SmartIDConfig,
111        interactions: Vec<Interaction>,
112        signature_algorithm: SignatureAlgorithm,
113        authentication_certificate_level: AuthenticationCertificateLevel,
114        initial_callback_url: Option<String>,
115        hash_algorithm: HashingAlgorithm,
116    ) -> Result<Self> {
117        // At least one interaction is needed for every authentication request
118        if interactions.is_empty() {
119            return Err(SmartIdClientError::ConfigMissingException(
120                "Define at least 1 interaction for an authentication request",
121            ));
122        };
123
124        for interaction in &interactions {
125            interaction.validate_text_length()?;
126        }
127
128        let encoded_interactions = encode_interactions_base_64(&interactions)?;
129
130        Ok(AuthenticationDeviceLinkRequest {
131            relying_party_uuid: cfg.relying_party_uuid.clone(),
132            relying_party_name: cfg.relying_party_name.clone(),
133            initial_callback_url,
134            certificate_level: authentication_certificate_level,
135
136            signature_protocol: SignatureProtocol::ACSP_V2,
137            signature_protocol_parameters: SignatureProtocolParameters::new_acsp_v2(
138                signature_algorithm,
139                hash_algorithm,
140            ),
141            interactions: encoded_interactions,
142            request_properties: None,
143            capabilities: None,
144        })
145    }
146}
147
148pub(crate) type AuthenticationDeviceLinkResponse =
149    SmartIdAPIResponse<AuthenticationDeviceLinkSession>;
150
151#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
152#[serde(rename_all = "camelCase")]
153pub struct AuthenticationDeviceLinkSession {
154    #[serde(rename = "sessionID")]
155    pub session_id: String,
156    pub session_secret: String,
157    pub session_token: String,
158    pub device_link_base: String,
159}
160
161// endregion AuthenticationDeviceLinkSessionRequest
162
163// region AuthenticationNotificationRequest
164
165/// Authentication Notification Request
166///
167/// This struct represents a request for authentication using a push notification with the Smart ID service.
168/// It includes various parameters required for the authentication process.
169///
170/// # Properties
171///
172/// * `relying_party_uuid` - The UUID of the relying party, provided by Smart ID.
173/// * `relying_party_name` - The name of the relying party, provided by Smart ID.
174/// * `initial_callback_url` - The initial callback URL for the authentication request, provided by Smart ID.
175/// * `certificate_level` - The level of the certificate required for authentication.
176/// * `signature_protocol` - The protocol used for the signature, currently only ACSP_V2 is supported.
177/// * `signature_protocol_parameters` - The parameters for the signature protocol.
178/// * `signature_algorithm_parameters` - The parameters for the signature algorithm.
179/// * `interactions` - A vector of interactions allowed during the authentication session. At least one interaction is required.
180/// * `request_properties` - Optional properties for the request.
181/// * `capabilities` - Used only when agreed with Smart-ID provider. When omitted request capabilities are derived from certificateLevel parameter.
182/// * `vc_type` - The type of the verification code used in the authentication request. Always numeric right now.
183///
184/// # Example
185///
186/// ```rust
187/// use smart_id_rust_client::error::Result;
188/// use smart_id_rust_client::config::SmartIDConfig;
189/// use smart_id_rust_client::models::api::authentication_session::{AuthenticationCertificateLevel, AuthenticationNotificationRequest};
190/// use smart_id_rust_client::models::interaction::Interaction;
191/// use smart_id_rust_client::models::signature::{HashingAlgorithm, SignatureAlgorithm};
192///
193/// fn create_authentication_request(cfg: &SmartIDConfig) -> Result<AuthenticationNotificationRequest> {
194///     let interactions = vec![Interaction::DisplayTextAndPIN {
195///         display_text_60: "Authenticate to Application: Test".to_string(),
196///     }];
197///     AuthenticationNotificationRequest::new(
198///         cfg,
199///         interactions,
200///         SignatureAlgorithm::RsassaPss,
201///         AuthenticationCertificateLevel::QUALIFIED,
202///         HashingAlgorithm::sha_256,
203///     )
204/// }
205/// ```
206#[skip_serializing_none]
207#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
208#[serde(rename_all = "camelCase")]
209pub struct AuthenticationNotificationRequest {
210    #[serde(rename = "relyingPartyUUID")]
211    pub relying_party_uuid: String,
212    pub relying_party_name: String,
213    pub certificate_level: AuthenticationCertificateLevel,
214    pub signature_protocol: SignatureProtocol,
215    pub signature_protocol_parameters: SignatureProtocolParameters,
216    pub interactions: String,
217    pub request_properties: Option<RequestProperties>,
218    pub capabilities: Option<Vec<String>>,
219    pub vc_type: VCCodeType,
220}
221
222/// Creates a new `AuthenticationNotificationRequest`.
223///
224/// # Arguments
225///
226/// * `cfg` - The configuration for the Smart-ID service.
227/// * `interactions` - A vector of interactions allowed during the authentication session. At least one interaction is required.
228/// * `signature_algorithm` - The algorithm used for the signature.
229/// * `authentication_certificate_level` - The level of the certificate required for authentication.
230/// * `initial_callback_url` - The initial callback URL for the authentication request, provided by Smart ID.
231/// * `hash_algorithm` - The hashing algorithm used for the signature request.
232///
233/// # Errors
234///
235/// Returns an error if no interactions are defined or if any interaction has invalid text length.
236///
237/// # Example
238///
239/// ```rust
240/// use smart_id_rust_client::error::Result;
241/// use smart_id_rust_client::config::SmartIDConfig;
242/// use smart_id_rust_client::models::api::authentication_session::{AuthenticationNotificationRequest, AuthenticationCertificateLevel};
243/// use smart_id_rust_client::models::interaction::Interaction;
244/// use smart_id_rust_client::models::signature::{HashingAlgorithm, SignatureAlgorithm};
245///
246/// fn create_authentication_request(cfg: &SmartIDConfig) -> Result<AuthenticationNotificationRequest> {
247///     let interactions = vec![Interaction::DisplayTextAndPIN {
248///         display_text_60: "Authenticate to Application: Test".to_string(),
249///     }];
250///     AuthenticationNotificationRequest::new(
251///         cfg,
252///         interactions,
253///         SignatureAlgorithm::RsassaPss,
254///         AuthenticationCertificateLevel::QUALIFIED,
255///         HashingAlgorithm::sha_256,
256///     )
257/// }
258/// ```
259impl AuthenticationNotificationRequest {
260    pub fn new(
261        cfg: &SmartIDConfig,
262        interactions: Vec<Interaction>,
263        signature_algorithm: SignatureAlgorithm,
264        authentication_certificate_level: AuthenticationCertificateLevel,
265        hash_algorithm: HashingAlgorithm,
266    ) -> Result<Self> {
267        // At least one interaction is needed for every authentication request
268        if interactions.is_empty() {
269            return Err(SmartIdClientError::ConfigMissingException(
270                "Define at least 1 interaction for an authentication request",
271            ));
272        };
273
274        for interaction in &interactions {
275            interaction.validate_text_length()?;
276        }
277
278        let encoded_interactions = encode_interactions_base_64(&interactions)?;
279
280        Ok(AuthenticationNotificationRequest {
281            relying_party_uuid: cfg.relying_party_uuid.clone(),
282            relying_party_name: cfg.relying_party_name.clone(),
283            certificate_level: authentication_certificate_level,
284            signature_protocol: SignatureProtocol::ACSP_V2,
285            signature_protocol_parameters: SignatureProtocolParameters::new_acsp_v2(
286                signature_algorithm,
287                hash_algorithm,
288            ),
289            interactions: encoded_interactions,
290            request_properties: None,
291            capabilities: None,
292            vc_type: VCCodeType::numeric4,
293        })
294    }
295}
296
297pub(crate) type AuthenticationNotificationResponse =
298    SmartIdAPIResponse<AuthenticationNotificationSession>;
299
300#[derive(Clone, Debug, Serialize, Deserialize)]
301pub struct AuthenticationNotificationSession {
302    #[serde(rename = "sessionID")]
303    pub session_id: String,
304}
305
306// endregion AuthenticationNotificationRequest
307
308// region enums
309
310#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
311#[allow(non_camel_case_types)]
312#[non_exhaustive]
313pub enum AuthenticationCertificateLevel {
314    QUALIFIED,
315    ADVANCED,
316}
317
318impl From<AuthenticationCertificateLevel> for CertificateLevel {
319    fn from(val: AuthenticationCertificateLevel) -> Self {
320        match val {
321            AuthenticationCertificateLevel::QUALIFIED => CertificateLevel::QUALIFIED,
322            AuthenticationCertificateLevel::ADVANCED => CertificateLevel::ADVANCED,
323        }
324    }
325}
326
327// endregion enums