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
1 changed files with 29 additions and 15 deletions

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',
cents = checkout_session['display_items'][0]['amount'] created={
dollars = decimal.Decimal(cents)/100 # Check for events created in the last half hour
'gte': int(time.time() - (30 * 60)),
},
)
#consume_stripe_checkout_session deletes the checkout session row and inserts a payment row for event in checkout_session_completed_events.auto_paging_iter():
# its ok to call consume_stripe_checkout_session more than once because it only takes an action if the session exists checkout_session = event['data']['object']
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 redirect(url_for("console.account_balance")) if checkout_session and 'id' in checkout_session and checkout_session['id'] == stripe_checkout_session_id:
cents = checkout_session['display_items'][0]['amount']
dollars = decimal.Decimal(cents)/100
# I don't think the webhook is needed #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
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 redirect(url_for("console.account_balance"))
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,8 +123,10 @@ 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:
# print("/stripe/webhook returned 400: bad request", e) # print("/stripe/webhook returned 400: bad request", e)