Search for subscription recipient by DID instead of login address

This commit is contained in:
silverpill 2022-08-15 21:54:46 +00:00
parent 5f24af4dbf
commit e2f8408b1e
5 changed files with 56 additions and 6 deletions

View file

@ -131,7 +131,11 @@ pub async fn check_subscriptions(
continue; continue;
}, },
}; };
let recipient = get_user_by_wallet_address(db_client, &recipient_address).await?; let recipient = get_user_by_wallet_address(
db_client,
&ETHEREUM,
&recipient_address,
).await?;
match get_subscription_by_participants( match get_subscription_by_participants(
db_client, db_client,

View file

@ -56,6 +56,7 @@ use crate::models::subscriptions::queries::get_incoming_subscriptions;
use crate::models::users::queries::{ use crate::models::users::queries::{
is_valid_invite_code, is_valid_invite_code,
create_user, create_user,
get_user_by_did,
}; };
use crate::models::users::types::UserCreateData; use crate::models::users::types::UserCreateData;
use crate::utils::crypto::{ use crate::utils::crypto::{
@ -260,6 +261,15 @@ async fn create_identity_proof(
return Err(ValidationError("DID doesn't match current identity").into()); return Err(ValidationError("DID doesn't match current identity").into());
}; };
}; };
match get_user_by_did(db_client, &did).await {
Ok(user) => {
if user.id != current_user.id {
return Err(ValidationError("DID already associated with another user").into());
};
},
Err(DatabaseError::NotFound(_)) => (),
Err(other_error) => return Err(other_error.into()),
};
verify_identity_proof( verify_identity_proof(
&actor_id, &actor_id,
&did, &did,

View file

@ -8,7 +8,7 @@ use crate::ethereum::eip4361::verify_eip4361_signature;
use crate::models::oauth::queries::save_oauth_token; use crate::models::oauth::queries::save_oauth_token;
use crate::models::users::queries::{ use crate::models::users::queries::{
get_user_by_name, get_user_by_name,
get_user_by_wallet_address, get_user_by_login_address,
}; };
use crate::utils::crypto::verify_password; use crate::utils::crypto::verify_password;
use crate::utils::currencies::validate_wallet_address; use crate::utils::currencies::validate_wallet_address;
@ -37,7 +37,7 @@ async fn token_view(
let wallet_address = request_data.wallet_address.as_ref() let wallet_address = request_data.wallet_address.as_ref()
.ok_or(ValidationError("wallet address is required"))?; .ok_or(ValidationError("wallet address is required"))?;
validate_wallet_address(&config.default_currency(), wallet_address)?; validate_wallet_address(&config.default_currency(), wallet_address)?;
get_user_by_wallet_address(db_client, wallet_address).await? get_user_by_login_address(db_client, wallet_address).await?
}, },
"eip4361" => { "eip4361" => {
let message = request_data.message.as_ref() let message = request_data.message.as_ref()
@ -50,7 +50,7 @@ async fn token_view(
&config.instance().host(), &config.instance().host(),
&config.login_message, &config.login_message,
)?; )?;
get_user_by_wallet_address(db_client, &wallet_address).await? get_user_by_login_address(db_client, &wallet_address).await?
}, },
_ => { _ => {
return Err(ValidationError("unsupported grant type").into()); return Err(ValidationError("unsupported grant type").into());

View file

@ -404,7 +404,7 @@ pub async fn search_profile_by_did(
_ => "LIKE", _ => "LIKE",
}; };
// This query does not scan user_account.wallet_address because // This query does not scan user_account.wallet_address because
// login addresses are private by default. // login addresses are private.
let statement = format!( let statement = format!(
" "
{identity_proof_query} {identity_proof_query}

View file

@ -3,8 +3,10 @@ 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::profiles::queries::create_profile; use crate::models::profiles::queries::create_profile;
use crate::models::profiles::types::{DbActorProfile, ProfileCreateData}; use crate::models::profiles::types::{DbActorProfile, ProfileCreateData};
use crate::utils::currencies::Currency;
use super::types::{DbUser, User, UserCreateData}; use super::types::{DbUser, User, UserCreateData};
use super::utils::generate_invite_code; use super::utils::generate_invite_code;
@ -161,7 +163,7 @@ pub async fn is_registered_user(
Ok(maybe_row.is_some()) Ok(maybe_row.is_some())
} }
pub async fn get_user_by_wallet_address( pub async fn get_user_by_login_address(
db_client: &impl GenericClient, db_client: &impl GenericClient,
wallet_address: &str, wallet_address: &str,
) -> Result<User, DatabaseError> { ) -> Result<User, DatabaseError> {
@ -180,6 +182,40 @@ pub async fn get_user_by_wallet_address(
Ok(user) Ok(user)
} }
pub async fn get_user_by_did(
db_client: &impl GenericClient,
did: &DidPkh,
) -> Result<User, DatabaseError> {
// DIDs must be locally unique
let maybe_row = db_client.query_opt(
"
SELECT user_account, actor_profile
FROM user_account JOIN actor_profile USING (id)
WHERE
EXISTS (
SELECT 1
FROM jsonb_array_elements(actor_profile.identity_proofs) AS proof
WHERE proof ->> 'issuer' = $1
)
",
&[&did.to_string()],
).await?;
let row = maybe_row.ok_or(DatabaseError::NotFound("user"))?;
let db_user: DbUser = row.try_get("user_account")?;
let db_profile: DbActorProfile = row.try_get("actor_profile")?;
let user = User::new(db_user, db_profile);
Ok(user)
}
pub async fn get_user_by_wallet_address(
db_client: &impl GenericClient,
currency: &Currency,
wallet_address: &str,
) -> Result<User, DatabaseError> {
let did = DidPkh::from_address(currency, wallet_address);
get_user_by_did(db_client, &did).await
}
pub async fn get_user_count( pub async fn get_user_count(
db_client: &impl GenericClient, db_client: &impl GenericClient,
) -> Result<i64, DatabaseError> { ) -> Result<i64, DatabaseError> {