Example #1
0
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)
Example #2
0
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
Example #3
0
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)
Example #4
0
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 ""
Example #5
0
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 ""