From a80c11b99c9db911477e14d3e48faff455534f69 Mon Sep 17 00:00:00 2001 From: silverpill Date: Mon, 15 Aug 2022 19:25:31 +0000 Subject: [PATCH] Allow users of password auth to use subscriptions --- docs/openapi.yaml | 7 +------ src/mastodon_api/accounts/types.rs | 7 ------- src/mastodon_api/accounts/views.rs | 9 ++++++--- src/mastodon_api/statuses/views.rs | 5 +++-- src/models/users/types.rs | 25 ++++++++++++++++--------- 5 files changed, 26 insertions(+), 27 deletions(-) diff --git a/docs/openapi.yaml b/docs/openapi.yaml index f4b6b1a..1da1471 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -159,7 +159,7 @@ paths: description: User's wallet address is not known or not verified 418: description: Blockchain integration is not enabled - /api/v1/accounts/subscription_enabled: + /api/v1/accounts/subscriptions_enabled: post: summary: Notify server about subscription setup responses: @@ -792,11 +792,6 @@ components: type: array items: $ref: '#/components/schemas/Field' - wallet_address: - description: Ethereum wallet address (visibile only to the current user). - type: string - nullable: true - example: '0xd8da6bf...' subscription_page_url: description: Subscription page URL type: string diff --git a/src/mastodon_api/accounts/types.rs b/src/mastodon_api/accounts/types.rs index 9eaeb63..9d2c01b 100644 --- a/src/mastodon_api/accounts/types.rs +++ b/src/mastodon_api/accounts/types.rs @@ -57,7 +57,6 @@ pub struct Account { pub source: Option, - pub wallet_address: Option, pub subscription_page_url: Option, } @@ -122,7 +121,6 @@ impl Account { following_count: profile.following_count, statuses_count: profile.post_count, source: None, - wallet_address: None, subscription_page_url, } } @@ -140,11 +138,8 @@ impl Account { note: user.profile.bio_source.clone(), fields: fields_sources, }; - // Expose login address only if it's verified - let wallet_address = user.public_wallet_address(); let mut account = Self::from_profile(user.profile, instance_url); account.source = Some(source); - account.wallet_address = wallet_address; account } } @@ -388,7 +383,6 @@ mod tests { format!("{}/media/test", INSTANCE_URL), ); assert!(account.source.is_none()); - assert!(account.wallet_address.is_none()); } #[test] @@ -410,6 +404,5 @@ mod tests { account.source.unwrap().note.unwrap(), bio_source, ); - assert_eq!(account.wallet_address, None); } } diff --git a/src/mastodon_api/accounts/views.rs b/src/mastodon_api/accounts/views.rs index b8dae80..98049e0 100644 --- a/src/mastodon_api/accounts/views.rs +++ b/src/mastodon_api/accounts/views.rs @@ -300,9 +300,11 @@ async fn authorize_subscription( .ok_or(HttpError::NotSupported)? .ethereum_config() .ok_or(HttpError::NotSupported)?; - // Wallet address must be public, because subscribers should be able + // The user must have a public wallet address, + // because subscribers should be able // to verify that payments are actually sent to the recipient. - let wallet_address = current_user.public_wallet_address() + let wallet_address = current_user + .public_wallet_address(&config.default_currency()) .ok_or(HttpError::PermissionError)?; let signature = create_subscription_signature( ethereum_config, @@ -323,7 +325,8 @@ async fn subscriptions_enabled( let mut current_user = get_current_user(db_client, auth.token()).await?; let contract_set = maybe_blockchain.as_ref().as_ref() .ok_or(HttpError::NotSupported)?; - let wallet_address = current_user.public_wallet_address() + let wallet_address = current_user + .public_wallet_address(&config.default_currency()) .ok_or(HttpError::PermissionError)?; let is_registered = is_registered_recipient(contract_set, &wallet_address) .await.map_err(|_| HttpError::InternalError)?; diff --git a/src/mastodon_api/statuses/views.rs b/src/mastodon_api/statuses/views.rs index cb9060a..1f95e32 100644 --- a/src/mastodon_api/statuses/views.rs +++ b/src/mastodon_api/statuses/views.rs @@ -429,8 +429,9 @@ async fn get_signature( .ok_or(HttpError::NotSupported)? .ethereum_config() .ok_or(HttpError::NotSupported)?; - // Wallet address must be public because minting exposes it - let wallet_address = current_user.public_wallet_address() + // User must have a public wallet address + let wallet_address = current_user + .public_wallet_address(&config.default_currency()) .ok_or(HttpError::PermissionError)?; let post = get_post_by_id(db_client, &status_id).await?; if post.author.id != current_user.id || !post.is_public() || post.repost_of_id.is_some() { diff --git a/src/models/users/types.rs b/src/models/users/types.rs index 1fdd5e6..b989369 100644 --- a/src/models/users/types.rs +++ b/src/models/users/types.rs @@ -5,6 +5,7 @@ use uuid::Uuid; use crate::errors::ValidationError; use crate::models::profiles::types::DbActorProfile; +use crate::utils::currencies::Currency; #[allow(dead_code)] #[derive(FromSql)] @@ -23,7 +24,7 @@ pub struct DbUser { #[cfg_attr(test, derive(Default))] pub struct User { pub id: Uuid, - pub wallet_address: Option, + pub wallet_address: Option, // login address pub password_hash: Option, pub private_key: String, pub profile: DbActorProfile, @@ -44,12 +45,17 @@ impl User { } } - /// Returns login address if it is verified - pub fn public_wallet_address(&self) -> Option { - let wallet_address = self.wallet_address.clone()?; - let is_verified = self.profile.identity_proofs.clone().into_inner().iter() - .any(|proof| proof.issuer.address == wallet_address); - if is_verified { Some(wallet_address) } else { None } + /// Returns wallet address if it is verified + pub fn public_wallet_address(&self, currency: &Currency) -> Option { + for proof in self.profile.identity_proofs.clone().into_inner() { + // Return first match (it's safe if user is local) + if let Some(ref address_currency) = proof.issuer.currency() { + if address_currency == currency { + return Some(proof.issuer.address); + }; + }; + }; + None } } @@ -76,12 +82,13 @@ mod tests { use super::*; #[test] - fn test_public_wallet_address_hidden_by_default() { + fn test_public_wallet_address_login_address_not_exposed() { let user = User { wallet_address: Some("0x1234".to_string()), ..Default::default() }; - assert_eq!(user.public_wallet_address(), None); + let ethereum = Currency::Ethereum; + assert_eq!(user.public_wallet_address(ðereum), None); } #[test]