summaryrefslogtreecommitdiff
path: root/talerbank/app/middleware.py
blob: 6bd129d31eb5c9dc75b4dc510e5f100f012597f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import logging
from django.http import JsonResponse
from django.shortcuts import redirect
from .models import BankAccount, BankTransaction
from .views import \
    (DebitLimitException, SameAccountException,
     LoginFailed, RejectNoRightsException)
from .schemas import \
    (URLParameterMissing, URLParameterMalformed,
     JSONFieldException)
from .amount import CurrencyMismatch, BadFormatAmount

LOGGER = logging.getLogger()


##
# Class holding data needed by the handling logic.
class ExceptionMiddleware:

    ##
    # Init constructor.
    #
    # @param self the object itself.
    # @param get_response FIXME TBD.
    def __init__(self, get_response):
        self.get_response = get_response

        self.excs = {
            BankAccount.DoesNotExist: 0,
            BankTransaction.DoesNotExist: 1,
            SameAccountException: 2,
            DebitLimitException: 3,
            URLParameterMissing: 8,
            URLParameterMalformed: 9,
            JSONFieldException: 6,
            CurrencyMismatch: 11,
            BadFormatAmount: 11,
            LoginFailed: 12,
            RejectNoRightsException: 13}

        self.apis = {
            "/reject": 5300,
            "/history": 5200,
            "/admin/add/incoming": 5100}

        self.render = {
            "/profile": "profile",
            "/register": "index",
            "/public-accounts": "index",
            "/pin/verify": "profile"}


    def __call__(self, request):
        return self.get_response(request)


    ##
    # Main logic for processing the exception.  It checks
    # if the exception captured can be managed, and does it
    # if so.  Otherwise, it lets the native handler operate.
    #
    # @param a @a ExceptionMiddleware object.
    # @param request Django-specific HTTP request.
    # @param exception the exception raised from the bank.
    def process_exception(self, request, 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)

        # The way error codes compose matches
        # definitions found in [1].
        taler_ec += self.apis.get(request.path, 1000)
        render_to = self.render.get(request.path)
        if not render_to:
            return JsonResponse({"ec": taler_ec,
                                 "error": exception.hint},
                                status=exception.http_status_code)
        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#n1502