Allow users of password auth to use subscriptions
This commit is contained in:
parent
596871e6e3
commit
a80c11b99c
5 changed files with 26 additions and 27 deletions
|
@ -159,7 +159,7 @@ paths:
|
||||||
description: User's wallet address is not known or not verified
|
description: User's wallet address is not known or not verified
|
||||||
418:
|
418:
|
||||||
description: Blockchain integration is not enabled
|
description: Blockchain integration is not enabled
|
||||||
/api/v1/accounts/subscription_enabled:
|
/api/v1/accounts/subscriptions_enabled:
|
||||||
post:
|
post:
|
||||||
summary: Notify server about subscription setup
|
summary: Notify server about subscription setup
|
||||||
responses:
|
responses:
|
||||||
|
@ -792,11 +792,6 @@ components:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/Field'
|
$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:
|
subscription_page_url:
|
||||||
description: Subscription page URL
|
description: Subscription page URL
|
||||||
type: string
|
type: string
|
||||||
|
|
|
@ -57,7 +57,6 @@ pub struct Account {
|
||||||
|
|
||||||
pub source: Option<Source>,
|
pub source: Option<Source>,
|
||||||
|
|
||||||
pub wallet_address: Option<String>,
|
|
||||||
pub subscription_page_url: Option<String>,
|
pub subscription_page_url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +121,6 @@ impl Account {
|
||||||
following_count: profile.following_count,
|
following_count: profile.following_count,
|
||||||
statuses_count: profile.post_count,
|
statuses_count: profile.post_count,
|
||||||
source: None,
|
source: None,
|
||||||
wallet_address: None,
|
|
||||||
subscription_page_url,
|
subscription_page_url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,11 +138,8 @@ impl Account {
|
||||||
note: user.profile.bio_source.clone(),
|
note: user.profile.bio_source.clone(),
|
||||||
fields: fields_sources,
|
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);
|
let mut account = Self::from_profile(user.profile, instance_url);
|
||||||
account.source = Some(source);
|
account.source = Some(source);
|
||||||
account.wallet_address = wallet_address;
|
|
||||||
account
|
account
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -388,7 +383,6 @@ mod tests {
|
||||||
format!("{}/media/test", INSTANCE_URL),
|
format!("{}/media/test", INSTANCE_URL),
|
||||||
);
|
);
|
||||||
assert!(account.source.is_none());
|
assert!(account.source.is_none());
|
||||||
assert!(account.wallet_address.is_none());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -410,6 +404,5 @@ mod tests {
|
||||||
account.source.unwrap().note.unwrap(),
|
account.source.unwrap().note.unwrap(),
|
||||||
bio_source,
|
bio_source,
|
||||||
);
|
);
|
||||||
assert_eq!(account.wallet_address, None);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,9 +300,11 @@ async fn authorize_subscription(
|
||||||
.ok_or(HttpError::NotSupported)?
|
.ok_or(HttpError::NotSupported)?
|
||||||
.ethereum_config()
|
.ethereum_config()
|
||||||
.ok_or(HttpError::NotSupported)?;
|
.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.
|
// 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)?;
|
.ok_or(HttpError::PermissionError)?;
|
||||||
let signature = create_subscription_signature(
|
let signature = create_subscription_signature(
|
||||||
ethereum_config,
|
ethereum_config,
|
||||||
|
@ -323,7 +325,8 @@ async fn subscriptions_enabled(
|
||||||
let mut current_user = get_current_user(db_client, auth.token()).await?;
|
let mut current_user = get_current_user(db_client, auth.token()).await?;
|
||||||
let contract_set = maybe_blockchain.as_ref().as_ref()
|
let contract_set = maybe_blockchain.as_ref().as_ref()
|
||||||
.ok_or(HttpError::NotSupported)?;
|
.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)?;
|
.ok_or(HttpError::PermissionError)?;
|
||||||
let is_registered = is_registered_recipient(contract_set, &wallet_address)
|
let is_registered = is_registered_recipient(contract_set, &wallet_address)
|
||||||
.await.map_err(|_| HttpError::InternalError)?;
|
.await.map_err(|_| HttpError::InternalError)?;
|
||||||
|
|
|
@ -429,8 +429,9 @@ async fn get_signature(
|
||||||
.ok_or(HttpError::NotSupported)?
|
.ok_or(HttpError::NotSupported)?
|
||||||
.ethereum_config()
|
.ethereum_config()
|
||||||
.ok_or(HttpError::NotSupported)?;
|
.ok_or(HttpError::NotSupported)?;
|
||||||
// Wallet address must be public because minting exposes it
|
// User must have a public wallet address
|
||||||
let wallet_address = current_user.public_wallet_address()
|
let wallet_address = current_user
|
||||||
|
.public_wallet_address(&config.default_currency())
|
||||||
.ok_or(HttpError::PermissionError)?;
|
.ok_or(HttpError::PermissionError)?;
|
||||||
let post = get_post_by_id(db_client, &status_id).await?;
|
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() {
|
if post.author.id != current_user.id || !post.is_public() || post.repost_of_id.is_some() {
|
||||||
|
|
|
@ -5,6 +5,7 @@ use uuid::Uuid;
|
||||||
|
|
||||||
use crate::errors::ValidationError;
|
use crate::errors::ValidationError;
|
||||||
use crate::models::profiles::types::DbActorProfile;
|
use crate::models::profiles::types::DbActorProfile;
|
||||||
|
use crate::utils::currencies::Currency;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(FromSql)]
|
#[derive(FromSql)]
|
||||||
|
@ -23,7 +24,7 @@ pub struct DbUser {
|
||||||
#[cfg_attr(test, derive(Default))]
|
#[cfg_attr(test, derive(Default))]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub wallet_address: Option<String>,
|
pub wallet_address: Option<String>, // login address
|
||||||
pub password_hash: Option<String>,
|
pub password_hash: Option<String>,
|
||||||
pub private_key: String,
|
pub private_key: String,
|
||||||
pub profile: DbActorProfile,
|
pub profile: DbActorProfile,
|
||||||
|
@ -44,12 +45,17 @@ impl User {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns login address if it is verified
|
/// Returns wallet address if it is verified
|
||||||
pub fn public_wallet_address(&self) -> Option<String> {
|
pub fn public_wallet_address(&self, currency: &Currency) -> Option<String> {
|
||||||
let wallet_address = self.wallet_address.clone()?;
|
for proof in self.profile.identity_proofs.clone().into_inner() {
|
||||||
let is_verified = self.profile.identity_proofs.clone().into_inner().iter()
|
// Return first match (it's safe if user is local)
|
||||||
.any(|proof| proof.issuer.address == wallet_address);
|
if let Some(ref address_currency) = proof.issuer.currency() {
|
||||||
if is_verified { Some(wallet_address) } else { None }
|
if address_currency == currency {
|
||||||
|
return Some(proof.issuer.address);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,12 +82,13 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_public_wallet_address_hidden_by_default() {
|
fn test_public_wallet_address_login_address_not_exposed() {
|
||||||
let user = User {
|
let user = User {
|
||||||
wallet_address: Some("0x1234".to_string()),
|
wallet_address: Some("0x1234".to_string()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
assert_eq!(user.public_wallet_address(), None);
|
let ethereum = Currency::Ethereum;
|
||||||
|
assert_eq!(user.public_wallet_address(ðereum), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue