diff options
author | Florian Dold <florian@dold.me> | 2020-11-09 21:36:34 +0100 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2020-11-09 21:36:34 +0100 |
commit | a87bd68502667b6ab75a82c44aa36fbb15882941 (patch) | |
tree | 65af494f9cd467c9a79d19e33821279485ca13ac | |
parent | f9446c7338898a1d6cb9e4947e4e4e48afcdec47 (diff) | |
download | bank-a87bd68502667b6ab75a82c44aa36fbb15882941.tar.gz bank-a87bd68502667b6ab75a82c44aa36fbb15882941.tar.bz2 bank-a87bd68502667b6ab75a82c44aa36fbb15882941.zip |
pretty printer
-rw-r--r-- | talerbank/app/management/commands/top_up.py | 4 | ||||
-rw-r--r-- | talerbank/app/middleware.py | 11 | ||||
-rw-r--r-- | talerbank/app/schemas.py | 4 | ||||
-rw-r--r-- | talerbank/app/tests.py | 130 | ||||
-rw-r--r-- | talerbank/app/urls.py | 80 | ||||
-rw-r--r-- | talerbank/app/views.py | 131 | ||||
-rw-r--r-- | talerbank/cli.py | 69 |
7 files changed, 275 insertions, 154 deletions
diff --git a/talerbank/app/management/commands/top_up.py b/talerbank/app/management/commands/top_up.py index 88cca0a..f20f835 100644 --- a/talerbank/app/management/commands/top_up.py +++ b/talerbank/app/management/commands/top_up.py @@ -62,7 +62,9 @@ class Command(BaseCommand): user = User.objects.get(username=options["user"]) # Take the money from the bank's account try: - debit_account = BankAccount.objects.get(account_no=1,) + debit_account = BankAccount.objects.get( + account_no=1, + ) except BankAccount.DoesNotExist: LOGGER.error("Debit account (bank's own account) does not exist.") sys.exit(1) diff --git a/talerbank/app/middleware.py b/talerbank/app/middleware.py index 7a76505..ef43625 100644 --- a/talerbank/app/middleware.py +++ b/talerbank/app/middleware.py @@ -112,7 +112,10 @@ class ExceptionMiddleware: return redirect(render_to) else: return JsonResponse( - dict(code=ErrorCode.BANK_UNMANAGED_EXCEPTION, - hint="unexpected exception", - exception=str(exception)), - status=HTTPStatus.INTERNAL_SERVER_ERROR) + dict( + code=ErrorCode.BANK_UNMANAGED_EXCEPTION, + hint="unexpected exception", + exception=str(exception), + ), + status=HTTPStatus.INTERNAL_SERVER_ERROR, + ) diff --git a/talerbank/app/schemas.py b/talerbank/app/schemas.py index db58f19..4bd4589 100644 --- a/talerbank/app/schemas.py +++ b/talerbank/app/schemas.py @@ -136,7 +136,9 @@ class BankValidator: def __init__(self, validator, data): self.validation_result = validator(data) if not self.validation_result.is_valid(): - raise JSONFieldException(self.validation_result.errors, HTTPStatus.BAD_REQUEST) + raise JSONFieldException( + self.validation_result.errors, HTTPStatus.BAD_REQUEST + ) def get(self, name, default=None): ret = self.validation_result.cleaned_data.get(name) diff --git a/talerbank/app/tests.py b/talerbank/app/tests.py index bf6711b..b5c926e 100644 --- a/talerbank/app/tests.py +++ b/talerbank/app/tests.py @@ -53,6 +53,7 @@ fileHandler.setFormatter( ) LOGGER.addHandler(fileHandler) + def make_auth_line(username, password): credentials = "%s:%s" % (username, password) b64enc = base64.b64encode(bytes(credentials, "utf-8")) @@ -68,6 +69,7 @@ def clear_db(): cursor.execute("ALTER SEQUENCE app_bankaccount_account_no_seq" " RESTART") cursor.execute("ALTER SEQUENCE app_banktransaction_id_seq RESTART") + class WireGatewayTestCase(TestCase): def setUp(self): clear_db() @@ -77,12 +79,12 @@ class WireGatewayTestCase(TestCase): customer.save() exchange_bank_account = BankAccount( user=exchange, - balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 100, 0)) + balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 100, 0)), ) exchange_bank_account.save() customer_bank_account = BankAccount( user=customer, - balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 100, 0)) + balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 100, 0)), ) customer_bank_account.save() self.client = Client() @@ -92,9 +94,12 @@ class WireGatewayTestCase(TestCase): reverse("twg-add-incoming", kwargs=dict(acct_id="RandomExchange")), HTTP_AUTHORIZATION=make_auth_line("RandomExchange", "XYZ"), content_type="application/json", - data=dict(amount=f"{settings.TALER_CURRENCY}:10", - reserve_pub="FXWC2JHBY8B0XE2MMGAJ9TGPY307TN12HVEKYSTN6HE3GTHTF8XG", - debit_account="payto://x-taler-bank/localhost/RandomCustomer")) + data=dict( + amount=f"{settings.TALER_CURRENCY}:10", + reserve_pub="FXWC2JHBY8B0XE2MMGAJ9TGPY307TN12HVEKYSTN6HE3GTHTF8XG", + debit_account="payto://x-taler-bank/localhost/RandomCustomer", + ), + ) self.assertEqual(r.status_code, 200) # Test incoming transfers of Exchange. @@ -111,8 +116,12 @@ class WireGatewayTestCase(TestCase): HTTP_AUTHORIZATION=make_auth_line("RandomExchange", "XYZ"), content_type="application/json", data=dict( - request_uid="0", amount=f"{settings.TALER_CURRENCY}:3", - exchange_base_url="mock", wtid="123", credit_account="payto://x-taler-bank/localhost/RandomCustomer") + request_uid="0", + amount=f"{settings.TALER_CURRENCY}:3", + exchange_base_url="mock", + wtid="123", + credit_account="payto://x-taler-bank/localhost/RandomCustomer", + ), ) r = self.client.get( reverse("twg-history-outgoing", kwargs=dict(acct_id="RandomExchange")), @@ -121,15 +130,18 @@ class WireGatewayTestCase(TestCase): ) self.assertEqual(r.status_code, 200) + class IntegrationApiTestCase(TestCase): def setUp(self): clear_db() - self.exchange = User.objects.create_user(username="RandomExchange", password="XYZ") + self.exchange = User.objects.create_user( + username="RandomExchange", password="XYZ" + ) self.exchange.save() self.exchange_bank_account = BankAccount( user=self.exchange, - balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 100, 0)) + balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 100, 0)), ) self.exchange_bank_account.save() @@ -137,7 +149,7 @@ class IntegrationApiTestCase(TestCase): self.user.save() self.user_bank_account = BankAccount( user=self.user, - balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 100, 0)) + balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 100, 0)), ) self.user_bank_account.save() self.client = Client() @@ -150,19 +162,21 @@ class IntegrationApiTestCase(TestCase): def test_withdraw(self): operation = TalerWithdrawOperation( amount=Amount(settings.TALER_CURRENCY, 100, 0), - withdraw_account=self.user_bank_account + withdraw_account=self.user_bank_account, ) operation.save() r = self.client.post( - reverse("api-withdraw-operation", - kwargs=dict(withdraw_id=operation.withdraw_id)), + reverse( + "api-withdraw-operation", kwargs=dict(withdraw_id=operation.withdraw_id) + ), data=dict( reserve_pub="reserve-public-key", - selected_exchange=f"payto://x-taler-bank/localhost/RandomExchange" + selected_exchange=f"payto://x-taler-bank/localhost/RandomExchange", ), - content_type="application/json" + content_type="application/json", ) - self.assertEqual(r.status_code, 200) + self.assertEqual(r.status_code, 200) + class AccessApiWithdrawTestCase(TestCase): def setUp(self): @@ -171,7 +185,7 @@ class AccessApiWithdrawTestCase(TestCase): self.user.save() self.user_bank_account = BankAccount( user=self.user, - balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 100, 0)) + balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 100, 0)), ) self.user_bank_account.save() self.client = Client() @@ -181,7 +195,7 @@ class AccessApiWithdrawTestCase(TestCase): reverse("access-api-withdrawal", kwargs=dict(acct_id="RandomUser")), HTTP_AUTHORIZATION=make_auth_line("RandomUser", "XYZ"), content_type="application/json", - data=dict(amount=f"{settings.TALER_CURRENCY}:5") + data=dict(amount=f"{settings.TALER_CURRENCY}:5"), ) self.assertEqual(r.status_code, 200) data = r.content.decode("utf-8") @@ -196,8 +210,10 @@ class AccessApiWithdrawTestCase(TestCase): def test_accees_withdraw_status(self): withdrawal_id = self.create_withdrawal() r = self.client.get( - reverse("access-api-withdrawal-status", - kwargs=dict(acct_id="RandomUser", wid=withdrawal_id)), + reverse( + "access-api-withdrawal-status", + kwargs=dict(acct_id="RandomUser", wid=withdrawal_id), + ), HTTP_AUTHORIZATION=make_auth_line("RandomUser", "XYZ"), ) self.assertEqual(r.status_code, 200) @@ -205,8 +221,10 @@ class AccessApiWithdrawTestCase(TestCase): def test_accees_withdraw_abort(self): withdrawal_id = self.create_withdrawal() r = self.client.post( - reverse("access-api-withdrawal-abort", - kwargs=dict(acct_id="RandomUser", wid=withdrawal_id)), + reverse( + "access-api-withdrawal-abort", + kwargs=dict(acct_id="RandomUser", wid=withdrawal_id), + ), HTTP_AUTHORIZATION=make_auth_line("RandomUser", "XYZ"), ) self.assertEqual(r.status_code, 200) @@ -214,8 +232,10 @@ class AccessApiWithdrawTestCase(TestCase): def test_accees_withdraw_confirm(self): withdrawal_id = self.create_withdrawal() r = self.client.post( - reverse("access-api-withdrawal-confirm", - kwargs=dict(acct_id="RandomUser", wid=withdrawal_id)), + reverse( + "access-api-withdrawal-confirm", + kwargs=dict(acct_id="RandomUser", wid=withdrawal_id), + ), HTTP_AUTHORIZATION=make_auth_line("RandomUser", "XYZ"), ) self.assertEqual(r.status_code, 200) @@ -223,14 +243,18 @@ class AccessApiWithdrawTestCase(TestCase): def test_accees_withdraw_abort_then_confirm(self): withdrawal_id = self.create_withdrawal() r = self.client.post( - reverse("access-api-withdrawal-abort", - kwargs=dict(acct_id="RandomUser", wid=withdrawal_id)), + reverse( + "access-api-withdrawal-abort", + kwargs=dict(acct_id="RandomUser", wid=withdrawal_id), + ), HTTP_AUTHORIZATION=make_auth_line("RandomUser", "XYZ"), ) self.assertEqual(r.status_code, 200) r = self.client.post( - reverse("access-api-withdrawal-confirm", - kwargs=dict(acct_id="RandomUser", wid=withdrawal_id)), + reverse( + "access-api-withdrawal-confirm", + kwargs=dict(acct_id="RandomUser", wid=withdrawal_id), + ), HTTP_AUTHORIZATION=make_auth_line("RandomUser", "XYZ"), ) self.assertEqual(r.status_code, 409) @@ -240,25 +264,29 @@ class AccessApiWithdrawTestCase(TestCase): r = self.client.get( reverse( "access-api-withdrawal-status", - kwargs=dict( - acct_id="RandomUser", - wid=wid)), - HTTP_AUTHORIZATION=make_auth_line("RandomUser", "XYZ") + kwargs=dict(acct_id="RandomUser", wid=wid), + ), + HTTP_AUTHORIZATION=make_auth_line("RandomUser", "XYZ"), ) self.assertEqual(r.status_code, 200) def test_integration_api_withdraw_confirm(self): wid = self.create_withdrawal() r = self.client.post( - reverse("access-api-withdrawal-confirm", kwargs=dict(acct_id="RandomUser", wid=wid)), + reverse( + "access-api-withdrawal-confirm", + kwargs=dict(acct_id="RandomUser", wid=wid), + ), data=dict( reserve_pub="FXWC2JHBY8B0XE2MMGAJ9TGPY307TN12HVEKYSTN6HE3GTHTF8XG", - selected_exchange="payto://x-taler-bank/localhost/RandomUser"), + selected_exchange="payto://x-taler-bank/localhost/RandomUser", + ), content_type="application/json", - HTTP_AUTHORIZATION=make_auth_line("RandomUser", "XYZ") + HTTP_AUTHORIZATION=make_auth_line("RandomUser", "XYZ"), ) self.assertEqual(r.status_code, 200) + class AccessApiBalanceTestCase(TestCase): def setUp(self): clear_db() @@ -275,6 +303,7 @@ class AccessApiBalanceTestCase(TestCase): ) self.assertEqual(r.status_code, 200) + class AccessApiTestingRegistrationTestCase(TestCase): def setUp(self): clear_db() @@ -285,26 +314,41 @@ class AccessApiTestingRegistrationTestCase(TestCase): def test_testing_registration(self): c = Client() - r = c.post(reverse("testing-withdraw-register"), - data=dict(username="x", password="y"), - content_type="application/json") + r = c.post( + reverse("testing-withdraw-register"), + data=dict(username="x", password="y"), + content_type="application/json", + ) self.assertEqual(r.status_code, 200) + class ReservePubExtractionTestCase(TestCase): def test_extraction(self): - self.assertTrue(get_reserve_pub("0T096A11M57GWGG0P6ZM9Z8G5829BFJFH2AN9R5T80FJ931DX7GG")) - self.assertTrue(get_reserve_pub("0T096A11M57GWGG0P6ZM9Z8G5829BFJFH2AN9R5T80FJ931DX7GG other data")) + self.assertTrue( + get_reserve_pub("0T096A11M57GWGG0P6ZM9Z8G5829BFJFH2AN9R5T80FJ931DX7GG") + ) + self.assertTrue( + get_reserve_pub( + "0T096A11M57GWGG0P6ZM9Z8G5829BFJFH2AN9R5T80FJ931DX7GG other data" + ) + ) self.assertFalse(get_reserve_pub("not a reserve public key")) + class PaytoParseTestCase(TestCase): def test_payto_parse(self): - parsed = PaytoParse("payto://x-taler-bank/bank.int.taler.net/Exchange?subject=0T096A11M57GWGG0P6ZM9Z8G5829BFJFH2AN9R5T80FJ931DX7GG&amount=EUR:1") + parsed = PaytoParse( + "payto://x-taler-bank/bank.int.taler.net/Exchange?subject=0T096A11M57GWGG0P6ZM9Z8G5829BFJFH2AN9R5T80FJ931DX7GG&amount=EUR:1" + ) self.assertTrue("Exchange" == parsed.account) - self.assertTrue("0T096A11M57GWGG0P6ZM9Z8G5829BFJFH2AN9R5T80FJ931DX7GG" == parsed.subject) + self.assertTrue( + "0T096A11M57GWGG0P6ZM9Z8G5829BFJFH2AN9R5T80FJ931DX7GG" == parsed.subject + ) self.assertTrue(parsed.amount.value == 1) self.assertTrue(parsed.amount.fraction == 0) self.assertTrue(parsed.amount.currency == "EUR") + class PublicAccountsTestCase(TestCase): def setUp(self): clear_db() @@ -381,6 +425,7 @@ class WithdrawTestCase(TestCase): def tearDown(self): clear_db() + class RegisterTestCase(TestCase): """User registration""" @@ -470,6 +515,7 @@ class LoginTestCase(TestCase): data = response.content.decode("utf-8") self.assertEqual(401, response.status_code) + class AddIncomingTestCase(TestCase): """Test money transfer's API""" diff --git a/talerbank/app/urls.py b/talerbank/app/urls.py index e7c354d..1e0a712 100644 --- a/talerbank/app/urls.py +++ b/talerbank/app/urls.py @@ -48,40 +48,40 @@ taler_wire_gateway_patterns = [ taler_bank_integration_api_patterns = [ - path("api/config", - views.api_config, - name="api-config" - ), - path("api/withdrawal-operation/<str:withdraw_id>", - views.api_withdraw_operation, - name="api-withdraw-operation" + path("api/config", views.api_config, name="api-config"), + path( + "api/withdrawal-operation/<str:withdraw_id>", + views.api_withdraw_operation, + name="api-withdraw-operation", ), ] # These paths are part of the bank access API taler_bank_access_api_patterns = [ - path("accounts/<str:acct_id>", - views.bank_accounts_api_balance, - name="access-api-balance"), + path( + "accounts/<str:acct_id>", + views.bank_accounts_api_balance, + name="access-api-balance", + ), path( "accounts/<str:acct_id>/withdrawals", views.bank_accounts_api_create_withdrawal, - name="access-api-withdrawal" + name="access-api-withdrawal", ), path( "accounts/<str:acct_id>/withdrawals/<str:wid>", views.bank_accounts_api_get_withdrawal, - name="access-api-withdrawal-status" + name="access-api-withdrawal-status", ), path( "accounts/<str:acct_id>/withdrawals/<str:wid>/confirm", views.bank_accounts_api_confirm_withdrawal, - name="access-api-withdrawal-confirm" + name="access-api-withdrawal-confirm", ), path( "accounts/<str:acct_id>/withdrawals/<str:wid>/abort", views.bank_accounts_api_abort_withdrawal, - name="access-api-withdrawal-abort" + name="access-api-withdrawal-abort", ), path("testing/withdraw", views.withdraw_headless, name="testing-withdraw"), path("testing/register", views.register_headless, name="testing-withdraw-register"), @@ -91,51 +91,49 @@ urlpatterns = [ path("", include(taler_bank_integration_api_patterns)), path("", include(taler_bank_access_api_patterns)), path("taler-wire-gateway/", include(taler_wire_gateway_patterns)), - path("abort-withdrawal/<str:withdraw_id>", - views.abort_withdrawal, - name="abort-withdrawal" + path( + "abort-withdrawal/<str:withdraw_id>", + views.abort_withdrawal, + name="abort-withdrawal", ), path("favicon.ico", views.ignore), path("config", views.config_view, name="config"), path("history", views.serve_history, name="history"), - path("public-accounts", - views.serve_public_accounts, name="public-accounts"), - path("payto-transfer", - views.payto_transfer, - name="payto-transfer"), + path("public-accounts", views.serve_public_accounts, name="public-accounts"), + path("payto-transfer", views.payto_transfer, name="payto-transfer"), ] urlpatterns += i18n_patterns( - path("confirm-withdrawal/<str:withdraw_id>", - views.confirm_withdrawal, - name="withdraw-confirm", + path( + "confirm-withdrawal/<str:withdraw_id>", + views.confirm_withdrawal, + name="withdraw-confirm", ), - path("start-withdrawal", - views.start_withdrawal, - name="start-withdrawal"), - - path("show-withdrawal/<str:withdraw_id>", - views.show_withdrawal, - name="withdraw-show" + path("start-withdrawal", views.start_withdrawal, name="start-withdrawal"), + path( + "show-withdrawal/<str:withdraw_id>", views.show_withdrawal, name="withdraw-show" ), path("", RedirectView.as_view(pattern_name="profile"), name="index"), path("logout", views.logout_view, name="logout"), path("register", views.register, name="register"), path("profile", views.profile_page, name="profile"), path("payto-form", views.payto_form, name="payto-form"), - path("login", + path( + "login", auth_views.LoginView.as_view( template_name="login.html", authentication_form=views.TalerAuthenticationForm, ), - name="login" + name="login", ), - path("public-accounts/<str:name>", - views.serve_public_accounts, - name="public-accounts" + path( + "public-accounts/<str:name>", + views.serve_public_accounts, + name="public-accounts", + ), + path( + "public-accounts/<str:name>/<int:page>", + views.serve_public_accounts, + name="public-accounts", ), - path("public-accounts/<str:name>/<int:page>", - views.serve_public_accounts, - name="public-accounts" - ) ) diff --git a/talerbank/app/views.py b/talerbank/app/views.py index 004d200..fc1eb54 100644 --- a/talerbank/app/views.py +++ b/talerbank/app/views.py @@ -87,15 +87,19 @@ def login_via_headers(view_func): if not user_account: raise LoginFailed("authentication failed") return view_func(request, user_account, *args, **kwargs) + return wraps(view_func)(_decorator) + def allow_origin_star(view_func): def _decorator(request, *args, **kwargs): response = view_func(request, *args, **kwargs) response["Access-Control-Allow-Origin"] = "*" return response + return wraps(view_func)(_decorator) + class PaytoParse: def __init__(self, payto_uri): parsed_payto = urlparse(payto_uri) @@ -235,6 +239,7 @@ def get_session_hint(request): del request.session["hint"] return ret + def set_session_hint(request, success, hint): if "hint" in request.session: LOGGER.warning("Overriding a non consumed hint") @@ -298,6 +303,7 @@ class InputDatalist(forms.TextInput): datalist += "</datalist>" return html + datalist + class PaytoTransferForm(forms.Form): address = forms.CharField() @@ -309,6 +315,7 @@ def payto_form(request): ) return render(request, "payto_wiretransfer.html", context) + ## # This method serves the profile page, which is the main # page where the user interacts with the bank, and also the @@ -346,16 +353,13 @@ def profile_page(request): response.status_code = HTTPStatus.ACCEPTED return response + @login_required @require_POST def payto_transfer(request): data = PaytoTransferForm(request.POST) if not data.is_valid(): - set_session_hint( - request, - success=False, - hint=gettext("Bad form submitted!") - ) + set_session_hint(request, success=False, hint=gettext("Bad form submitted!")) return redirect("profile") parsed_address = PaytoParse(data.cleaned_data.get("address")) @@ -363,15 +367,12 @@ def payto_transfer(request): parsed_address.amount, BankAccount.objects.get(user=request.user), BankAccount.objects.get(account_no=parsed_address.account), - parsed_address.subject - ) - set_session_hint( - request, - success=True, - hint=gettext("Wire transfer successful!") + parsed_address.subject, ) + set_session_hint(request, success=True, hint=gettext("Wire transfer successful!")) return redirect("profile") + ## # Helper function that hashes its input. Usually # used to hash the response to the math CAPTCHA. @@ -465,15 +466,19 @@ def register_headless(request): registering a user. """ if not settings.ALLOW_REGISTRATIONS: - return JsonResponse(dict(error="registrations are not allowed"), status=HTTPStatus.FORBIDDEN) + return JsonResponse( + dict(error="registrations are not allowed"), status=HTTPStatus.FORBIDDEN + ) username = expect_json_body_str(request, "username") password = expect_json_body_str(request, "password") try: internal_register(username, password) except UsernameUnavailable: - return JsonResponse(dict(hint="username unavailable"), status=HTTPStatus.CONFLICT) + return JsonResponse( + dict(hint="username unavailable"), status=HTTPStatus.CONFLICT + ) except InvalidInputData: - return HttpResponse(status=HTTPStatus.NOT_ACCEPTABLE) # WTF? BAD REQUEST? + return HttpResponse(status=HTTPStatus.NOT_ACCEPTABLE) # WTF? BAD REQUEST? return HttpResponse(status=HTTPStatus.OK) @@ -487,7 +492,9 @@ def register(request): """ if not settings.ALLOW_REGISTRATIONS: # FIXME: shouldn't be JSON! - return JsonResponse(dict(error="registrations are not allowed"), status=HTTPStatus.FORBIDDEN) + return JsonResponse( + dict(error="registrations are not allowed"), status=HTTPStatus.FORBIDDEN + ) if request.method != "POST": return render(request, "register.html") @@ -520,9 +527,7 @@ def register(request): {"wrong": True, "hint": "Out of business, cannot admit new customers."}, ) - set_session_hint( - request, success=True, hint=gettext("Registration successful!") - ) + set_session_hint(request, success=True, hint=gettext("Registration successful!")) django.contrib.auth.login(request, user) return redirect("profile") @@ -646,12 +651,15 @@ def serve_public_accounts(request, name=None, page=None): forth=page + 1 if page < num_pages else None, public_accounts=public_accounts, selected_account=dict( - name=name, number=user.bankaccount.account_no, history=history, + name=name, + number=user.bankaccount.account_no, + history=history, ), pages=pages, ) return render(request, "public_accounts.html", context) + ## # Build the DB query switch based on the "direction" history # argument given by the user. @@ -859,7 +867,12 @@ def twg_add_incoming(request, user_account, acct_id): debit_account = BankAccount.objects.get(user=debit_user) subject = f"{reserve_pub}" - wtrans = wire_transfer(amount, debit_account, exchange_account, subject,) + wtrans = wire_transfer( + amount, + debit_account, + exchange_account, + subject, + ) return JsonResponse( { @@ -898,8 +911,11 @@ def twg_transfer(request, user_account, acct_id): LOGGER.error(f"credit account '{credit_account_name}' does not exist") # FIXME: use EC from taler-util library return JsonResponse( - dict(code=ErrorCode.BANK_UNKNOWN_ACCOUNT, - error="credit account does not exist"), status=404 + dict( + code=ErrorCode.BANK_UNKNOWN_ACCOUNT, + error="credit account does not exist", + ), + status=404, ) credit_account = BankAccount.objects.get(user=credit_user) @@ -947,7 +963,12 @@ def twg_history_incoming(request, user_account, acct_id): start = None else: start = int(start_str) - qs = query_history(user_account.bankaccount, "credit", delta, start,) + qs = query_history( + user_account.bankaccount, + "credit", + delta, + start, + ) for item in qs: rp = get_reserve_pub(item.subject) if rp is None: @@ -975,7 +996,12 @@ def twg_history_outgoing(request, user_account, acct_id): start = None else: start = int(start_str) - qs = query_history(user_account.bankaccount, "debit", delta, start,) + 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.split(" ") @@ -1045,13 +1071,16 @@ def withdraw_headless(request, user): exchange_payto = data.get("exchange_payto_uri") if not exchange_payto: - return JsonResponse(dict(hint="exchange_payto_uri missig"), status=HTTPStatus.BAD_REQUEST) + return JsonResponse( + dict(hint="exchange_payto_uri missig"), status=HTTPStatus.BAD_REQUEST + ) exchange_account_name = get_acct_from_payto(exchange_payto) try: exchange_user = User.objects.get(username=exchange_account_name) except User.DoesNotExist: return JsonResponse( - dict(hint="exchange bank account does not exist"), status=HTTPStatus.NOT_FOUND + dict(hint="exchange bank account does not exist"), + status=HTTPStatus.NOT_FOUND, ) exchange_bankaccount = exchange_user.bankaccount wire_transfer( @@ -1074,7 +1103,9 @@ def api_withdraw_operation(request, withdraw_id): try: op = TalerWithdrawOperation.objects.get(withdraw_id=withdraw_id) except ObjectDoesNotExist: - return JsonResponse(dict(error="withdraw operation does not exist"), status=HTTPStatus.NOT_FOUND) + return JsonResponse( + dict(error="withdraw operation does not exist"), status=HTTPStatus.NOT_FOUND + ) if request.method == "POST": data = json.loads(decode_body(request)) @@ -1082,18 +1113,27 @@ def api_withdraw_operation(request, withdraw_id): try: exchange_account_name = get_acct_from_payto(exchange_payto_uri) except: - return JsonResponse(dict(error="exchange payto URI malformed"), status=HTTPStatus.BAD_REQUEST) + return JsonResponse( + dict(error="exchange payto URI malformed"), + status=HTTPStatus.BAD_REQUEST, + ) try: exchange_user = User.objects.get(username=exchange_account_name) except User.DoesNotExist: return JsonResponse( - dict(code=ErrorCode.BANK_UNKNOWN_ACCOUNT, - hint="bank account in payto URI unknown"), status=HTTPStatus.BAD_REQUEST # WTF? NOT_FOUND? + dict( + code=ErrorCode.BANK_UNKNOWN_ACCOUNT, + hint="bank account in payto URI unknown", + ), + status=HTTPStatus.BAD_REQUEST, # WTF? NOT_FOUND? ) exchange_account = exchange_user.bankaccount selected_reserve_pub = data.get("reserve_pub") if not isinstance(selected_reserve_pub, str): - return JsonResponse(dict(error="reserve_pub must be a string"), status=HTTPStatus.BAD_REQUEST) + return JsonResponse( + dict(error="reserve_pub must be a string"), + status=HTTPStatus.BAD_REQUEST, + ) if op.selection_done: if ( op.selected_exchange_account != exchange_account @@ -1102,7 +1142,7 @@ def api_withdraw_operation(request, withdraw_id): return JsonResponse( dict( code=ErrorCode.BANK_WITHDRAWAL_OPERATION_RESERVE_SELECTION_CONFLICT, - hint="selection of withdraw parameters already done" + hint="selection of withdraw parameters already done", ), status=HTTPStatus.CONFLICT, ) @@ -1145,7 +1185,10 @@ def api_withdraw_operation(request, withdraw_id): ) ) else: - return JsonResponse(dict(error="only GET and POST are allowed"), status=HTTPStatus.METHOD_NOT_ALLOWED) + return JsonResponse( + dict(error="only GET and POST are allowed"), + status=HTTPStatus.METHOD_NOT_ALLOWED, + ) @login_required @@ -1216,7 +1259,9 @@ def confirm_withdrawal(request, withdraw_id): type(hashed_attempt), type(request.POST.get("pin_1")), ) - set_session_hint(request, success=False, hint=gettext("Wrong CAPTCHA answer.")) + set_session_hint( + request, success=False, hint=gettext("Wrong CAPTCHA answer.") + ) return redirect("withdraw-confirm", withdraw_id=withdraw_id) op.confirmation_done = True op.save() @@ -1226,9 +1271,7 @@ def confirm_withdrawal(request, withdraw_id): op.selected_exchange_account, op.selected_reserve_pub, ) - set_session_hint( - request, success=True, hint=gettext("Withdrawal successful!") - ) + set_session_hint(request, success=True, hint=gettext("Withdrawal successful!")) request.session["just_withdrawn"] = True return redirect("profile") @@ -1243,7 +1286,7 @@ def confirm_withdrawal(request, withdraw_id): amount=op.amount.stringify(settings.TALER_DIGITS), exchange=op.selected_exchange_account.user, is_success=is_success, - hint=hint + hint=hint, ) return render(request, "withdraw_confirm.html", context) raise Exception("not reached") @@ -1402,6 +1445,7 @@ def bank_accounts_api_get_withdrawal(request, user, acct_id, wid): } ) + def withdraw_abort_internal(wid): op = TalerWithdrawOperation.objects.get(withdraw_id=wid) if op.confirmation_done: @@ -1415,7 +1459,11 @@ def withdraw_abort_internal(wid): @login_required def abort_withdrawal(request, withdraw_id): internal_status = withdraw_abort_internal(withdraw_id) - set_session_hint(request, success=internal_status["status"] == HTTPStatus.OK, hint=internal_status["hint"]) + set_session_hint( + request, + success=internal_status["status"] == HTTPStatus.OK, + hint=internal_status["hint"], + ) return redirect("profile") @@ -1434,6 +1482,7 @@ def bank_accounts_api_abort_withdrawal(request, user, acct_id, wid): dict(hint=internal_status["hint"]), status=internal_status["status"] ) + @csrf_exempt @require_POST @login_via_headers @@ -1448,7 +1497,9 @@ def bank_accounts_api_confirm_withdrawal(request, user, acct_id, wid): if op.confirmation_done: return JsonResponse(dict(), status=HTTPStatus.OK) if op.aborted: - return JsonResponse(dict(hint="can't confirm aborted withdrawal"), status=HTTPStatus.CONFLICT) + return JsonResponse( + dict(hint="can't confirm aborted withdrawal"), status=HTTPStatus.CONFLICT + ) with transaction.atomic(): if op.selection_done: diff --git a/talerbank/cli.py b/talerbank/cli.py index d08ff4b..c62cba5 100644 --- a/talerbank/cli.py +++ b/talerbank/cli.py @@ -40,12 +40,13 @@ LOGGER = logging.getLogger(__name__) UWSGI_LOGFMT = "%(ltime) %(proto) %(method) %(uri) %(proto) => %(status)" os.environ.setdefault("DJANGO_SETTINGS_MODULE", "talerbank.settings") + @click.group(help="Manager script of Taler bank.") @click.pass_context @click.option( "--http-port", help="Set HTTP as the serving protocol (taking precedence over the config.), and set the port.", - type=int + type=int, ) @click.option("-c", "--config", help="Path to the config file.") @click.option("--with-db", help="Database connection string.") @@ -57,6 +58,7 @@ def cli(ctx, http_port, config, with_db): ctx.obj = dict(http_port=http_port, config=config) + @cli.command(help="Serve the bank") @click.pass_obj def serve(obj): @@ -81,51 +83,66 @@ def serve(obj): def handle_django(args): django.setup() # always run 'migrate' first, in case a virgin db is being used. - call_command('migrate') + call_command("migrate") django_index = sys.argv.index("django") from django.core.management import execute_from_command_line - execute_from_command_line([sys.argv[0] + " django"] + sys.argv[django_index+1:]) + + execute_from_command_line([sys.argv[0] + " django"] + sys.argv[django_index + 1 :]) def handle_serve_http(port): import django + django.setup() print("migrating") - call_command('migrate') + call_command("migrate") print("providing accounts") - call_command('provide_accounts') + call_command("provide_accounts") print("checking") - call_command('check') + call_command("check") if port is None: TC = TalerConfig.from_file(os.environ.get("TALER_CONFIG_FILE")) port = TC["bank"]["http_port"].value_int(required=True) httpspec = ":%d" % (port,) - params = ["uwsgi", "uwsgi", - "--static-map", "/static=%s/talerbank/app/static" % SITE_PACKAGES, - "--die-on-term", - "--no-orphans", - "--master", - "--http", httpspec, - "--log-format", UWSGI_LOGFMT, - "--module", "talerbank.wsgi"] + params = [ + "uwsgi", + "uwsgi", + "--static-map", + "/static=%s/talerbank/app/static" % SITE_PACKAGES, + "--die-on-term", + "--no-orphans", + "--master", + "--http", + httpspec, + "--log-format", + UWSGI_LOGFMT, + "--module", + "talerbank.wsgi", + ] os.execlp(*params) def handle_serve_uwsgi(): django.setup() - call_command('migrate') - call_command('provide_accounts') - call_command('check') + call_command("migrate") + call_command("provide_accounts") + call_command("check") TC = TalerConfig.from_file(os.environ.get("TALER_CONFIG_FILE")) serve_uwsgi = TC["bank"]["uwsgi_serve"].value_string(required=True).lower() - params = ["uwsgi", "uwsgi", - "--static-map", "/static=%s/talerbank/app/static" % SITE_PACKAGES, - "--die-on-term", - "--no-orphans", - "--master", - "--log-format", UWSGI_LOGFMT, - "--module", "talerbank.wsgi"] + params = [ + "uwsgi", + "uwsgi", + "--static-map", + "/static=%s/talerbank/app/static" % SITE_PACKAGES, + "--die-on-term", + "--no-orphans", + "--master", + "--log-format", + UWSGI_LOGFMT, + "--module", + "talerbank.wsgi", + ] if serve_uwsgi == "tcp": port = TC["bank"]["uwsgi_port"].value_int(required=True) spec = ":%d" % (port,) @@ -134,7 +151,7 @@ def handle_serve_uwsgi(): spec = TC["bank"]["uwsgi_unixpath"].value_filename(required=True) mode = TC["bank"]["uwsgi_unixpath_mode"].value_filename(required=True) params.extend(["--socket", spec]) - params.extend(["--chmod-socket="+mode]) + params.extend(["--chmod-socket=" + mode]) try: os.makedirs(os.path.dirname(spec), exist_ok=True) except FileNotFoundError: @@ -143,10 +160,12 @@ def handle_serve_uwsgi(): logging.info("launching uwsgi with argv %s", params[1:]) os.execlp(*params) + @cli.command(help="Print config values.") def config(): TC = TalerConfig.from_file(os.environ.get("TALER_CONFIG_FILE")) TC.dump() + def run(): cli() |