From 162d7437d6b894f1ee6874105535b8e3e7b83164 Mon Sep 17 00:00:00 2001 From: Matt Arcidy Date: Sun, 4 Aug 2019 08:22:00 -0700 Subject: [PATCH] nonces everywhere noncing the thing with xhr and stuff...still not really that obfuscated cleanup of logging and debug stuff --- donate/app.py | 7 ++- donate/models.py | 2 +- donate/routes.py | 90 +++++++++++++++++++++++++++---------- donate/static/js/helper.js | 19 ++++++++ donate/templates/base.html | 2 +- donate/templates/main.html | 3 +- donate/templates/nonce.html | 3 ++ 7 files changed, 95 insertions(+), 31 deletions(-) create mode 100644 donate/static/js/helper.js create mode 100644 donate/templates/nonce.html diff --git a/donate/app.py b/donate/app.py index 4ca4d78..df3549a 100644 --- a/donate/app.py +++ b/donate/app.py @@ -1,4 +1,3 @@ -import os from flask import Flask, Response import prometheus_client from donate.extensions import db, migrate @@ -7,8 +6,6 @@ Account, Currency, Project, - StripeDonation, - StripePlan, Transaction, User, ) @@ -33,7 +30,8 @@ def create_app(config_object=ProdConfig): # Handle metrics requests. @app.route("/metrics") def metrics(): - return Response(prometheus_client.generate_latest(), mimetype=prometheus_client.CONTENT_TYPE_LATEST) + return Response(prometheus_client.generate_latest(), + mimetype=prometheus_client.CONTENT_TYPE_LATEST) return(app) @@ -51,6 +49,7 @@ def register_blueprints(app): app.register_blueprint(routes.new_project_page) app.register_blueprint(routes.thanks_page) app.register_blueprint(routes.donation_charges) + app.register_blueprint(routes.nonce_page) def register_shellcontext(app): diff --git a/donate/models.py b/donate/models.py index 54a7dae..e0502b4 100644 --- a/donate/models.py +++ b/donate/models.py @@ -290,6 +290,6 @@ class DonateConfiguration(db.Model, TimestampMixin): __tablename__ = 'donate_configuration' id = db.Column(db.Integer, primary_key=True) - key = db.Column(db.String(32), nullable=False, unique=True) + key = db.Column(db.String(64), nullable=False, unique=True) type = db.Column(db.String(10), nullable=False) value = db.Column(db.String(32), nullable=False) diff --git a/donate/routes.py b/donate/routes.py index afdaaf1..15bddae 100644 --- a/donate/routes.py +++ b/donate/routes.py @@ -1,24 +1,23 @@ -import os -import git -import json +import random +import string +from datetime import datetime from flask import ( current_app as app, flash, + make_response, redirect, render_template, request, - url_for, Blueprint, ) from sqlalchemy.orm.exc import ( NoResultFound, - MultipleResultsFound, ) from donate.util import get_one from donate.database import db from donate.models import ( Account, - Donation, + DonateConfiguration, Project, Currency, Transaction, @@ -28,14 +27,11 @@ ) from donate.vendor.stripe import ( create_charge, - get_customer ) - -import stripe from stripe import error as se -#FIXME: git_sha = git.Repo(search_parent_directories=True).head.object.hexsha -git_sha="whatever" +# FIXME: git_sha = git.Repo(search_parent_directories=True).head.object.hexsha +git_sha = "whatever" repo_path = "https://github.com/noisebridge/python-nb-donate/tree/" donation_page = Blueprint('donation', __name__, template_folder="templates") @@ -49,6 +45,49 @@ __name__, template_folder="templates") donation_charges = Blueprint('new_charge', __name__, template_folder="templates") +nonce_page = Blueprint('denonce', __name__, template_folder="templates") + + +def create_nonce(): + nonce = ''.join(random.choice(string.ascii_letters + string.digits) + for n in range(256)) + db.session.add(DonateConfiguration(key=nonce, type="nonce", value="true")) + db.session.commit() + return nonce + + +def consume_nonce(nonce): + + nonces = db.session.query(DonateConfiguration).filter_by( + key=nonce, + type="nonce", + value="true").all() + + if len(nonces) == 0: + return None + + if len(nonces) == 1: + nonce = nonces[0] + if (datetime.now() - nonce.created_at).total_seconds() <= 60: + key = app.get_stripe_key('PUBLIC') + for nonce in nonces: + db.session.delete(nonce) + db.session.commit() + return key + + if len(nonces) > 1: + for nonce in nonces: + db.session.delete(nonce) + db.session.commit() + return None + + +@nonce_page.route('/nonce/', methods=['GET']) +def denonce(nonce): + data = {'value': consume_nonce(nonce)} + resp = make_response(render_template('nonce.html', data=data)) + resp.headers['Content-type'] = 'application/json' + return resp def get_donation_params(form): @@ -158,7 +197,7 @@ def donation(): app.logger.error("CardError: {}".format(error)) flash(msg) return redirect('/index#form') - except se.RateLimitError as error: + except se.RateLimitError: app.logger.warning("RateLimitError hit!") flash("Rate limit hit, please try again in a few seconds") return redirect('/index#form') @@ -189,14 +228,14 @@ def donation(): except NoResultFound: app.logger.debug("Creating plan {}".format(plan_name)) stripe_plan = StripePlan(name=plan_name, - amount=amt, - interval="M", - desc="{}/{}".format(amt, "M")) - stripe_plan.subscriptions=[stripe_sub] + amount=amt, + interval="M", + desc="{}/{}".format(amt, "M")) + stripe_plan.subscriptions = [stripe_sub] try: stripe_plan except NameError: - app.logging.error("Something went horribly wrong with StripePlan") + app.logger.error("Something went horribly wrong with StripePlan") app.logger.debug("Adding Subscription to " "plan {} for user {}" @@ -214,11 +253,13 @@ def donation(): app.logger.debug("Creating Transaction") tx = model_stripe_data(req_data=params) - app.logger.debug("Creating StripeDonation - anon: {}, card_id: {}, " - "charge_id: {}, email: {}".format(params['anonymous'], - params['stripe_token'], - charge_data['charge_id'], - charge_data['customer_id'])) + app.logger.debug( + "Creating StripeDonation - anon: {}, card_id: {}, " + "charge_id: {}, email: {}".format( + params['anonymous'], + params['stripe_token'], + charge_data['charge_id'], + charge_data['customer_id'])) sd = StripeDonation( anonymous=params['anonymous'], card_id=params['stripe_token'], @@ -250,7 +291,8 @@ def index(): # donations = db.session.query(Donation).limit(10) donations = [] - STRIPE_KEY = app.get_stripe_key('PUBLIC') + + nonce = create_nonce() return render_template('main.html', data={ @@ -258,7 +300,7 @@ def index(): 'repo_path': repo_path, 'recent_donations': donations, 'projects': sorted_projects, - 'stripe_pk': STRIPE_KEY + 'nonce': nonce }) diff --git a/donate/static/js/helper.js b/donate/static/js/helper.js new file mode 100644 index 0000000..ea977f2 --- /dev/null +++ b/donate/static/js/helper.js @@ -0,0 +1,19 @@ + + +function donateHttpGetAsync(value, cback) +{ + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + cback(this); + } + } + xhttp.open("GET", "nonce/"+value, true); + xhttp.send(); +} + +function initStripe(xhttp) { + // var data = document.getElementById('special-thing'); + var data = JSON.parse(xhttp.responseText); + stripe = Stripe.setPublishableKey(data); +} diff --git a/donate/templates/base.html b/donate/templates/base.html index c4dd375..84d1c6e 100644 --- a/donate/templates/base.html +++ b/donate/templates/base.html @@ -27,6 +27,7 @@ {% block head_css_page %}{% endblock head_css_page %} {% endblock head_css %} {% block head_script_section %} + - diff --git a/donate/templates/main.html b/donate/templates/main.html index ffe04a0..f04e046 100644 --- a/donate/templates/main.html +++ b/donate/templates/main.html @@ -2,7 +2,8 @@ {% block head_script_section %} {{ super() }} {% endblock %} {% block content %} diff --git a/donate/templates/nonce.html b/donate/templates/nonce.html new file mode 100644 index 0000000..0ec6187 --- /dev/null +++ b/donate/templates/nonce.html @@ -0,0 +1,3 @@ +{% block content %} +{{ data.value | tojson }} +{% endblock %}