def home_get(): """ Endpoint for the homepage """ cookie = request.cookies.get('session') if cookie is None or cookie != util.get_session_cookie(): return render_template("start.html") config = bunq.retrieve_config() bunqkeymode = config.get("mode") iftttkeyset = (util.get_ifttt_service_key("") is not None) accounts = util.get_bunq_accounts_with_permissions(config) enableexternal = util.get_external_payment_enabled() bunq_oauth = storage.get_value("bunq2IFTTT", "bunq_oauth") if bunq_oauth is not None and bunqkeymode != "APIkey": expire = arrow.get(bunq_oauth["timestamp"] + 90 * 24 * 3600) oauth_expiry = "{} ({})".format(expire.humanize(), expire.isoformat()) else: oauth_expiry = None # Google AppEngine does not provide fixed ip addresses defaultallips = (os.getenv("GAE_INSTANCE") is not None) return render_template("main.html",\ iftttkeyset=iftttkeyset, bunqkeymode=bunqkeymode, accounts=accounts,\ enableexternal=enableexternal, defaultallips=defaultallips,\ oauth_expiry=oauth_expiry)
def check_ifttt_service_key(): """ Helper method to check the IFTTT-Service-Key header """ if "IFTTT-Service-Key" not in request.headers or \ request.headers["IFTTT-Service-Key"] \ != util.get_ifttt_service_key(): return json.dumps({"errors": [{"message": "Invalid key"}]}) return None
def home_get(): """ Endpoint for the homepage """ cookie = request.cookies.get('session') if cookie is None or cookie != util.get_session_cookie(): return render_template("start.html") iftttkeyset = (util.get_ifttt_service_key() is not None) bunqkeymode = util.get_bunq_security_mode() accounts = util.get_bunq_accounts_combined() appmode = util.get_app_mode() masterurl = util.get_app_master_url() enableexternal = util.get_external_payment_enabled() # Google AppEngine does not provide fixed ip addresses defaultallips = (os.getenv("GAE_INSTANCE") is not None) return render_template("main.html",\ iftttkeyset=iftttkeyset, bunqkeymode=bunqkeymode, accounts=accounts,\ appmode=appmode, masterurl=masterurl, enableexternal=enableexternal,\ defaultallips=defaultallips)
def bunq_callback_mutation(): """ Handle bunq callbacks of type MUTATION """ try: data = request.get_json() print("[bunqcb_mutation] input: {}".format(json.dumps(data))) payment = data["NotificationUrl"]["object"]["Payment"] metaid = payment["id"] if storage.seen("seen_mutation", metaid): print("[bunqcb_mutation] duplicate transaction") return "" iban = payment["alias"]["iban"] item = { "created_at": payment["created"], "date": arrow.get(payment["created"]).format("YYYY-MM-DD"), "type": mutation_type(payment), "amount": payment["amount"]["value"], "balance": payment["balance_after_mutation"]["value"], "account": iban, "counterparty_account": counterparty_account(payment), "counterparty_name": payment["counterparty_alias"]["display_name"], "description": payment["description"], "payment_id": metaid, "meta": { "id": metaid, "timestamp": arrow.get(payment["created"]).timestamp } } print("[bunqcb_mutation] translated: {}".format(json.dumps(item))) triggerids_1 = [] triggerids_2 = [] for account in ["ANY", iban]: for trigger in storage.query("trigger_mutation", "account", "=", account): ident = trigger["identity"] if check_fields("mutation", ident, item, trigger["fields"]): triggerids_1.append(ident) storage.store("mutation_" + ident, metaid, {"value": item}) for trigger in storage.query("trigger_balance", "account", "=", account): ident = trigger["identity"] if check_fields("balance", ident, item, trigger["fields"]): if not trigger["last"]: triggerids_2.append(ident) storage.store("balance_" + ident, metaid, {"value": item}) trigger["last"] = True storage.store("trigger_balance", ident, trigger) elif trigger["last"]: trigger["last"] = False storage.store("trigger_balance", ident, trigger) print("Matched mutation triggers:", json.dumps(triggerids_1)) print("Matched balance triggers:", json.dumps(triggerids_2)) data = {"data": []} for triggerids in [triggerids_1, triggerids_2]: for triggerid in triggerids: data["data"].append({"trigger_identity": triggerid}) if data["data"]: headers = { "IFTTT-Channel-Key": util.get_ifttt_service_key(), "IFTTT-Service-Key": util.get_ifttt_service_key(), "X-Request-ID": uuid.uuid4().hex, "Content-Type": "application/json" } print("[bunqcb_mutation] to ifttt: {}".format(json.dumps(data))) res = requests.post("https://realtime.ifttt.com/v1/notifications", headers=headers, data=json.dumps(data)) print("[bunqcb_mutation] result: {} {}".format( res.status_code, res.text)) except Exception: traceback.print_exc() print("[bunqcb_mutation] ERROR during handling bunq callback") return ""
def bunq_callback_request(): """ Handle bunq callbacks of type REQUEST """ try: data = request.get_json() print("[bunqcb_request] input: {}".format(json.dumps(data))) if data["NotificationUrl"]["event_type"] != "REQUEST_RESPONSE_CREATED": print("[bunqcb_request] ignoring {} event".format( data["NotificationUrl"]["event_type"])) return "" obj = data["NotificationUrl"]["object"]["RequestResponse"] metaid = obj["id"] if storage.seen("seen_request", metaid): print("[bunqcb_request] duplicate transaction") return "" iban = obj["alias"]["iban"] item = { "created_at": obj["created"], "date": arrow.get(obj["created"]).format("YYYY-MM-DD"), "amount": obj["amount_inquired"]["value"], "account": iban, "counterparty_account": counterparty_account(obj), "counterparty_name": obj["counterparty_alias"]["display_name"], "description": obj["description"], "request_id": metaid, "meta": { "id": metaid, "timestamp": arrow.get(obj["created"]).timestamp } } print("[bunqcb_request] translated: {}".format(json.dumps(item))) triggerids = [] for account in ["ANY", iban]: for trigger in storage.query("trigger_request", "account", "=", account): ident = trigger["identity"] if check_fields("request", ident, item, trigger["fields"]): triggerids.append(ident) storage.store("request_" + ident, metaid, {"value": item}) print("[bunqcb_request] Matched triggers:", json.dumps(triggerids)) if triggerids: data = {"data": []} for triggerid in triggerids: data["data"].append({"trigger_identity": triggerid}) headers = { "IFTTT-Channel-Key": util.get_ifttt_service_key(), "IFTTT-Service-Key": util.get_ifttt_service_key(), "X-Request-ID": uuid.uuid4().hex, "Content-Type": "application/json" } print("[bunqcb_request] to ifttt: {}".format(json.dumps(data))) res = requests.post("https://realtime.ifttt.com/v1/notifications", headers=headers, data=json.dumps(data)) print("[bunqcb_request] result: {} {}".format( res.status_code, res.text)) except Exception: traceback.print_exc() print("[bunqcb_request] ERROR during handling bunq callback") return ""