diff options
author | Florian Dold <florian.dold@gmail.com> | 2020-01-17 15:35:20 +0100 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2020-01-17 15:35:20 +0100 |
commit | 5d465f9184be37686080394bb68708fb40835e72 (patch) | |
tree | fad16fe417dac10775e6d411673a113e6b5f6ab2 /talerbank/app/views.py | |
parent | 1250877d0c0744dbfa46e940af80a12ee7aaf2fe (diff) | |
download | bank-5d465f9184be37686080394bb68708fb40835e72.tar.gz bank-5d465f9184be37686080394bb68708fb40835e72.tar.bz2 bank-5d465f9184be37686080394bb68708fb40835e72.zip |
implement new APIs
Diffstat (limited to 'talerbank/app/views.py')
-rw-r--r-- | talerbank/app/views.py | 186 |
1 files changed, 182 insertions, 4 deletions
diff --git a/talerbank/app/views.py b/talerbank/app/views.py index 22cf62f..74219ef 100644 --- a/talerbank/app/views.py +++ b/talerbank/app/views.py @@ -25,6 +25,7 @@ import logging import hashlib import random import re +import time import base64 from urllib.parse import urlparse import django.contrib.auth @@ -723,16 +724,193 @@ def serve_history(request, user_account): return JsonResponse(dict(data=history), status=200) +def expect_json_body_str(request, param_name): + body = json.loads(request.body) # FIXME: cache! + val = body[param_name] + if not isinstance(val, str): + # FIXME: throw right exception to be handled by middleware + raise Exception(f"expected string for {param_name}") + return val + +def expect_json_body_amount(request, param_name): + body = json.loads(request.body) # FIXME: cache! + val = body[param_name] + if not isinstance(val, str): + # FIXME: throw right exception to be handled by middleware + raise Exception(f"expected string for {param_name}") + return Amount.parse(val) + +def expect_param_str(request, param_name): + val = request.GET[param_name] + if not isinstance(val, str): + # FIXME: throw right exception to be handled by middleware + raise Exception(f"expected string for {param_name}") + return val + + +def expect_param_amount(request, param_name): + val = request.GET[param_name] + if not isinstance(val, str): + # FIXME: throw right exception to be handled by middleware + raise Exception(f"expected string for {param_name}") + return Amount.parse(val) + + +@require_GET +def twg_base(request, acct_id): + """ + This endpoint is used by the exchange test cases to + check if the account is up, should not normally be used + for anything else. + """ + return JsonResponse(dict(), status=200) + + +@csrf_exempt +@require_POST +@login_via_headers +def twg_add_incoming(request, user_account, acct_id): + """ + Transfer money from a user's bank account to the exchange + for testing purposes. + """ + exchange_account = user_account.bankaccount + + if acct_id != user_account.username: + # FIXME: respond nicely + raise Exception(f"credentials do not match URL ('{acct_id}' vs '{user_account.username}')") + + reserve_pub = expect_json_body_str(request, "reserve_pub") + debit_account_payto = expect_json_body_str(request, "debit_account") + amount = expect_json_body_amount(request, "amount") + + debit_account_name = get_acct_from_payto(debit_account_payto) + print(f"adding incoming balance to exchange ({acct_id}) from account {debit_account_payto} ({debit_account_name})") + debit_user = User.objects.get(username=debit_account_name) + debit_account = BankAccount.objects.get(user=debit_user) + subject = f"{reserve_pub}" + + wtrans = wire_transfer( + amount, + debit_account, + exchange_account, + subject, + ) + + return JsonResponse( + { + "row_id": wtrans.id, + "timestamp": dict(t_ms=(int(wtrans.date.timestamp()) * 1000)), + } + ) + + +@csrf_exempt +@require_POST +@login_via_headers +def twg_transfer(request, user_account, acct_id): + """ + Transfer money from the exchange to a merchant account. + """ + + exchange_account = user_account.bankaccount + + exchange_account = user_account.bankaccount + + if acct_id != user_account.username: + # FIXME: respond nicely + raise Exception(f"credentials do not match URL ('{acct_id}' vs '{user_account.username}')") + + request_uid = expect_json_body_str(request, "request_uid") + wtid = expect_json_body_str(request, "wtid") + amount = expect_json_body_amount(request, "amount") + exchange_base_url = expect_json_body_str(request, "exchange_base_url") + credit_account_payto = expect_json_body_str(request, "credit_account") + + credit_account_name = get_acct_from_payto(credit_account_payto) + credit_user = User.objects.get(username=credit_account_name) + credit_account = BankAccount.objects.get(user=credit_user) + + subject = f"{wtid}\n{exchange_base_url}" + + wtrans = wire_transfer( + amount, + exchange_account, + credit_account, + subject, + ) + + return JsonResponse( + { + "row_id": wtrans.id, + "timestamp": dict(t_ms=(int(wtrans.date.timestamp()) * 1000)), + } + ) + + +def get_payto_from_account(request, acct): + h = request.META['HTTP_HOST'] + # remove port + h = h.split(":")[0] + return f"payto://x-taler-bank/{h}/{acct.user.username}" @require_GET @login_via_headers -def twg_history_incoming(request, user_account): - pass +def twg_history_incoming(request, user_account, acct_id): + history = [] + delta = int(request.GET["delta"]) + start_str = request.GET.get("start") + if start_str is None: + start = None + else: + start = int(start_str) + qs = query_history( + user_account.bankaccount, + "credit", + delta, + start, + ) + for item in qs: + history.append(dict( + row_id=item.id, + amount=item.amount.stringify(settings.TALER_DIGITS), + date=dict(t_ms=(int(item.date.timestamp()) * 1000)), + reserve_pub=item.subject, # fixme: parse/truncate? + credit_account=get_payto_from_account(request, item.credit_account), + debit_account=get_payto_from_account(request, item.debit_account), + )) + return JsonResponse(dict(incoming_transactions=history), status=200) + @require_GET @login_via_headers -def twg_history_outgoing(request, user_account): - pass +def twg_history_outgoing(request, user_account, acct_id): + history = [] + delta = int(request.GET["delta"]) + start_str = request.GET.get("start") + if start_str is None: + start = None + else: + start = int(start_str) + qs = query_history( + user_account.bankaccount, + "debit", + delta, + start, + ) + for item in qs: + # FIXME: proper parsing, more structure in subject + wtid, exchange_base_url = item.subject.splitlines() + history.append(dict( + row_id=item.id, + amount=item.amount.stringify(settings.TALER_DIGITS), + date=dict(t_ms=(int(item.date.timestamp()) * 1000)), + wtid=wtid, + exchange_base_url=exchange_base_url, + credit_account=get_payto_from_account(request, item.credit_account), + debit_account=get_payto_from_account(request, item.debit_account), + )) + return JsonResponse(dict(outgoing_transactions=history), status=200) ## |