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;
},
};
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(
db_client,

View file

@ -56,6 +56,7 @@ use crate::models::subscriptions::queries::get_incoming_subscriptions;
use crate::models::users::queries::{
is_valid_invite_code,
create_user,
get_user_by_did,
};
use crate::models::users::types::UserCreateData;
use crate::utils::crypto::{
@ -260,6 +261,15 @@ async fn create_identity_proof(
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(
&actor_id,
&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::users::queries::{
get_user_by_name,
get_user_by_wallet_address,
get_user_by_login_address,
};
use crate::utils::crypto::verify_password;
use crate::utils::currencies::validate_wallet_address;
@ -37,7 +37,7 @@ async fn token_view(
let wallet_address = request_data.wallet_address.as_ref()
.ok_or(ValidationError("wallet address is required"))?;
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" => {
let message = request_data.message.as_ref()
@ -50,7 +50,7 @@ async fn token_view(
&config.instance().host(),
&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());

View file

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

View file

@ -3,8 +3,10 @@ use uuid::Uuid;
use crate::database::catch_unique_violation;
use crate::errors::DatabaseError;
use crate::ethereum::identity::DidPkh;
use crate::models::profiles::queries::create_profile;
use crate::models::profiles::types::{DbActorProfile, ProfileCreateData};
use crate::utils::currencies::Currency;
use super::types::{DbUser, User, UserCreateData};
use super::utils::generate_invite_code;
@ -161,7 +163,7 @@ pub async fn is_registered_user(
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,
wallet_address: &str,
) -> Result<User, DatabaseError> {
@ -180,6 +182,40 @@ pub async fn get_user_by_wallet_address(
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(
db_client: &impl GenericClient,
) -> Result<i64, DatabaseError> {