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