diff --git a/src/ethereum/identity.rs b/src/ethereum/identity.rs index 5e5db0d..5db515a 100644 --- a/src/ethereum/identity.rs +++ b/src/ethereum/identity.rs @@ -1,7 +1,10 @@ use std::str::FromStr; use regex::Regex; -use serde::Serialize; +use serde::{ + Deserialize, Deserializer, Serialize, Serializer, + de::Error as DeserializerError, +}; use crate::errors::ValidationError; use super::signatures::recover_address; @@ -11,6 +14,7 @@ use super::utils::address_to_string; pub const ETHEREUM_EIP191_PROOF: &str = "ethereum-eip191-00"; // https://github.com/w3c-ccg/did-pkh/blob/main/did-pkh-method-draft.md +#[derive(Clone, Debug, PartialEq)] pub struct DidPkh { network_id: String, chain_id: String, @@ -62,6 +66,24 @@ impl FromStr for DidPkh { } } +impl Serialize for DidPkh { + fn serialize(&self, serializer: S) -> Result + where S: Serializer + { + let did_str = self.to_string(); + serializer.serialize_str(&did_str) + } +} + +impl<'de> Deserialize<'de> for DidPkh { + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de> + { + let did_str: String = Deserialize::deserialize(deserializer)?; + did_str.parse().map_err(DeserializerError::custom) + } +} + // https://www.w3.org/TR/vc-data-model/#credential-subject #[derive(Serialize)] #[serde(rename_all = "camelCase")] diff --git a/src/models/profiles/types.rs b/src/models/profiles/types.rs index 96b6077..2157b0e 100644 --- a/src/models/profiles/types.rs +++ b/src/models/profiles/types.rs @@ -7,6 +7,7 @@ use crate::activitypub::actor::Actor; use crate::activitypub::views::get_actor_url; use crate::database::json_macro::{json_from_sql, json_to_sql}; use crate::errors::ValidationError; +use crate::ethereum::identity::DidPkh; use super::validators::{ validate_username, validate_display_name, @@ -14,6 +15,26 @@ use super::validators::{ clean_extra_fields, }; +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct IdentityProof { + pub issuer: DidPkh, + pub proof_type: String, + pub value: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct IdentityProofs(pub Vec); + +impl IdentityProofs { + pub fn into_inner(self) -> Vec { + let Self(identity_proofs) = self; + identity_proofs + } +} + +json_from_sql!(IdentityProofs); +json_to_sql!(IdentityProofs); + #[derive(Clone, Debug, Deserialize, Serialize)] pub struct ExtraField { pub name: String, @@ -178,6 +199,15 @@ mod tests { const INSTANCE_HOST: &str = "example.com"; + #[test] + fn test_identity_proof_serialization() { + let json_data = r#"{"issuer":"did:pkh:eip155:1:0xb9c5714089478a327f09197987f16f9e5d936e8a","proof_type":"ethereum-eip191-00","value":"dbfe"}"#; + let proof: IdentityProof = serde_json::from_str(json_data).unwrap(); + assert_eq!(proof.issuer.address, "0xb9c5714089478a327f09197987f16f9e5d936e8a"); + let serialized = serde_json::to_string(&proof).unwrap(); + assert_eq!(serialized, json_data); + } + #[test] fn test_local_actor_address() { let local_profile = DbActorProfile {