verify PayPal IPN key

pull/2029/merge
Thibault Duplessis 2016-07-14 23:11:42 +02:00
parent 8908e43ffc
commit c69e6d87bf
5 changed files with 52 additions and 42 deletions

View File

@ -111,7 +111,8 @@ object Plan extends LilaController {
cents = lila.plan.Cents(ipn.grossCents),
name = ipn.name,
txnId = ipn.txnId,
ip = lila.common.HTTPRequest.lastRemoteAddress(req)
ip = lila.common.HTTPRequest.lastRemoteAddress(req),
key = lila.plan.PayPalIpnKey(get("key", req) | "N/A")
) inject Ok
)
}

View File

@ -100,10 +100,6 @@ qa {
answer = qa_answer
}
}
donation {
collection.donation = donation
weekly_goal = 30400
}
chat {
collection {
chat = chat
@ -607,6 +603,9 @@ plan {
secret="sk_test_erAQMvv5cF90WXUFlkv7Tke0"
}
}
paypal {
ipn_key=""
}
collection {
patron = plan_patron
charge = plan_charge

View File

@ -1,8 +1,8 @@
package lila.plan
import scala.concurrent.duration._
import akka.actor._
import com.typesafe.config.Config
import scala.concurrent.duration._
import lila.common.PimpedConfig._
@ -36,7 +36,8 @@ final class Env(
patronColl = patronColl,
chargeColl = db(CollectionCharge),
notifier = notifier,
bus)
bus,
payPalIpnKey = PayPalIpnKey(config getString "paypal.ipn_key"))
private lazy val webhookHandler = new WebhookHandler(api)

View File

@ -11,7 +11,8 @@ final class PlanApi(
patronColl: Coll,
chargeColl: Coll,
notifier: PlanNotifier,
bus: lila.common.Bus) {
bus: lila.common.Bus,
payPalIpnKey: PayPalIpnKey) {
import BsonHandlers._
import PatronHandlers._
@ -89,43 +90,49 @@ final class PlanApi(
cents: Cents,
name: Option[String],
txnId: Option[String],
ip: String): Funit = (cents.value >= 100) ?? {
chargeColl.insert(Charge.make(
userId = userId,
payPal = Charge.PayPal(
name = name,
email = email.map(_.value),
txnId = txnId,
subId = subId.map(_.value),
ip = ip.some).some,
cents = cents)) >>
(userId ?? UserRepo.named) flatMap {
_ ?? { user =>
val payPal = Patron.PayPal(email, subId, DateTime.now)
userPatron(user).flatMap {
case None => patronColl.insert(Patron(
_id = Patron.UserId(user.id),
payPal = payPal.some,
lastLevelUp = DateTime.now
).expireInOneMonth) >>
UserRepo.setPlan(user, lila.user.Plan.start) >>
notifier.onStart(user)
case Some(patron) =>
val p2 = patron.copy(
payPal = payPal.some
).levelUpIfPossible.expireInOneMonth
patronColl.update($id(patron.id), p2) >>
UserRepo.setPlan(user,
if (patron.canLevelUp) user.plan.incMonths
else user.plan.enable)
} >>- {
logger.info(s"Charged ${user.username} with paypal: $cents")
lila.mon.plan.amount(cents.value)
ip: String,
key: PayPalIpnKey): Funit =
if (key != payPalIpnKey) {
logger.error(s"Invalid PayPal IPN key $key from $ip $userId $cents")
funit
}
else (cents.value >= 100) ?? {
chargeColl.insert(Charge.make(
userId = userId,
payPal = Charge.PayPal(
name = name,
email = email.map(_.value),
txnId = txnId,
subId = subId.map(_.value),
ip = ip.some).some,
cents = cents)) >>
(userId ?? UserRepo.named) flatMap {
_ ?? { user =>
val payPal = Patron.PayPal(email, subId, DateTime.now)
userPatron(user).flatMap {
case None => patronColl.insert(Patron(
_id = Patron.UserId(user.id),
payPal = payPal.some,
lastLevelUp = DateTime.now
).expireInOneMonth) >>
UserRepo.setPlan(user, lila.user.Plan.start) >>
notifier.onStart(user)
case Some(patron) =>
val p2 = patron.copy(
payPal = payPal.some
).levelUpIfPossible.expireInOneMonth
patronColl.update($id(patron.id), p2) >>
UserRepo.setPlan(user,
if (patron.canLevelUp) user.plan.incMonths
else user.plan.enable)
} >>- {
logger.info(s"Charged ${user.username} with paypal: $cents")
lila.mon.plan.amount(cents.value)
}
}
}
}
}
}
def onSubscriptionDeleted(sub: StripeSubscription): Funit =
customerIdPatron(sub.customer) flatMap {

View File

@ -2,6 +2,8 @@ package lila.plan
import org.joda.time.DateTime
case class PayPalIpnKey(value: String) extends AnyVal
case class CustomerId(value: String) extends AnyVal
case class ChargeId(value: String) extends AnyVal