gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-blog] branch master updated: use upcoming backend AP


From: gnunet
Subject: [GNUnet-SVN] [taler-blog] branch master updated: use upcoming backend API
Date: Fri, 05 Jan 2018 12:00:55 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository blog.

The following commit(s) were added to refs/heads/master by this push:
     new 58be785  use upcoming backend API
58be785 is described below

commit 58be785e4181b403f2d74ce7e92cde2784aae455
Author: Florian Dold <address@hidden>
AuthorDate: Fri Jan 5 12:00:50 2018 +0100

    use upcoming backend API
---
 talerblog/blog/blog.py | 135 ++++++++++++++++++++-----------------------------
 1 file changed, 56 insertions(+), 79 deletions(-)

diff --git a/talerblog/blog/blog.py b/talerblog/blog/blog.py
index f5677d8..8cb5763 100644
--- a/talerblog/blog/blog.py
+++ b/talerblog/blog/blog.py
@@ -23,6 +23,7 @@ Implement URL handlers and payment logic for the blog 
merchant.
 from urllib.parse import urljoin, quote, parse_qsl
 import logging
 import os
+import uuid
 import base64
 import requests
 import flask
@@ -33,6 +34,7 @@ from ..helpers import (make_url, \
 from ..blog.content import (ARTICLES, \
     get_article_file, get_image_file)
 
+
 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
 app = flask.Flask(__name__, template_folder=BASE_DIR)
 app.debug = True
@@ -47,6 +49,7 @@ ARTICLE_AMOUNT = dict(value=0, fraction=50000000, 
currency=CURRENCY)
 
 app.config.from_object(__name__)
 
+
 @app.context_processor
 def utility_processor():
     def url(my_url):
@@ -55,48 +58,40 @@ def utility_processor():
         return os.environ.get(name, default)
     return dict(url=url, env=env)
 
+
 @app.route("/")
 def index():
     return flask.render_template("templates/index.html",
                                  merchant_currency=CURRENCY,
                                  articles=ARTICLES.values())
 
+
 @app.route("/javascript")
 def javascript_licensing():
     return flask.render_template("templates/javascript.html")
 
+
 # Triggers the refund by serving /refund/test?order_id=XY.
 # Will be triggered by a "refund button".
address@hidden("/refund", methods=["GET", "POST"])
address@hidden("/refund", methods=["POST"])
 def refund():
-    if flask.request.method == "POST":
-        payed_articles = flask.session["payed_articles"] = 
flask.session.get("payed_articles", {})
-        article_name = flask.request.form.get("article_name")
-        LOGGER.info("Looking for article '%s' to refund" % article_name)
-        order_id = payed_articles.get(article_name)
-        if not order_id:
-            return flask.jsonify(dict(error="Aborting refund: article not 
payed")), 401
-        resp = requests.post(urljoin(BACKEND_URL, "refund"),
-                             json=dict(order_id=order_id,
-                                       refund=ARTICLE_AMOUNT,
-                                       reason="Demo reimbursement",
-                                       instance=INSTANCE))
-        if resp.status_code != 200:
-            return backend_error(resp)
-        payed_articles[article_name] = "__refunded"
-        response = flask.make_response()
-        response.headers["X-Taler-Refund-Url"] = make_url("/refund", 
("order_id", order_id))
-        return response, 402
-
-    order_id = expect_parameter("order_id", False)
+    article_name = flask.request.form.get("article_name")
+    if not article_name:
+        return flask.jsonify(dict(error="No article_name found in form")), 400
+    LOGGER.info("Looking for %s to refund" % article_name)
+    order_id = payed_articles.get(article_name)
     if not order_id:
-        LOGGER.error("Missing parameter 'order_id'")
-        return flask.jsonify(dict(error="Missing parameter 'order_id'")), 400
-    resp = requests.get(urljoin(BACKEND_URL, "refund"),
-                        params=dict(order_id=order_id, instance=INSTANCE))
+        return flask.jsonify(dict(error="Aborting refund: article not 
payed")), 401
+    resp = requests.post(urljoin(BACKEND_URL, "refund"),
+                         json=dict(order_id=order_id,
+                                   refund=ARTICLE_AMOUNT,
+                                   reason="Demo reimbursement",
+                                   instance=INSTANCE))
     if resp.status_code != 200:
         return backend_error(resp)
-    return flask.jsonify(resp.json()), resp.status_code
+    if pay_status.get("refund_redirect_url"):
+        return flask.redirect(pay_status["refund_redirect_url"])
+    flask.abort(500)
 
 
 @app.route("/generate-contract", methods=["GET"])
@@ -134,24 +129,46 @@ def generate_contract():
     return flask.jsonify(**proposal_resp)
 
 
address@hidden("/cc-payment/<name>")
-def cc_payment(name):
-    return flask.render_template("templates/cc-payment.html",
-                                 article_name=name)
-
 
 @app.route("/essay/<name>")
 @app.route("/essay/<name>/data/<data>")
 def article(name, data=None):
-    LOGGER.info("processing %s" % name)
-    payed_articles = flask.session.get("payed_articles", {})
 
-    if payed_articles.get(name, "") == "__refunded":
+    # We use an explicit session ID so that each payment (or payment replay) is
+    # bound to a browser.  This forces re-play and prevents sharing the article
+    # by just sharing the URL.
+    session_id = flask.session.get("uid")
+    if not session_id:
+        session_id = flask.session["uid"] = uuid.uuid4()
+
+    pay_params = dict(
+        instance=INSTANCE,
+        contract_url=make_url("/generate-contract", ("article_name", name)),
+        session_id=session_id,
+        session_sig=requests.args.get("session_sig"),
+        order_id=requests.args.get("order_id"),
+        # URL that the browser will navigate to after the user has paid (or
+        # proved they already paid) with this session
+        confirm_url = make_url("/essay/" + name,
+                               ("order_id", "${order_id}"),
+                               ("session_sig", "${session_sig}"))
+    )
+
+    resp = requests.get(urljoin(BACKEND_URL, "check-payment"), 
params=pay_params)
+    if resp.status_code != 200:
+        return backend_error(resp)
+
+    pay_status = resp.json()
+
+    if pay_status.get("payment_redirect_url"):
+        return flask.redirect(pay_status["payment_redirect_url"])
+
+    if pay_status.get("refunded"):
         return flask.render_template("templates/article_refunded.html", 
article_name=name)
 
-    if name in payed_articles:
-        article_info = ARTICLES[name]
-        if article_info is None:
+    if pay_status.get("paid"):
+        articleInfo = ARTICLES[name]
+        if articleInfo is None:
             flask.abort(500)
         if data is not None:
             if data in article_info.extra_files:
@@ -161,45 +178,5 @@ def article(name, data=None):
                                      
article_file=get_article_file(article_info),
                                      article_name=name)
 
-    contract_url = make_url("/generate-contract",
-                            ("article_name", name))
-    response = flask.make_response(
-        flask.render_template("templates/fallback.html"), 402)
-    response.headers["X-Taler-Contract-Url"] = contract_url
-    response.headers["X-Taler-Contract-Query"] = "fulfillment_url"
-    # Useless (?) header, as X-Taler-Contract-Url takes always (?) precedence
-    # over X-Offer-Url.  This one might only be useful if the contract 
retrieval
-    # goes wrong.
-    response.headers["X-Taler-Offer-Url"] = make_url("/essay/" + quote(name))
-    return response
-
-
address@hidden("/pay", methods=["POST"])
-def pay():
-    deposit_permission = flask.request.get_json()
-    if deposit_permission is None:
-        return flask.jsonify(error="no json in body"), 400
-    resp = requests.post(urljoin(BACKEND_URL, "pay"),
-                         json=deposit_permission)
-    if resp.status_code != 200:
-        return backend_error(resp)
-    proposal_data = resp.json()["contract_terms"]
-    article_name = proposal_data["extra"]["article_name"]
-    payed_articles = flask.session["payed_articles"] = 
flask.session.get("payed_articles", {})
-
-    try:
-        resp.json()["refund_permissions"].pop()
-        # we had some refunds on the article purchase already!
-        LOGGER.info("Article %s was refunded, before /pay" % article_name)
-        payed_articles[article_name] = "__refunded"
-        return flask.jsonify(resp.json()), 200
-    except IndexError:
-        pass
-
-    if not deposit_permission["order_id"]:
-        LOGGER.error("order_id missing from deposit_permission!")
-        return flask.jsonify(dict(error="internal error: ask for refund!")), 
500
-    if article_name not in payed_articles:
-        LOGGER.info("Article %s goes in state" % article_name)
-        payed_articles[article_name] = deposit_permission["order_id"]
-    return flask.jsonify(resp.json()), 200
+    # no pay_redirect but article not paid, this should never happen!
+    flask.abort(500)

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]