# This file is part of GNU TALER. # Copyright (C) 2017 Taler Systems SA # # TALER is free software; you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free Software # Foundation; either version 2.1, or (at your option) any later version. # # TALER is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License along with # GNU TALER; see the file COPYING. If not, see # # @author Marcello Stanisci import os import base64 import logging import json from urllib.parse import urljoin import flask import requests from ..talerconfig import TalerConfig from .amount import Amount BASE_DIR = os.path.dirname(os.path.abspath(__file__)) app = flask.Flask(__name__, template_folder=BASE_DIR) app.debug = True app.secret_key = base64.b64encode(os.urandom(64)).decode('utf-8') TC = TalerConfig.from_env() BACKEND_URL = TC["frontends"]["backend"].value_string(required=True) CURRENCY = TC["taler"]["currency"].value_string(required=True) app.config.from_object(__name__) LOGGER = logging.getLogger(__name__) def backend_error(requests_response): LOGGER.error("Backend error: status code: " + str(requests_response.status_code)) try: return flask.jsonify(requests_response.json()), requests_response.status_code except json.decoder.JSONDecodeError: LOGGER.error("Backend error (NO JSON returned): status code: " + str(requests_response.status_code)) return flask.jsonify(dict(error="Backend died, no JSON got from it")), 502 @app.context_processor def utility_processor(): def join_urlparts(*parts): ret = "" part = 0 while part < len(parts): buf = parts[part] part += 1 if ret.endswith("/"): buf = buf.lstrip("/") elif ret and not buf.startswith("/"): buf = "/" + buf ret += buf return ret def url(my_url): return join_urlparts(flask.request.script_root, my_url) def env(name, default=None): return os.environ.get(name, default) return dict(url=url, env=env) @app.route("/tip-pickup", methods=["POST"]) def pick(): body = flask.request.get_json() resp = requests.post(urljoin(BACKEND_URL, 'tip-pickup'), json=body) if resp.status_code != 200: return backend_error(resp) return flask.jsonify(resp.json()) @app.route("/submit-survey", methods=["POST"]) def submit_survey(): tip_spec = dict(pickup_url=urljoin(flask.request.base_url, "/tip-pickup"), amount=Amount(CURRENCY, 1).dump(), instance="default", justification="Payment methods survey") resp = requests.post(urljoin(BACKEND_URL, 'tip-authorize'), json=tip_spec) if resp.status_code != 200: return backend_error(resp) response = flask.make_response( flask.render_template("templates/wait.html", success=True), 402) response.headers["X-Taler-Tip"] = resp.json()["tip_token"] return response @app.route("/", methods=["GET"]) def survey(): return flask.render_template("templates/index.html", merchant_currency=CURRENCY)