Include results based on identity proofs when searching profiles by wallet address
This commit is contained in:
parent
a1af35997c
commit
303827ffc6
4 changed files with 60 additions and 14 deletions
|
@ -7,6 +7,7 @@ use serde::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::errors::ValidationError;
|
use crate::errors::ValidationError;
|
||||||
|
use crate::models::profiles::currencies::Currency;
|
||||||
use super::signatures::recover_address;
|
use super::signatures::recover_address;
|
||||||
use super::utils::address_to_string;
|
use super::utils::address_to_string;
|
||||||
|
|
||||||
|
@ -22,14 +23,10 @@ pub struct DidPkh {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DidPkh {
|
impl DidPkh {
|
||||||
pub fn from_ethereum_address(address: &str) -> Self {
|
pub fn from_address(currency: &Currency, address: &str) -> Self {
|
||||||
// Ethereum mainnet
|
let (network_id, chain_id) = currency.caip2();
|
||||||
// https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-3.md
|
let address = currency.normalize_address(address);
|
||||||
Self {
|
Self { network_id, chain_id, address }
|
||||||
network_id: "eip155".to_string(),
|
|
||||||
chain_id: "1".to_string(),
|
|
||||||
address: address.to_lowercase(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,10 +130,12 @@ mod tests {
|
||||||
use crate::ethereum::utils::address_to_string;
|
use crate::ethereum::utils::address_to_string;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
const ETHEREUM: Currency = Currency::Ethereum;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_did_string_conversion() {
|
fn test_did_string_conversion() {
|
||||||
let address = "0xB9C5714089478a327F09197987f16f9E5d936E8a";
|
let address = "0xB9C5714089478a327F09197987f16f9E5d936E8a";
|
||||||
let did = DidPkh::from_ethereum_address(address);
|
let did = DidPkh::from_address(ÐEREUM, address);
|
||||||
assert_eq!(did.address, address.to_lowercase());
|
assert_eq!(did.address, address.to_lowercase());
|
||||||
|
|
||||||
let did_str = did.to_string();
|
let did_str = did.to_string();
|
||||||
|
@ -156,7 +155,7 @@ mod tests {
|
||||||
let secret_key_ref = SecretKeyRef::new(&secret_key);
|
let secret_key_ref = SecretKeyRef::new(&secret_key);
|
||||||
let secret_key_str = secret_key.display_secret().to_string();
|
let secret_key_str = secret_key.display_secret().to_string();
|
||||||
let address = address_to_string(secret_key_ref.address());
|
let address = address_to_string(secret_key_ref.address());
|
||||||
let did = DidPkh::from_ethereum_address(&address);
|
let did = DidPkh::from_address(ÐEREUM, &address);
|
||||||
let message = create_identity_claim(actor_id, &did).unwrap();
|
let message = create_identity_claim(actor_id, &did).unwrap();
|
||||||
let signature = sign_message(&secret_key_str, message.as_bytes()).unwrap().to_string();
|
let signature = sign_message(&secret_key_str, message.as_bytes()).unwrap().to_string();
|
||||||
let result = verify_identity_proof(actor_id, &did, &signature);
|
let result = verify_identity_proof(actor_id, &did, &signature);
|
||||||
|
|
|
@ -227,7 +227,7 @@ async fn get_identity_claim(
|
||||||
let actor_id = current_user.profile.actor_id(&config.instance_url());
|
let actor_id = current_user.profile.actor_id(&config.instance_url());
|
||||||
let wallet_address = current_user.wallet_address.as_ref()
|
let wallet_address = current_user.wallet_address.as_ref()
|
||||||
.ok_or(HttpError::PermissionError)?;
|
.ok_or(HttpError::PermissionError)?;
|
||||||
let did = DidPkh::from_ethereum_address(wallet_address);
|
let did = DidPkh::from_address(&config.default_currency(), wallet_address);
|
||||||
let claim = create_identity_claim(&actor_id, &did)
|
let claim = create_identity_claim(&actor_id, &did)
|
||||||
.map_err(|_| HttpError::InternalError)?;
|
.map_err(|_| HttpError::InternalError)?;
|
||||||
let response = IdentityClaim { claim };
|
let response = IdentityClaim { claim };
|
||||||
|
@ -246,7 +246,7 @@ async fn create_identity_proof(
|
||||||
let actor_id = current_user.profile.actor_id(&config.instance_url());
|
let actor_id = current_user.profile.actor_id(&config.instance_url());
|
||||||
let wallet_address = current_user.wallet_address.as_ref()
|
let wallet_address = current_user.wallet_address.as_ref()
|
||||||
.ok_or(HttpError::PermissionError)?;
|
.ok_or(HttpError::PermissionError)?;
|
||||||
let did = DidPkh::from_ethereum_address(wallet_address);
|
let did = DidPkh::from_address(&config.default_currency(), wallet_address);
|
||||||
verify_identity_proof(
|
verify_identity_proof(
|
||||||
&actor_id,
|
&actor_id,
|
||||||
&did,
|
&did,
|
||||||
|
|
|
@ -10,6 +10,21 @@ impl Currency {
|
||||||
Self::Ethereum => "ETH",
|
Self::Ethereum => "ETH",
|
||||||
}.to_string()
|
}.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Network ID and chain ID according to CAIP-2 standard
|
||||||
|
/// https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md
|
||||||
|
pub fn caip2(&self) -> (String, String) {
|
||||||
|
let (network_id, chain_id) = match self {
|
||||||
|
Self::Ethereum => ("eip155", "1"),
|
||||||
|
};
|
||||||
|
(network_id.to_string(), chain_id.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn normalize_address(&self, address: &str) -> String {
|
||||||
|
match self {
|
||||||
|
Self::Ethereum => address.to_lowercase(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_currency_field_name(currency: &Currency) -> String {
|
pub fn get_currency_field_name(currency: &Currency) -> String {
|
||||||
|
|
|
@ -3,6 +3,7 @@ use uuid::Uuid;
|
||||||
|
|
||||||
use crate::database::catch_unique_violation;
|
use crate::database::catch_unique_violation;
|
||||||
use crate::errors::DatabaseError;
|
use crate::errors::DatabaseError;
|
||||||
|
use crate::ethereum::identity::DidPkh;
|
||||||
use crate::models::cleanup::{
|
use crate::models::cleanup::{
|
||||||
find_orphaned_files,
|
find_orphaned_files,
|
||||||
find_orphaned_ipfs_objects,
|
find_orphaned_ipfs_objects,
|
||||||
|
@ -374,6 +375,7 @@ pub async fn search_profile_by_wallet_address(
|
||||||
wallet_address: &str,
|
wallet_address: &str,
|
||||||
) -> Result<Vec<DbActorProfile>, DatabaseError> {
|
) -> Result<Vec<DbActorProfile>, DatabaseError> {
|
||||||
let field_name = get_currency_field_name(currency);
|
let field_name = get_currency_field_name(currency);
|
||||||
|
let did_str = DidPkh::from_address(currency, wallet_address).to_string();
|
||||||
// If currency is Ethereum,
|
// If currency is Ethereum,
|
||||||
// search over extra fields must be case insensitive
|
// search over extra fields must be case insensitive
|
||||||
let rows = db_client.query(
|
let rows = db_client.query(
|
||||||
|
@ -382,6 +384,11 @@ pub async fn search_profile_by_wallet_address(
|
||||||
FROM actor_profile LEFT JOIN user_account USING (id)
|
FROM actor_profile LEFT JOIN user_account USING (id)
|
||||||
WHERE
|
WHERE
|
||||||
user_account.wallet_address = $2
|
user_account.wallet_address = $2
|
||||||
|
OR EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM jsonb_array_elements(actor_profile.identity_proofs) AS proof
|
||||||
|
WHERE proof ->> 'issuer' = $3
|
||||||
|
)
|
||||||
OR EXISTS (
|
OR EXISTS (
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM jsonb_array_elements(actor_profile.extra_fields) AS field
|
FROM jsonb_array_elements(actor_profile.extra_fields) AS field
|
||||||
|
@ -390,7 +397,7 @@ pub async fn search_profile_by_wallet_address(
|
||||||
AND field ->> 'value' ILIKE $2
|
AND field ->> 'value' ILIKE $2
|
||||||
)
|
)
|
||||||
",
|
",
|
||||||
&[&field_name, &wallet_address],
|
&[&field_name, &wallet_address, &did_str],
|
||||||
).await?;
|
).await?;
|
||||||
let profiles: Vec<DbActorProfile> = rows.iter()
|
let profiles: Vec<DbActorProfile> = rows.iter()
|
||||||
.map(|row| row.try_get("actor_profile"))
|
.map(|row| row.try_get("actor_profile"))
|
||||||
|
@ -481,7 +488,11 @@ mod tests {
|
||||||
use crate::activitypub::actor::Actor;
|
use crate::activitypub::actor::Actor;
|
||||||
use crate::database::test_utils::create_test_database;
|
use crate::database::test_utils::create_test_database;
|
||||||
use crate::models::profiles::queries::create_profile;
|
use crate::models::profiles::queries::create_profile;
|
||||||
use crate::models::profiles::types::{ExtraField, ProfileCreateData};
|
use crate::models::profiles::types::{
|
||||||
|
ExtraField,
|
||||||
|
IdentityProof,
|
||||||
|
ProfileCreateData,
|
||||||
|
};
|
||||||
use crate::models::users::queries::create_user;
|
use crate::models::users::queries::create_user;
|
||||||
use crate::models::users::types::UserCreateData;
|
use crate::models::users::types::UserCreateData;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -575,4 +586,25 @@ mod tests {
|
||||||
assert_eq!(profiles.len(), 1);
|
assert_eq!(profiles.len(), 1);
|
||||||
assert_eq!(profiles[0].id, profile.id);
|
assert_eq!(profiles[0].id, profile.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[serial]
|
||||||
|
async fn test_search_profile_by_wallet_address_identity_proof() {
|
||||||
|
let db_client = &mut create_test_database().await;
|
||||||
|
let identity_proof = IdentityProof {
|
||||||
|
issuer: DidPkh::from_address(ÐEREUM, "0x1234abcd"),
|
||||||
|
proof_type: "ethereum".to_string(),
|
||||||
|
value: "13590013185bdea963".to_string(),
|
||||||
|
};
|
||||||
|
let profile_data = ProfileCreateData {
|
||||||
|
identity_proofs: vec![identity_proof],
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let profile = create_profile(db_client, profile_data).await.unwrap();
|
||||||
|
let profiles = search_profile_by_wallet_address(
|
||||||
|
db_client, ÐEREUM, "0x1234abcd").await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(profiles.len(), 1);
|
||||||
|
assert_eq!(profiles[0].id, profile.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue