fix a bug that would allow users to cheat the stripe checkout system

This commit is contained in:
forest 2020-05-14 12:41:12 -05:00
parent 58f85edcb4
commit 314b74e33b

View File

@ -1,8 +1,8 @@
import stripe import stripe
import json import json
import time
import decimal import decimal
from flask import Blueprint from flask import Blueprint
from flask import request from flask import request
from flask import current_app from flask import current_app
@ -80,23 +80,35 @@ def success():
print("/stripe/success returned 400: missing required URL parameter session_id") print("/stripe/success returned 400: missing required URL parameter session_id")
abort(400, "missing required URL parameter session_id") abort(400, "missing required URL parameter session_id")
else: else:
checkout_session = stripe.checkout.Session.retrieve(stripe_checkout_session_id) checkout_session_completed_events = stripe.Event.list(
if checkout_session and 'display_items' in checkout_session: type='checkout.session.completed',
created={
# Check for events created in the last half hour
'gte': int(time.time() - (30 * 60)),
},
)
for event in checkout_session_completed_events.auto_paging_iter():
checkout_session = event['data']['object']
if checkout_session and 'id' in checkout_session and checkout_session['id'] == stripe_checkout_session_id:
cents = checkout_session['display_items'][0]['amount'] cents = checkout_session['display_items'][0]['amount']
dollars = decimal.Decimal(cents)/100 dollars = decimal.Decimal(cents)/100
#consume_stripe_checkout_session deletes the checkout session row and inserts a payment row #consume_stripe_checkout_session deletes the checkout session row and inserts a payment row
# its ok to call consume_stripe_checkout_session more than once because it only takes an action if the session exists # its ok to call consume_stripe_checkout_session more than once because it only takes an action if the session exists
success_account = get_model().consume_stripe_checkout_session(stripe_checkout_session_id, dollars) success_account = get_model().consume_stripe_checkout_session(stripe_checkout_session_id, dollars)
if success_account: if success_account:
print(f"{success_account} paid ${dollars} successfully (stripe_checkout_session_id={stripe_checkout_session_id})") print(f"{success_account} paid ${dollars} successfully (stripe_checkout_session_id={stripe_checkout_session_id})")
return redirect(url_for("console.account_balance")) return redirect(url_for("console.account_balance"))
# I don't think the webhook is needed abort(400, "this checkout session is not paid yet")
# webhook is not needed
# @bp.route("/webhook", methods=("POST",)) # @bp.route("/webhook", methods=("POST",))
# def webhook(): # def webhook():
# request_data = json.loads(request.data) # request_data = json.loads(request.data)
# signature = request.headers.get('stripe-signature') # signature = request.headers.get('stripe-signature')
# try: # try:
@ -111,7 +123,9 @@ def success():
# #consume_stripe_checkout_session deletes the checkout session row and inserts a payment row # #consume_stripe_checkout_session deletes the checkout session row and inserts a payment row
# # its ok to call consume_stripe_checkout_session more than once because it only takes an action if the session exists # # its ok to call consume_stripe_checkout_session more than once because it only takes an action if the session exists
# get_model().consume_stripe_checkout_session(stripe_checkout_session_id, dollars) # success_account = get_model().consume_stripe_checkout_session(stripe_checkout_session_id, dollars)
# if success_account:
# print(f"{success_account} paid ${dollars} successfully (stripe_checkout_session_id={stripe_checkout_session_id})")
# return jsonify({'status': 'success'}) # return jsonify({'status': 'success'})
# except ValueError as e: # except ValueError as e: