kopia lustrzana https://github.com/ryukoposting/Signal-Android
Ensure capability check occurs for gift recipients.
rodzic
53e347a67d
commit
84d0283719
|
@ -1,22 +1,14 @@
|
|||
package org.thoughtcrime.securesms.badges.gifts.flow
|
||||
|
||||
import io.reactivex.rxjava3.core.Completable
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.money.FiatMoney
|
||||
import org.thoughtcrime.securesms.badges.models.Badge
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.errors.DonationError
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.getGiftBadgeAmounts
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.getGiftBadges
|
||||
import org.thoughtcrime.securesms.database.RecipientTable
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.util.ProfileUtil
|
||||
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile
|
||||
import org.whispersystems.signalservice.internal.push.DonationsConfiguration
|
||||
import java.io.IOException
|
||||
import java.util.Currency
|
||||
import java.util.Locale
|
||||
|
||||
|
@ -50,39 +42,4 @@ class GiftFlowRepository {
|
|||
.flatMap { it.flattenResult() }
|
||||
.map { it.getGiftBadgeAmounts() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the given recipient is a supported target for a gift.
|
||||
*
|
||||
* TODO[alex] - this needs to be incorporated into the correct flows.
|
||||
*/
|
||||
fun verifyRecipientIsAllowedToReceiveAGift(badgeRecipient: RecipientId): Completable {
|
||||
return Completable.fromAction {
|
||||
Log.d(TAG, "Verifying badge recipient $badgeRecipient", true)
|
||||
val recipient = Recipient.resolved(badgeRecipient)
|
||||
|
||||
if (recipient.isSelf) {
|
||||
Log.d(TAG, "Cannot send a gift to self.", true)
|
||||
throw DonationError.GiftRecipientVerificationError.SelectedRecipientDoesNotSupportGifts
|
||||
}
|
||||
|
||||
if (recipient.isGroup || recipient.isDistributionList || recipient.registered != RecipientTable.RegisteredState.REGISTERED) {
|
||||
Log.w(TAG, "Invalid badge recipient $badgeRecipient. Verification failed.", true)
|
||||
throw DonationError.GiftRecipientVerificationError.SelectedRecipientIsInvalid
|
||||
}
|
||||
|
||||
try {
|
||||
val profile = ProfileUtil.retrieveProfileSync(ApplicationDependencies.getApplication(), recipient, SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL)
|
||||
if (!profile.profile.capabilities.isGiftBadges) {
|
||||
Log.w(TAG, "Badge recipient does not support gifting. Verification failed.", true)
|
||||
throw DonationError.GiftRecipientVerificationError.SelectedRecipientDoesNotSupportGifts
|
||||
} else {
|
||||
Log.d(TAG, "Badge recipient supports gifting. Verification successful.", true)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
Log.w(TAG, "Failed to retrieve profile for recipient.", e, true)
|
||||
throw DonationError.GiftRecipientVerificationError.FailedToFetchProfile(e)
|
||||
}
|
||||
}.subscribeOn(Schedulers.io())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.thoughtcrime.securesms.badges.models.Badge
|
|||
import org.thoughtcrime.securesms.components.settings.app.subscription.boost.Boost
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.errors.DonationError
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.errors.DonationErrorSource
|
||||
import org.thoughtcrime.securesms.database.RecipientTable
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.database.model.DonationReceiptRecord
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
|
@ -17,8 +18,11 @@ import org.thoughtcrime.securesms.jobmanager.JobTracker
|
|||
import org.thoughtcrime.securesms.jobs.BoostReceiptRequestResponseJob
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.util.ProfileUtil
|
||||
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile
|
||||
import org.whispersystems.signalservice.api.services.DonationsService
|
||||
import org.whispersystems.signalservice.internal.push.DonationProcessor
|
||||
import java.io.IOException
|
||||
import java.util.Currency
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
@ -38,6 +42,36 @@ class OneTimeDonationRepository(private val donationsService: DonationsService)
|
|||
Single.error(DonationError.getPaymentSetupError(errorSource, throwable, paymentSourceType))
|
||||
}
|
||||
}
|
||||
|
||||
fun verifyRecipientIsAllowedToReceiveAGift(badgeRecipient: RecipientId): Completable {
|
||||
return Completable.fromAction {
|
||||
Log.d(TAG, "Verifying badge recipient $badgeRecipient", true)
|
||||
val recipient = Recipient.resolved(badgeRecipient)
|
||||
|
||||
if (recipient.isSelf) {
|
||||
Log.d(TAG, "Cannot send a gift to self.", true)
|
||||
throw DonationError.GiftRecipientVerificationError.SelectedRecipientDoesNotSupportGifts
|
||||
}
|
||||
|
||||
if (recipient.isGroup || recipient.isDistributionList || recipient.registered != RecipientTable.RegisteredState.REGISTERED) {
|
||||
Log.w(TAG, "Invalid badge recipient $badgeRecipient. Verification failed.", true)
|
||||
throw DonationError.GiftRecipientVerificationError.SelectedRecipientIsInvalid
|
||||
}
|
||||
|
||||
try {
|
||||
val profile = ProfileUtil.retrieveProfileSync(ApplicationDependencies.getApplication(), recipient, SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL)
|
||||
if (!profile.profile.capabilities.isGiftBadges) {
|
||||
Log.w(TAG, "Badge recipient does not support gifting. Verification failed.", true)
|
||||
throw DonationError.GiftRecipientVerificationError.SelectedRecipientDoesNotSupportGifts
|
||||
} else {
|
||||
Log.d(TAG, "Badge recipient supports gifting. Verification successful.", true)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
Log.w(TAG, "Failed to retrieve profile for recipient.", e, true)
|
||||
throw DonationError.GiftRecipientVerificationError.FailedToFetchProfile(e)
|
||||
}
|
||||
}.subscribeOn(Schedulers.io())
|
||||
}
|
||||
}
|
||||
|
||||
fun getBoosts(): Single<Map<Currency, List<Boost>>> {
|
||||
|
|
|
@ -127,12 +127,20 @@ class PayPalPaymentInProgressViewModel(
|
|||
) {
|
||||
Log.d(TAG, "Proceeding with one-time payment pipeline...", true)
|
||||
store.update { DonationProcessorStage.PAYMENT_PIPELINE }
|
||||
val verifyUser = if (request.donateToSignalType == DonateToSignalType.GIFT) {
|
||||
OneTimeDonationRepository.verifyRecipientIsAllowedToReceiveAGift(request.recipientId)
|
||||
} else {
|
||||
Completable.complete()
|
||||
}
|
||||
|
||||
disposables += payPalRepository
|
||||
.createOneTimePaymentIntent(
|
||||
amount = request.fiat,
|
||||
badgeRecipient = request.recipientId,
|
||||
badgeLevel = request.level
|
||||
disposables += verifyUser
|
||||
.andThen(
|
||||
payPalRepository
|
||||
.createOneTimePaymentIntent(
|
||||
amount = request.fiat,
|
||||
badgeRecipient = request.recipientId,
|
||||
badgeLevel = request.level
|
||||
)
|
||||
)
|
||||
.flatMap(routeToPaypalConfirmation)
|
||||
.flatMap { result ->
|
||||
|
|
|
@ -178,8 +178,13 @@ class StripePaymentInProgressViewModel(
|
|||
Log.w(TAG, "Beginning one-time payment pipeline...", true)
|
||||
|
||||
val amount = request.fiat
|
||||
val verifyUser = if (request.donateToSignalType == DonateToSignalType.GIFT) {
|
||||
OneTimeDonationRepository.verifyRecipientIsAllowedToReceiveAGift(request.recipientId)
|
||||
} else {
|
||||
Completable.complete()
|
||||
}
|
||||
|
||||
val continuePayment: Single<StripeIntentAccessor> = stripeRepository.continuePayment(amount, request.recipientId, request.level, paymentSourceProvider.paymentSourceType)
|
||||
val continuePayment: Single<StripeIntentAccessor> = verifyUser.andThen(stripeRepository.continuePayment(amount, request.recipientId, request.level, paymentSourceProvider.paymentSourceType))
|
||||
val intentAndSource: Single<Pair<StripeIntentAccessor, StripeApi.PaymentSource>> = Single.zip(continuePayment, paymentSourceProvider.paymentSource, ::Pair)
|
||||
|
||||
disposables += intentAndSource.flatMapCompletable { (paymentIntent, paymentSource) ->
|
||||
|
|
Ładowanie…
Reference in New Issue