use crate::config::SmartIDConfig;
use crate::error::Result;
use crate::error::SmartIdClientError;
use crate::models::api::response::SmartIdAPIResponse;
use crate::models::common::{CertificateLevel, RequestProperties, VCCode};
use crate::models::interaction::{encode_interactions_base_64, hash_encode_digest, Interaction};
use crate::models::signature::{
HashingAlgorithm, SignatureAlgorithm, SignatureProtocol, SignatureProtocolParameters,
SignatureRequestAlgorithmParameters,
};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
#[skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SignatureDeviceLinkRequest {
#[serde(rename = "relyingPartyUUID")]
pub relying_party_uuid: String,
pub relying_party_name: String,
pub initial_callback_url: Option<String>,
pub certificate_level: CertificateLevel,
pub signature_protocol: SignatureProtocol,
pub signature_protocol_parameters: SignatureProtocolParameters,
pub nonce: Option<String>,
pub interactions: String,
pub request_properties: Option<RequestProperties>,
pub capabilities: Option<Vec<String>>,
}
impl SignatureDeviceLinkRequest {
pub fn new(
cfg: &SmartIDConfig,
interactions: Vec<Interaction>,
digest: String,
signature_algorithm: SignatureAlgorithm,
hash_algorithm: HashingAlgorithm,
initial_callback_url: Option<String>,
) -> Result<Self> {
if interactions.is_empty() {
return Err(SmartIdClientError::ConfigMissingException(
"Define at least 1 interaction for an authentication request",
));
};
for interaction in &interactions {
interaction.validate_text_length()?;
}
let encoded_interactions = encode_interactions_base_64(&interactions)?;
let hashed_and_encoded_digest = hash_encode_digest(&digest, &hash_algorithm)?;
Ok(SignatureDeviceLinkRequest {
relying_party_uuid: cfg.relying_party_uuid.clone(),
relying_party_name: cfg.relying_party_name.clone(),
initial_callback_url,
certificate_level: CertificateLevel::QUALIFIED,
signature_protocol: SignatureProtocol::RAW_DIGEST_SIGNATURE,
signature_protocol_parameters: SignatureProtocolParameters::RAW_DIGEST_SIGNATURE {
digest: hashed_and_encoded_digest,
signature_algorithm,
signature_algorithm_parameters: SignatureRequestAlgorithmParameters {
hash_algorithm,
},
},
nonce: None,
interactions: encoded_interactions,
request_properties: None,
capabilities: None,
})
}
}
pub(crate) type SignatureDeviceLinkResponse = SmartIdAPIResponse<SignatureDeviceLinkSession>;
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SignatureDeviceLinkSession {
#[serde(rename = "sessionID")]
pub session_id: String,
pub session_secret: String,
pub session_token: String,
pub device_link_base: String,
}
#[skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SignatureNotificationRequest {
#[serde(rename = "relyingPartyUUID")]
pub relying_party_uuid: String,
pub relying_party_name: String,
pub certificate_level: CertificateLevel,
pub signature_protocol: SignatureProtocol,
pub signature_protocol_parameters: SignatureProtocolParameters,
pub nonce: Option<String>,
pub interactions: String,
pub request_properties: Option<RequestProperties>,
pub capabilities: Option<Vec<String>>,
}
impl SignatureNotificationRequest {
pub fn new(
cfg: &SmartIDConfig,
interactions: Vec<Interaction>,
digest: String,
signature_algorithm: SignatureAlgorithm,
hash_algorithm: HashingAlgorithm,
) -> Result<Self> {
if interactions.is_empty() {
return Err(SmartIdClientError::ConfigMissingException(
"Define at least 1 interaction for an authentication request",
));
};
for interaction in &interactions {
interaction.validate_text_length()?;
}
let encoded_interactions = encode_interactions_base_64(&interactions)?;
let hashed_and_encoded_digest = hash_encode_digest(&digest, &hash_algorithm)?;
Ok(SignatureNotificationRequest {
relying_party_uuid: cfg.relying_party_uuid.clone(),
relying_party_name: cfg.relying_party_name.clone(),
certificate_level: CertificateLevel::QUALIFIED,
signature_protocol: SignatureProtocol::RAW_DIGEST_SIGNATURE,
signature_protocol_parameters: SignatureProtocolParameters::RAW_DIGEST_SIGNATURE {
digest: hashed_and_encoded_digest,
signature_algorithm,
signature_algorithm_parameters: SignatureRequestAlgorithmParameters {
hash_algorithm,
},
},
nonce: None,
interactions: encoded_interactions,
request_properties: None,
capabilities: None,
})
}
}
pub(crate) type SignatureNotificationResponse = SmartIdAPIResponse<SignatureNotificationSession>;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SignatureNotificationSession {
#[serde(rename = "sessionID")]
pub session_id: String,
pub vc: VCCode,
}
#[skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SignatureNotificationLinkedRequest {
#[serde(rename = "relyingPartyUUID")]
pub relying_party_uuid: String,
pub relying_party_name: String,
pub certificate_level: CertificateLevel,
pub signature_protocol: SignatureProtocol,
pub signature_protocol_parameters: SignatureProtocolParameters,
#[serde(rename = "linkedSessionID")]
pub linked_session_id: String, pub nonce: Option<String>,
pub interactions: String, pub request_properties: Option<RequestProperties>,
pub capabilities: Option<Vec<String>>,
}
impl SignatureNotificationLinkedRequest {
pub fn new(
cfg: &SmartIDConfig,
interactions: Vec<Interaction>,
digest: String,
signature_algorithm: SignatureAlgorithm,
linked_session_id: String,
hash_algorithm: HashingAlgorithm,
) -> Result<Self> {
if interactions.is_empty() {
return Err(SmartIdClientError::ConfigMissingException(
"Define at least 1 interaction for an authentication request",
));
};
for interaction in &interactions {
interaction.validate_text_length()?;
}
let encoded_interactions = encode_interactions_base_64(&interactions)?;
let hashed_and_encoded_digest = hash_encode_digest(&digest, &hash_algorithm)?;
Ok(SignatureNotificationLinkedRequest {
relying_party_uuid: cfg.relying_party_uuid.clone(),
relying_party_name: cfg.relying_party_name.clone(),
linked_session_id,
certificate_level: CertificateLevel::QUALIFIED,
signature_protocol: SignatureProtocol::RAW_DIGEST_SIGNATURE,
signature_protocol_parameters: SignatureProtocolParameters::RAW_DIGEST_SIGNATURE {
digest: hashed_and_encoded_digest,
signature_algorithm,
signature_algorithm_parameters: SignatureRequestAlgorithmParameters {
hash_algorithm,
},
},
nonce: None,
interactions: encoded_interactions,
request_properties: None,
capabilities: None,
})
}
}
pub(crate) type SignatureNotificationLinkedResponse =
SmartIdAPIResponse<SignatureNotificationLinkedSession>;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SignatureNotificationLinkedSession {
#[serde(rename = "sessionID")]
pub session_id: String,
}