def set_bunq_oauth_response(): """ Handles the bunq OAuth redirect """ try: code = request.args["code"] if len(code) != 64: print("Invalid code: ", code) return render_template("message.html", msgtype="danger", msg=\ 'Invalid code! <br><br>'\ '<a href="/">Click here to try again</a>') url = "https://api.oauth.bunq.com/v1/token?grant_type="\ "authorization_code&code={}&redirect_uri={}"\ "&client_id={}&client_secret={}"\ .format(code, request.url_root + "auth", storage.retrieve("config", "bunq_client_id")["value"], storage.retrieve("config", "bunq_client_secret")["value"] ) req = requests.post(url) key = req.json()["access_token"] allips = storage.retrieve("config", "bunq_allips")["value"] bunq.install(key, allips=allips) util.save_bunq_security_mode("OAuth") util.save_app_mode("master") util.retrieve_and_save_bunq_userid() util.update_bunq_accounts() return render_template("message.html", msgtype="success", msg=\ 'OAuth successfully setup <br><br>'\ '<a href="/">Click here to return home</a>') except Exception: traceback.print_exc() return render_template("message.html", msgtype="danger", msg=\ 'An unknown exception occurred. See the logs. <br><br>'\ '<a href="/">Click here to return home</a>')
def update_accounts(): """ Endpoint to update the list of bunq accounts """ cookie = request.cookies.get('session') if cookie is None or cookie != util.get_session_cookie(): return render_template("message.html", msgtype="danger", msg=\ "Invalid request: session cookie not set or not valid") util.update_bunq_accounts() return render_template("message.html", msgtype="success", msg=\ 'Account update completed<br><br>'\ '<a href="/">Click here to return home</a>')
def set_bunq_oauth_api_key(): """ Handles bunq OAuth id/secret submission or API key submission """ try: key = request.form["bunqkey"] allips = False if "allips" in request.form and request.form["allips"] == 'on': allips = True print("allips:", allips) tokens = re.split("[:, \r\n\t]+", key.strip()) if len(tokens) == 6 and len(tokens[2]) == 64 and len(tokens[5]) == 64: # OAuth client id/secret submitted storage.store("config", "bunq_client_id", {"value": tokens[2]}) storage.store("config", "bunq_client_secret", {"value": tokens[5]}) storage.store("config", "bunq_allips", {"value": allips}) redirect_url = request.url_root + "auth" url = "https://oauth.bunq.com/auth?response_type=code"\ "&client_id=" + tokens[2] + \ "&redirect_uri=" + redirect_url return render_template("message.html", msgtype="primary", msg=\ "Make sure the following URL is included as a redirect url:"\ "<br><br><b>" + redirect_url + "</b><br><br>"\ 'Then click <a href="' + url + '">this link</a>') if len(tokens) == 1 and len(tokens[0]) == 64: # API key submitted try: bunq.install(key, allips=allips) util.save_bunq_security_mode("API key") util.retrieve_and_save_bunq_userid() util.update_bunq_accounts() return render_template("message.html", msgtype="success", msg=\ 'API key successfully installed <br><br>'\ '<a href="/">Click here to return home</a>') except Exception: traceback.print_exc() return render_template("message.html", msgtype="danger", msg=\ 'An exception occurred while installing the API key. '\ 'See the logs. <br><br>'\ '<a href="/">Click here to try again</a>') print("Invalid key: ", key) return render_template("message.html", msgtype="danger", msg=\ 'No valid API key or OAuth client id/secret found!<br><br>'\ '<a href="/">Click here to return home</a>') except Exception: traceback.print_exc() return render_template("message.html", msgtype="danger", msg=\ 'An unknown exception occurred. See the logs. <br><br>'\ '<a href="/">Click here to return home</a>')
def ifttt_bunq_topup(internal, draft): """ Execute a topup, internal payment """ util.update_bunq_accounts() config = bunq.retrieve_config() data = request.get_json() print("[action_payment] input: {}".format(json.dumps(data))) errmsg = None if not internal and not draft and not util.get_external_payment_enabled(): errmsg = "external payments disabled" if "actionFields" not in data: errmsg = "missing actionFields" if errmsg: print("[action_payment] ERROR: " + errmsg) return json.dumps({"errors": [{"status": "SKIP", "message": errmsg}]})\ , 400 # get the payment message fields = data["actionFields"] # get the target account balance for acc in config["accounts"]: if acc["iban"] == fields["target_account"]: balance = acc["balance"] # check balance and amount try: fields["amount"] = float(fields["amount"]) - float(balance) except ValueError: errmsg = f"Invalid amount: {fields['amount']} or balance: {balance}" print("[action_payment] ERROR: " + errmsg) return {"errors": [{"status": "SKIP", "message": errmsg}]} msg = create_payment_message(internal, fields, config) if "errors" in msg or "data" in msg: # error or test payment return json.dumps(msg), 400 if "errors" in msg else 200 # find the source account id source_accid, enabled = check_source_account(internal, draft, config, fields["source_account"]) if source_accid is None: errmsg = "unknown source account: " + fields["source_account"] if not enabled: errmsg = "Payment type not enabled for account: "+\ fields["source_account"] if errmsg: print("[action_payment] ERROR: " + errmsg) return json.dumps({"errors": [{"status": "SKIP", "message": errmsg}]})\ , 400 # execute the payment if draft: msg = {"number_of_required_accepts": 1, "entries": [msg]} result = bunq.post( "v1/user/{}/monetary-account/{}/draft-payment".format( config["user_id"], source_accid), msg) else: result = bunq.post( "v1/user/{}/monetary-account/{}/payment".format( config["user_id"], source_accid), msg) print(result) if "Error" in result: return json.dumps({ "errors": [{ "status": "SKIP", "message": result["Error"][0]["error_description"] }] }), 400 return json.dumps( {"data": [{ "id": str(result["Response"][0]["Id"]["id"]) }]})