From fd5b3e7df26690169bb420f81e27a266a8c5d17b Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Sat, 16 Nov 2019 03:10:17 +0100 Subject: Closing #5788 and shortening middleware code. --- talerbank/app/middleware.py | 52 +++++++++++---------------------------------- talerbank/app/models.py | 2 ++ talerbank/app/schemas.py | 2 ++ talerbank/app/tests.py | 13 ++++++++++++ talerbank/app/views.py | 12 ++++++++++- 5 files changed, 40 insertions(+), 41 deletions(-) diff --git a/talerbank/app/middleware.py b/talerbank/app/middleware.py index a0d8f40..21c747f 100644 --- a/talerbank/app/middleware.py +++ b/talerbank/app/middleware.py @@ -1,12 +1,14 @@ import logging import zlib +from . import urls from django.http import JsonResponse +from django.urls import reverse from django.shortcuts import redirect from .models import BankAccount, BankTransaction, \ BankAccountDoesNotExist, BankTransactionDoesNotExist from .views import \ (DebitLimitException, SameAccountException, - LoginFailed, RejectNoRightsException) + LoginFailed, RejectNoRightsException, UnhandledException) from .schemas import \ (JSONFieldException, @@ -68,31 +70,12 @@ class ExceptionMiddleware: def __init__(self, get_response): self.get_response = get_response - # List of all the exceptions that are managed by - # this module. - self.excs = { - BankAccountDoesNotExist: 5110, - BankTransactionDoesNotExist: 5111, - SameAccountException: 5102, - URLParamValidationError: 5105, - JSONFieldException: 5106, - CurrencyMismatch: 5104, - BadFormatAmount: 11, - LoginFailed: 5312, - NumberTooBig: 5108, - NegativeNumber: 5107, - DebitLimitException: 5103, - RejectNoRightsException: 5200, - } - # Map between endpoints and Web pages to render # after the exception gets managed. self.render = { - "/profile": "profile", - "/accounts/register": "index", - "/public-accounts": "index", - "/pin/verify": "profile", - "/withdraw": "profile" + reverse("profile", urlconf=urls): "profile", + reverse("register", urlconf=urls): "index", + reverse("public-accounts", urlconf=urls): "index", } ## @@ -117,28 +100,17 @@ class ExceptionMiddleware: # @param exception the exception raised from the bank. def process_exception(self, request, exception): LOGGER.warning(str(exception)) - # See if we manage this exception. Return None if not. - exc_class = None - for e in self.excs: - if isinstance(exception, e): - exc_class = e - break - if not exc_class: - return None - - # Managed exception. Build response. - taler_ec = self.excs.get(exc_class) - - # Check if the endpoint should cause a human-readable - # page to be returned. + + if not hasattr(exception, "taler_error_code"): + exception = UnhandledException() + render_to = self.render.get(request.path) if not render_to: - return JsonResponse({"ec": taler_ec, + return JsonResponse({"ec": exception.taler_error_code, "error": exception.hint}, status=exception.http_status_code) - request.session["profile_hint"] = \ - True, False, exception.hint + request.session["profile_hint"] = True, False, exception.hint return redirect(render_to) # [1] https://git.taler.net/exchange.git/tree/src/include/taler_error_codes.h diff --git a/talerbank/app/models.py b/talerbank/app/models.py index d7ce64c..692d6b8 100644 --- a/talerbank/app/models.py +++ b/talerbank/app/models.py @@ -126,12 +126,14 @@ class BankAccountDoesNotExist(Exception): def __init__(self): self.hint = "Bank account not found" self.http_status_code = 404 + self.taler_error_code = 5110 self.minor_error_code = 0 class BankTransactionDoesNotExist(Exception): def __init__(self): self.hint = "Bank transaction not found" self.http_status_code = 404 + self.taler_error_code = 5111 self.minor_error_code = 0 class CustomManager(models.Manager): diff --git a/talerbank/app/schemas.py b/talerbank/app/schemas.py index bbe998c..b6aaeb2 100644 --- a/talerbank/app/schemas.py +++ b/talerbank/app/schemas.py @@ -70,6 +70,7 @@ class JSONFieldException(ValueError): def __init__(self, error, http_status_code): self.hint = json.dumps(error.as_json()) self.http_status_code = http_status_code + self.taler_error_code = 5106 super().__init__() @@ -87,6 +88,7 @@ class URLParamValidationError(ValueError): def __init__(self, error, http_status_code): self.hint = json.stringify(error.as_json()) self.http_status_code = http_status_code + self.taler_error_code = 5105 super().__init__() diff --git a/talerbank/app/tests.py b/talerbank/app/tests.py index b58e3c8..4181c8c 100644 --- a/talerbank/app/tests.py +++ b/talerbank/app/tests.py @@ -51,6 +51,18 @@ 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() @@ -498,6 +510,7 @@ class AddIncomingTestCase(TestCase): self.assertRaises(CurrencyMismatch) self.assertEqual(406, response.status_code) LOGGER.info(response.content.decode("utf-8")) + # Try to go debit data = '{"auth": {"type": "basic"}, \ "credit_account": 1, \ diff --git a/talerbank/app/views.py b/talerbank/app/views.py index 426937e..d4c1872 100644 --- a/talerbank/app/views.py +++ b/talerbank/app/views.py @@ -68,7 +68,7 @@ UINT64_MAX = (2**64) - 1 class LoginFailed(Exception): hint = "Wrong username/password" http_status_code = 401 - + taler_error_code = 5109 class InvalidInputData(Exception): def __init__(self, msg): @@ -93,6 +93,7 @@ class PrivateAccountException(Exception): class DebitLimitException(Exception): hint = "Insufficient credit, operation not acceptable." http_status_code = 406 + taler_error_code = 5103 ## @@ -102,6 +103,7 @@ class DebitLimitException(Exception): class SameAccountException(Exception): hint = "Debit and credit account are the same." http_status_code = 403 + taler_error_code = 5102 ## @@ -112,6 +114,14 @@ class RejectNoRightsException(Exception): hint = "You weren't the transaction credit account, " \ "no rights to reject." http_status_code = 403 + taler_error_code = 5200 + +class UnhandledException(Exception): + hint = "Unhandled exception happened!" + http_status_code = 500 + taler_error_code = 5300 + + ## -- cgit v1.2.3