aboutsummaryrefslogtreecommitdiff
path: root/talerbank
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2020-01-18 16:36:25 +0100
committerFlorian Dold <florian.dold@gmail.com>2020-01-18 16:36:25 +0100
commit8bad829f155590706b581528d46db249e94b9d18 (patch)
tree8dc376ae9e91449a7614288ebc90e9d4665ffb12 /talerbank
parent4804a61c6fa6ec930435b4781873e79e77c9d0ee (diff)
downloadbank-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.py13
-rw-r--r--talerbank/app/tests.py88
-rw-r--r--talerbank/app/urls.py1
-rw-r--r--talerbank/app/views.py121
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)