diff options
author | Florian Dold <florian.dold@gmail.com> | 2020-01-18 16:36:25 +0100 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2020-01-18 16:36:25 +0100 |
commit | 8bad829f155590706b581528d46db249e94b9d18 (patch) | |
tree | 8dc376ae9e91449a7614288ebc90e9d4665ffb12 /talerbank | |
parent | 4804a61c6fa6ec930435b4781873e79e77c9d0ee (diff) | |
download | bank-8bad829f155590706b581528d46db249e94b9d18.tar.gz bank-8bad829f155590706b581528d46db249e94b9d18.tar.bz2 bank-8bad829f155590706b581528d46db249e94b9d18.zip |
remove old add_incoming, test the new one
Diffstat (limited to 'talerbank')
-rw-r--r-- | talerbank/app/management/commands/wire_transfer.py | 13 | ||||
-rw-r--r-- | talerbank/app/tests.py | 88 | ||||
-rw-r--r-- | talerbank/app/urls.py | 1 | ||||
-rw-r--r-- | talerbank/app/views.py | 121 |
4 files changed, 40 insertions, 183 deletions
diff --git a/talerbank/app/management/commands/wire_transfer.py b/talerbank/app/management/commands/wire_transfer.py index 08372ac..adf5186 100644 --- a/talerbank/app/management/commands/wire_transfer.py +++ b/talerbank/app/management/commands/wire_transfer.py @@ -24,8 +24,8 @@ import logging import json from django.core.management.base import BaseCommand from django.contrib.auth import authenticate -from taler.util.amount import Amount, BadFormatAmount -from ...views import wire_transfer +from taler.util.amount import Amount +from ...views import wire_transfer, User from ...models import BankAccount, BankTransaction LOGGER = logging.getLogger(__name__) @@ -53,9 +53,9 @@ class Command(BaseCommand): ) parser.add_argument( "credit-account", - type=int, + type=str, metavar="CREDIT-ACCOUNT", - help="Which account number will *receive* money.", + help="Which account will receive money.", ) parser.add_argument( "subject", @@ -90,9 +90,8 @@ class Command(BaseCommand): sys.exit(1) try: - credit_account = BankAccount.objects.get( - account_no=options["credit-account"] - ) + credit_account_user = User.objects.get(username=options["credit-account"]) + credit_account = credit_account_user.bankaccount except BankAccount.DoesNotExist: LOGGER.error("Credit account does not exist.") sys.exit(1) diff --git a/talerbank/app/tests.py b/talerbank/app/tests.py index 61aec9e..83a8fb8 100644 --- a/talerbank/app/tests.py +++ b/talerbank/app/tests.py @@ -65,14 +65,6 @@ def clear_db(): cursor.execute("ALTER SEQUENCE app_banktransaction_id_seq RESTART") -# Bank used to crash when malformed JSON was sent -# to some endpoint that needs to authenticate the -# user. -class MalformedLoginTestCase(TestCase): - def test_malformed_login(self): - self.client.generic("POST", reverse("add-incoming", urlconf=urls), "malformed") - - class PublicAccountsTestCase(TestCase): def setUp(self): clear_db() @@ -390,87 +382,19 @@ class AddIncomingTestCase(TestCase): def test_add_incoming(self): client = Client() - data = ( - '{"auth": {"type": "basic"}, \ - "credit_account": 1, \ - "subject": "TESTWTID", \ - "exchange_url": "https://exchange.test", \ - "amount": "%s:1.0"}' - % settings.TALER_CURRENCY - ) + request_body = dict( + reserve_pub="TESTWTID", + amount=f"{settings.TALER_CURRENCY}:1.0", + debit_account="payto://x-taler-bank/bank_user") response = client.post( - reverse("add-incoming", urlconf=urls), - data=data, + reverse("twg-add-incoming", urlconf=urls, args=["user_user"]), + data=json.dumps(request_body), content_type="application/json", follow=True, HTTP_AUTHORIZATION=make_auth_line("user_user", "user_password"), ) self.assertEqual(200, response.status_code) - # Trying the same request, but compressed. - zdata = zlib.compress(bytes(data, "utf-8")) - response = client.post( - reverse("add-incoming", urlconf=urls), - data=zdata, - content_type="application/json", - follow=True, - HTTP_AUTHORIZATION=make_auth_line("user_user", "user_password"), - HTTP_CONTENT_ENCODING="deflate", - ) - self.assertEqual(200, response.status_code) - - data = '{"auth": {"type": "basic"}, \ - "credit_account": 1, \ - "subject": "TESTWTID", \ - "exchange_url": "https://exchange.test", \ - "amount": "WRONGCURRENCY:1.0"}' - - response = client.post( - reverse("add-incoming", urlconf=urls), - data=data, - content_type="application/json", - follow=True, - HTTP_AUTHORIZATION=make_auth_line("user_user", "user_password"), - ) - # note: a bad currency request gets 400. - self.assertEqual(400, response.status_code) - LOGGER.info(response.content.decode("utf-8")) - - # Try to go debit - data = ( - '{"auth": {"type": "basic"}, \ - "credit_account": 1, \ - "subject": "TESTWTID", \ - "exchange_url": "https://exchange.test", \ - "amount": "%s:50.1"}' - % settings.TALER_CURRENCY - ) - response = client.post( - reverse("add-incoming", urlconf=urls), - data=data, - content_type="application/json", - follow=True, - HTTP_AUTHORIZATION=make_auth_line("user_user", "user_password"), - ) - self.assertEqual(406, response.status_code) - # Try use a non-existent recipient. - data = ( - '{"auth": {"type": "basic"}, \ - "credit_account": 1987, \ - "subject": "TESTWTID", \ - "exchange_url": "https://exchange.test", \ - "amount": "%s:1"}' - % settings.TALER_CURRENCY - ) - response = client.post( - reverse("add-incoming", urlconf=urls), - data=data, - content_type="application/json", - follow=True, - HTTP_AUTHORIZATION=make_auth_line("user_user", "user_password"), - ) - self.assertEqual(404, response.status_code) - class CustomDoesNotExistTestCase(TestCase): def test_bankaccount_doesnotexist(self): diff --git a/talerbank/app/urls.py b/talerbank/app/urls.py index 10639d8..e929125 100644 --- a/talerbank/app/urls.py +++ b/talerbank/app/urls.py @@ -43,7 +43,6 @@ urlpatterns = [ path("taler-wire-gateway/", include(taler_wire_gateway_patterns)), path("", RedirectView.as_view(pattern_name="profile"), name="index"), path("favicon.ico", views.ignore), - path("admin/add/incoming", views.add_incoming, name="add-incoming"), path( "login/", auth_views.LoginView.as_view( diff --git a/talerbank/app/views.py b/talerbank/app/views.py index 5f68bbe..eae593a 100644 --- a/talerbank/app/views.py +++ b/talerbank/app/views.py @@ -408,14 +408,15 @@ def internal_register(request): user = User.objects.create_user(username=username, password=password) user_account = BankAccount(user=user) user_account.save() - bank_internal_account = BankAccount.objects.get(account_no=1) - wire_transfer( - Amount(settings.TALER_CURRENCY, 100, 0), - bank_internal_account, - user_account, - "Joining bonus", - ) + # Give the user their joining bonus + bank_internal_account = BankAccount.objects.get(account_no=1) + wire_transfer( + Amount(settings.TALER_CURRENCY, 100, 0), + bank_internal_account, + user_account, + "Joining bonus", + ) return user @@ -430,10 +431,8 @@ def register_headless(request): try: user = internal_register(request) - except UsernameUnavailable: return HttpResponse(status=409) # Conflict - except InvalidInputData: return HttpResponse(status=406) # Not Acceptable @@ -493,19 +492,6 @@ def logout_view(request): return redirect("index") -## -# Build the history array. -# -# @param account the bank account object whose history is being -# extracted. -# @param delta how many history entries will be contained in the -# array (will be passed as-is to the internal routine -# @a query_history). -# @param start any history will be searched starting from this -# value (which is a row ID), and going to the past or to -# the future (depending on the user choice). However, this -# value itself will not be included in the history. -# @return the history array. def extract_history(account, delta, start=None): history = [] qs = query_history(account, "both", delta, start) @@ -851,10 +837,14 @@ def twg_transfer(request, user_account, acct_id): ) -def get_payto_from_account(request, acct): - h = request.META['HTTP_HOST'] +def get_plain_host(request): + h = request.META.get("HTTP_HOST", "localhost") # remove port - h = h.split(":")[0] + return h.split(":")[0] + + +def get_payto_from_account(request, acct): + h = get_plain_host(request) return f"payto://x-taler-bank/{h}/{acct.user.username}" @require_GET @@ -939,60 +929,6 @@ def basic_auth(request): return django.contrib.auth.authenticate(username=username, password=password) -## -# Serve a request to make a wire transfer. Allows fintech -# providers to issues payments in a programmatic way. -# -# @param request Django-specific HTTP request object. -# @param user_account the (authenticated) user issuing this -# request. -# @return Django-specific HTTP response object. -@csrf_exempt -@require_POST -@login_via_headers -def add_incoming(request, user_account): - - data = AddIncomingData(json.loads(decode_body(request))) - - subject = "%s %s" % (data.get("subject"), data.get("exchange_url")) - - try: - credit_account = BankAccount.objects.get(account_no=data.get("credit_account")) - except BankAccount.DoesNotExist: - return JsonResponse( - { - "error": "Bank account not found" - }, - status=404, - ) - - - amount = Amount.parse(data.get("amount")) - - if amount.currency != settings.TALER_CURRENCY: - return JsonResponse( - { - "error": "Incorrect currency" - }, - status=400, - ) - - - wtrans = wire_transfer( - amount, - user_account.bankaccount, - credit_account, - subject, - ) - - return JsonResponse( - { - "row_id": wtrans.id, - "timestamp": dict(t_ms=(int(wtrans.date.timestamp()) * 1000)), - } - ) - - @login_via_headers @csrf_exempt @require_POST @@ -1005,7 +941,7 @@ def withdraw_headless_uri(request, user): user_balance = SignedAmount(not user_account.debit, user_account.amount) if user_balance - amount < -debt_threshold: raise DebitLimitException( - f"Aborting payment initiated by '{user_account.user.username}', debit limit crossed." + f"Aborting payment initiated by '{user_account.user.username}', debit limit {debt_threshold} crossed." ) op = TalerWithdrawOperation(amount=amount, withdraw_account=user_account) op.save() @@ -1023,10 +959,8 @@ def withdraw_headless(request, user): """ data = WithdrawHeadless(json.loads(decode_body(request))) - sender_payto = "payto://x-taler-bank/%s/%d" % ( - request.get_host(), - user.bankaccount.account_no, - ) + h = get_plain_host(request) + sender_payto = f"payto://x-taler-bank/{h}/{user.username}" ret_obj = {"sender_wire_details": sender_payto} exchange_payto = data.get("exchange_wire_details") @@ -1130,7 +1064,7 @@ def start_withdrawal(request): user_balance = user_account.balance if user_balance - withdraw_amount < -debt_threshold: raise DebitLimitException( - f"Aborting payment initiated by '{user_account.user.username}', debit limit crossed." + f"Aborting payment initiated by '{user_account.user.username}', debit limit {debt_threshold} crossed." ) op = TalerWithdrawOperation(amount=amount, withdraw_account=user_account) op.save() @@ -1214,20 +1148,21 @@ def confirm_withdrawal(request, withdraw_id): def wire_transfer(amount, debit_account, credit_account, subject): """ - Make a wire transfer between two accounts (internal to the bank) + Make a wire transfer between two accounts of this demo bank. """ + if debit_account.pk == credit_account.pk: + LOGGER.error("Debit and credit account are the same!") + raise SameAccountException() + LOGGER.debug( "transfering %s => %s, %s, %s" % ( - debit_account.account_no, - credit_account.account_no, - amount.stringify(2), + debit_account.user.username, + credit_account.user.username, + amount.stringify(), subject, ) ) - if debit_account.pk == credit_account.pk: - LOGGER.error("Debit and credit account are the same!") - raise SameAccountException() transaction_item = BankTransaction( amount=amount, @@ -1243,7 +1178,7 @@ def wire_transfer(amount, debit_account, credit_account, subject): if debit_account.balance - SignedAmount(True, amount) < threshold: raise DebitLimitException( - f"Aborting payment initiated by '{debit_account.user.username}', debit limit crossed." + f"Aborting payment initiated by '{debit_account.user.username}', debit limit {threshold} crossed." ) debit_account.balance -= SignedAmount(True, amount) |