summaryrefslogtreecommitdiff
path: root/talerbank/app/views.py
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2020-01-17 15:35:20 +0100
committerFlorian Dold <florian.dold@gmail.com>2020-01-17 15:35:20 +0100
commit5d465f9184be37686080394bb68708fb40835e72 (patch)
treefad16fe417dac10775e6d411673a113e6b5f6ab2 /talerbank/app/views.py
parent1250877d0c0744dbfa46e940af80a12ee7aaf2fe (diff)
downloadbank-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.py186
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)
##