Rewrite /api/v1/subscriptions/enable handler to support more subscription types
This commit is contained in:
parent
daaa0855a6
commit
b3fb1c612c
4 changed files with 84 additions and 18 deletions
|
@ -626,6 +626,8 @@ paths:
|
|||
/api/v1/subscriptions/authorize:
|
||||
get:
|
||||
summary: Get authorization for setting up Ethereum subscription.
|
||||
security:
|
||||
- tokenAuth: []
|
||||
parameters:
|
||||
- name: price
|
||||
in: query
|
||||
|
@ -647,6 +649,22 @@ paths:
|
|||
/api/v1/subscriptions/enable:
|
||||
post:
|
||||
summary: Enable subscriptions
|
||||
security:
|
||||
- tokenAuth: []
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
description: Subscription type
|
||||
type: string
|
||||
enum:
|
||||
- ethereum
|
||||
- monero
|
||||
required:
|
||||
- type
|
||||
responses:
|
||||
200:
|
||||
description: Successful operation
|
||||
|
|
|
@ -4,3 +4,12 @@ use serde::Deserialize;
|
|||
pub struct SubscriptionQueryParams {
|
||||
pub price: u64,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum SubscriptionSettings {
|
||||
#[serde(rename = "ethereum")]
|
||||
Ethereum,
|
||||
#[serde(rename = "monero")]
|
||||
Monero { },
|
||||
}
|
||||
|
|
|
@ -13,8 +13,16 @@ use crate::ethereum::subscriptions::{
|
|||
use crate::mastodon_api::accounts::types::Account;
|
||||
use crate::mastodon_api::oauth::auth::get_current_user;
|
||||
use crate::models::profiles::queries::update_profile;
|
||||
use crate::models::profiles::types::{PaymentOption, ProfileUpdateData};
|
||||
use super::types::SubscriptionQueryParams;
|
||||
use crate::models::profiles::types::{
|
||||
PaymentOption,
|
||||
PaymentType,
|
||||
ProfileUpdateData,
|
||||
};
|
||||
use crate::utils::currencies::Currency;
|
||||
use super::types::{
|
||||
SubscriptionQueryParams,
|
||||
SubscriptionSettings,
|
||||
};
|
||||
|
||||
pub async fn authorize_subscription(
|
||||
auth: BearerAuth,
|
||||
|
@ -47,24 +55,40 @@ pub async fn subscriptions_enabled(
|
|||
config: web::Data<Config>,
|
||||
db_pool: web::Data<Pool>,
|
||||
maybe_blockchain: web::Data<Option<ContractSet>>,
|
||||
subscription_settings: web::Json<SubscriptionSettings>,
|
||||
) -> Result<HttpResponse, HttpError> {
|
||||
let db_client = &**get_database_client(&db_pool).await?;
|
||||
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(&config.default_currency())
|
||||
.ok_or(HttpError::PermissionError)?;
|
||||
let is_registered = is_registered_recipient(contract_set, &wallet_address)
|
||||
.await.map_err(|_| HttpError::InternalError)?;
|
||||
if !is_registered {
|
||||
return Err(ValidationError("recipient is not registered").into());
|
||||
};
|
||||
|
||||
if current_user.profile.payment_options.is_empty() {
|
||||
let mut maybe_payment_option = None;
|
||||
match subscription_settings.into_inner() {
|
||||
SubscriptionSettings::Ethereum => {
|
||||
let contract_set = maybe_blockchain.as_ref().as_ref()
|
||||
.ok_or(HttpError::NotSupported)?;
|
||||
let wallet_address = current_user
|
||||
.public_wallet_address(&Currency::Ethereum)
|
||||
.ok_or(HttpError::PermissionError)?;
|
||||
if !current_user.profile.payment_options
|
||||
.any(PaymentType::EthereumSubscription)
|
||||
{
|
||||
let is_registered = is_registered_recipient(
|
||||
contract_set,
|
||||
&wallet_address,
|
||||
).await.map_err(|_| HttpError::InternalError)?;
|
||||
if !is_registered {
|
||||
return Err(ValidationError("recipient is not registered").into());
|
||||
};
|
||||
maybe_payment_option = Some(PaymentOption::EthereumSubscription);
|
||||
};
|
||||
},
|
||||
SubscriptionSettings::Monero { } => {
|
||||
todo!();
|
||||
},
|
||||
};
|
||||
if let Some(payment_option) = maybe_payment_option {
|
||||
// Add payment option to profile
|
||||
let mut profile_data = ProfileUpdateData::from(¤t_user.profile);
|
||||
profile_data.payment_options = vec![PaymentOption::EthereumSubscription];
|
||||
profile_data.payment_options.push(payment_option);
|
||||
current_user.profile = update_profile(
|
||||
db_client,
|
||||
¤t_user.id,
|
||||
|
|
|
@ -42,6 +42,7 @@ impl IdentityProofs {
|
|||
json_from_sql!(IdentityProofs);
|
||||
json_to_sql!(IdentityProofs);
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum PaymentType {
|
||||
Link,
|
||||
EthereumSubscription,
|
||||
|
@ -81,6 +82,15 @@ pub enum PaymentOption {
|
|||
EthereumSubscription,
|
||||
}
|
||||
|
||||
impl PaymentOption {
|
||||
fn payment_type(&self) -> PaymentType {
|
||||
match self {
|
||||
Self::Link(_) => PaymentType::Link,
|
||||
Self::EthereumSubscription => PaymentType::EthereumSubscription,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Integer tags are not supported https://github.com/serde-rs/serde/issues/745
|
||||
// Workaround: https://stackoverflow.com/a/65576570
|
||||
impl<'de> Deserialize<'de> for PaymentOption {
|
||||
|
@ -110,10 +120,7 @@ impl Serialize for PaymentOption {
|
|||
where S: Serializer,
|
||||
{
|
||||
let mut map = serializer.serialize_map(None)?;
|
||||
let payment_type = match self {
|
||||
Self::Link(_) => PaymentType::Link,
|
||||
Self::EthereumSubscription => PaymentType::EthereumSubscription,
|
||||
};
|
||||
let payment_type = self.payment_type();
|
||||
map.serialize_entry("payment_type", &i16::from(&payment_type))?;
|
||||
|
||||
match self {
|
||||
|
@ -137,6 +144,14 @@ impl PaymentOptions {
|
|||
let Self(payment_options) = self;
|
||||
payment_options.is_empty()
|
||||
}
|
||||
|
||||
/// Returns true if payment option list contains at least one option
|
||||
/// of the given type.
|
||||
pub fn any(&self, payment_type: PaymentType) -> bool {
|
||||
let Self(payment_options) = self;
|
||||
payment_options.iter()
|
||||
.any(|option| option.payment_type() == payment_type)
|
||||
}
|
||||
}
|
||||
|
||||
json_from_sql!(PaymentOptions);
|
||||
|
|
Loading…
Reference in a new issue