Use numbers to represent identity proof type in database

This commit is contained in:
silverpill 2023-03-13 19:31:31 +00:00
parent 8400241ab4
commit d4f701332f
5 changed files with 64 additions and 45 deletions

View file

@ -0,0 +1,18 @@
UPDATE actor_profile
SET identity_proofs = replaced.identity_proofs
FROM (
SELECT
actor_profile.id,
jsonb_agg(
CASE
WHEN identity_proof ->> 'proof_type' = 'ethereum-eip191-00'
THEN jsonb_set(identity_proof, '{proof_type}', '1')
WHEN identity_proof ->> 'proof_type' = 'MitraMinisignSignature2022A'
THEN jsonb_set(identity_proof, '{proof_type}', '2')
END
) AS identity_proofs
FROM actor_profile
CROSS JOIN jsonb_array_elements(actor_profile.identity_proofs) AS identity_proof
GROUP BY actor_profile.id
) AS replaced
WHERE actor_profile.id = replaced.id;

View file

@ -11,13 +11,14 @@ use crate::identity::{
claims::create_identity_claim, claims::create_identity_claim,
did::Did, did::Did,
minisign::verify_minisign_identity_proof, minisign::verify_minisign_identity_proof,
signatures::{PROOF_TYPE_ID_EIP191, PROOF_TYPE_ID_MINISIGN},
}; };
use crate::models::profiles::types::{ use crate::models::profiles::types::{
ExtraField, ExtraField,
IdentityProof, IdentityProof,
IdentityProofType,
PaymentLink, PaymentLink,
PaymentOption, PaymentOption,
ProofType,
}; };
use crate::web_client::urls::get_subscription_page_url; use crate::web_client::urls::get_subscription_page_url;
use super::types::ActorAttachment; use super::types::ActorAttachment;
@ -25,12 +26,16 @@ use super::types::ActorAttachment;
pub fn attach_identity_proof( pub fn attach_identity_proof(
proof: IdentityProof, proof: IdentityProof,
) -> ActorAttachment { ) -> ActorAttachment {
let proof_type_str = match proof.proof_type {
IdentityProofType::LegacyEip191IdentityProof => PROOF_TYPE_ID_EIP191,
IdentityProofType::LegacyMinisignIdentityProof => PROOF_TYPE_ID_MINISIGN,
};
ActorAttachment { ActorAttachment {
object_type: IDENTITY_PROOF.to_string(), object_type: IDENTITY_PROOF.to_string(),
name: proof.issuer.to_string(), name: proof.issuer.to_string(),
value: None, value: None,
href: None, href: None,
signature_algorithm: Some(proof.proof_type.to_string()), signature_algorithm: Some(proof_type_str.to_string()),
signature_value: Some(proof.value), signature_value: Some(proof.value),
} }
} }
@ -42,10 +47,13 @@ pub fn parse_identity_proof(
if attachment.object_type != IDENTITY_PROOF { if attachment.object_type != IDENTITY_PROOF {
return Err(ValidationError("invalid attachment type")); return Err(ValidationError("invalid attachment type"));
}; };
let proof_type = attachment.signature_algorithm.as_ref() let proof_type_str = attachment.signature_algorithm.as_ref()
.ok_or(ValidationError("missing proof type"))? .ok_or(ValidationError("missing proof type"))?;
.parse() let proof_type = match proof_type_str.as_str() {
.map_err(|_| ValidationError("unsupported proof type"))?; PROOF_TYPE_ID_EIP191 => IdentityProofType::LegacyEip191IdentityProof,
PROOF_TYPE_ID_MINISIGN => IdentityProofType::LegacyMinisignIdentityProof,
_ => return Err(ValidationError("unsupported proof type")),
};
let did = attachment.name.parse::<Did>() let did = attachment.name.parse::<Did>()
.map_err(|_| ValidationError("invalid DID"))?; .map_err(|_| ValidationError("invalid DID"))?;
let message = create_identity_claim(actor_id, &did) let message = create_identity_claim(actor_id, &did)
@ -54,7 +62,7 @@ pub fn parse_identity_proof(
.ok_or(ValidationError("missing signature"))?; .ok_or(ValidationError("missing signature"))?;
match did { match did {
Did::Key(ref did_key) => { Did::Key(ref did_key) => {
if !matches!(proof_type, ProofType::LegacyMinisignIdentityProof) { if !matches!(proof_type, IdentityProofType::LegacyMinisignIdentityProof) {
return Err(ValidationError("incorrect proof type")); return Err(ValidationError("incorrect proof type"));
}; };
verify_minisign_identity_proof( verify_minisign_identity_proof(
@ -64,7 +72,7 @@ pub fn parse_identity_proof(
).map_err(|_| ValidationError("invalid identity proof"))?; ).map_err(|_| ValidationError("invalid identity proof"))?;
}, },
Did::Pkh(ref did_pkh) => { Did::Pkh(ref did_pkh) => {
if !matches!(proof_type, ProofType::LegacyEip191IdentityProof) { if !matches!(proof_type, IdentityProofType::LegacyEip191IdentityProof) {
return Err(ValidationError("incorrect proof type")); return Err(ValidationError("incorrect proof type"));
}; };
verify_eip191_identity_proof( verify_eip191_identity_proof(

View file

@ -76,8 +76,8 @@ use crate::models::{
}, },
profiles::types::{ profiles::types::{
IdentityProof, IdentityProof,
IdentityProofType,
ProfileUpdateData, ProfileUpdateData,
ProofType,
}, },
relationships::queries::{ relationships::queries::{
get_followers_paginated, get_followers_paginated,
@ -411,7 +411,7 @@ async fn create_identity_proof(
&message, &message,
&proof_data.signature, &proof_data.signature,
).map_err(|_| ValidationError("invalid signature"))?; ).map_err(|_| ValidationError("invalid signature"))?;
ProofType::LegacyMinisignIdentityProof IdentityProofType::LegacyMinisignIdentityProof
}, },
Did::Pkh(ref did_pkh) => { Did::Pkh(ref did_pkh) => {
if did_pkh.chain_id != ChainId::ethereum_mainnet() { if did_pkh.chain_id != ChainId::ethereum_mainnet() {
@ -432,7 +432,7 @@ async fn create_identity_proof(
&message, &message,
&proof_data.signature, &proof_data.signature,
).map_err(|_| ValidationError("invalid signature"))?; ).map_err(|_| ValidationError("invalid signature"))?;
ProofType::LegacyEip191IdentityProof IdentityProofType::LegacyEip191IdentityProof
}, },
}; };

View file

@ -819,8 +819,8 @@ mod tests {
profiles::types::{ profiles::types::{
ExtraField, ExtraField,
IdentityProof, IdentityProof,
IdentityProofType,
ProfileCreateData, ProfileCreateData,
ProofType,
}, },
users::queries::create_user, users::queries::create_user,
users::types::UserCreateData, users::types::UserCreateData,
@ -993,7 +993,7 @@ mod tests {
let db_client = &mut create_test_database().await; let db_client = &mut create_test_database().await;
let identity_proof = IdentityProof { let identity_proof = IdentityProof {
issuer: Did::Pkh(DidPkh::from_address(&ETHEREUM, "0x1234abcd")), issuer: Did::Pkh(DidPkh::from_address(&ETHEREUM, "0x1234abcd")),
proof_type: ProofType::LegacyEip191IdentityProof, proof_type: IdentityProofType::LegacyEip191IdentityProof,
value: "13590013185bdea963".to_string(), value: "13590013185bdea963".to_string(),
}; };
let profile_data = ProfileCreateData { let profile_data = ProfileCreateData {

View file

@ -1,6 +1,3 @@
use std::fmt;
use std::str::FromStr;
use chrono::{DateTime, Duration, Utc}; use chrono::{DateTime, Duration, Utc};
use postgres_types::FromSql; use postgres_types::FromSql;
use serde::{ use serde::{
@ -21,11 +18,8 @@ use crate::database::{
json_macro::{json_from_sql, json_to_sql}, json_macro::{json_from_sql, json_to_sql},
DatabaseTypeError, DatabaseTypeError,
}; };
use crate::errors::{ConversionError, ValidationError}; use crate::errors::ValidationError;
use crate::identity::{ use crate::identity::did::Did;
did::Did,
signatures::{PROOF_TYPE_ID_EIP191, PROOF_TYPE_ID_MINISIGN},
};
use crate::models::emojis::types::DbEmoji; use crate::models::emojis::types::DbEmoji;
use crate::webfinger::types::ActorAddress; use crate::webfinger::types::ActorAddress;
use super::validators::{ use super::validators::{
@ -60,55 +54,54 @@ json_from_sql!(ProfileImage);
json_to_sql!(ProfileImage); json_to_sql!(ProfileImage);
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum ProofType { pub enum IdentityProofType {
LegacyEip191IdentityProof, LegacyEip191IdentityProof,
LegacyMinisignIdentityProof, LegacyMinisignIdentityProof,
} }
impl FromStr for ProofType { impl From<&IdentityProofType> for i16 {
type Err = ConversionError; fn from(proof_type: &IdentityProofType) -> i16 {
match proof_type {
IdentityProofType::LegacyEip191IdentityProof => 1,
IdentityProofType::LegacyMinisignIdentityProof => 2,
}
}
}
fn from_str(value: &str) -> Result<Self, Self::Err> { impl TryFrom<i16> for IdentityProofType {
type Error = DatabaseTypeError;
fn try_from(value: i16) -> Result<Self, Self::Error> {
let proof_type = match value { let proof_type = match value {
PROOF_TYPE_ID_EIP191 => Self::LegacyEip191IdentityProof, 1 => Self::LegacyEip191IdentityProof,
PROOF_TYPE_ID_MINISIGN => Self::LegacyMinisignIdentityProof, 2 => Self::LegacyMinisignIdentityProof,
_ => return Err(ConversionError), _ => return Err(DatabaseTypeError),
}; };
Ok(proof_type) Ok(proof_type)
} }
} }
impl fmt::Display for ProofType { impl<'de> Deserialize<'de> for IdentityProofType {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
let proof_type_str = match self {
Self::LegacyEip191IdentityProof => PROOF_TYPE_ID_EIP191,
Self::LegacyMinisignIdentityProof => PROOF_TYPE_ID_MINISIGN,
};
write!(formatter, "{}", proof_type_str)
}
}
impl<'de> Deserialize<'de> for ProofType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de> where D: Deserializer<'de>
{ {
String::deserialize(deserializer)? i16::deserialize(deserializer)?
.parse().map_err(DeserializerError::custom) .try_into().map_err(DeserializerError::custom)
} }
} }
impl Serialize for ProofType { impl Serialize for IdentityProofType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer where S: Serializer
{ {
serializer.serialize_str(&self.to_string()) serializer.serialize_i16(self.into())
} }
} }
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct IdentityProof { pub struct IdentityProof {
pub issuer: Did, pub issuer: Did,
pub proof_type: ProofType, pub proof_type: IdentityProofType,
pub value: String, pub value: String,
} }
@ -551,7 +544,7 @@ mod tests {
#[test] #[test]
fn test_identity_proof_serialization() { fn test_identity_proof_serialization() {
let json_data = r#"{"issuer":"did:pkh:eip155:1:0xb9c5714089478a327f09197987f16f9e5d936e8a","proof_type":"ethereum-eip191-00","value":"dbfe"}"#; let json_data = r#"{"issuer":"did:pkh:eip155:1:0xb9c5714089478a327f09197987f16f9e5d936e8a","proof_type":1,"value":"dbfe"}"#;
let proof: IdentityProof = serde_json::from_str(json_data).unwrap(); let proof: IdentityProof = serde_json::from_str(json_data).unwrap();
let did_pkh = match proof.issuer { let did_pkh = match proof.issuer {
Did::Pkh(ref did_pkh) => did_pkh, Did::Pkh(ref did_pkh) => did_pkh,