use std::convert::TryFrom;
use serde::{Deserialize, Serialize};
use crate::error::{EnigmaNodeTypesError, Result};
use crate::user_id::{normalize_username, UserId};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct PublicIdentity {
pub user_id: UserId,
pub username_hint: Option<String>,
pub signing_public_key: Vec<u8>,
pub encryption_public_key: Vec<u8>,
pub signature: Vec<u8>,
pub created_at_ms: u64,
}
impl PublicIdentity {
pub fn validate(&self) -> Result<()> {
if self.signing_public_key.is_empty() {
return Err(EnigmaNodeTypesError::InvalidField("signing_public_key"));
}
if self.encryption_public_key.is_empty() {
return Err(EnigmaNodeTypesError::InvalidField("encryption_public_key"));
}
if self.signature.is_empty() {
return Err(EnigmaNodeTypesError::InvalidField("signature"));
}
if self.created_at_ms == 0 {
return Err(EnigmaNodeTypesError::InvalidField("created_at_ms"));
}
if let Some(hint) = &self.username_hint {
normalize_username(hint)?;
}
Ok(())
}
}
pub fn signed_payload(
username_hint: &str,
signing_public_key: &[u8],
encryption_public_key: &[u8],
) -> Vec<u8> {
let hint_bytes = username_hint.as_bytes();
let hint_len = match u32::try_from(hint_bytes.len()) {
Ok(v) => v,
Err(_) => u32::MAX,
};
let signing_len = match u32::try_from(signing_public_key.len()) {
Ok(v) => v,
Err(_) => u32::MAX,
};
let encryption_len = match u32::try_from(encryption_public_key.len()) {
Ok(v) => v,
Err(_) => u32::MAX,
};
let mut payload = Vec::with_capacity(
hint_bytes.len()
.saturating_add(signing_public_key.len())
.saturating_add(encryption_public_key.len())
.saturating_add(12),
);
payload.extend_from_slice(&hint_len.to_be_bytes());
payload.extend_from_slice(hint_bytes);
payload.extend_from_slice(&signing_len.to_be_bytes());
payload.extend_from_slice(signing_public_key);
payload.extend_from_slice(&encryption_len.to_be_bytes());
payload.extend_from_slice(encryption_public_key);
payload
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct RegisterRequest {
pub identity: PublicIdentity,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct RegisterResponse {
pub ok: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct ResolveResponse {
pub identity: Option<PublicIdentity>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct CheckUserResponse {
pub exists: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct SyncRequest {
pub identities: Vec<PublicIdentity>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct SyncResponse {
pub merged: usize,
}