gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-bank] branch master updated (9430850 -> 05d86a1)


From: gnunet
Subject: [GNUnet-SVN] [taler-bank] branch master updated (9430850 -> 05d86a1)
Date: Mon, 29 May 2017 11:25:15 +0200

This is an automated email from the git hooks/post-receive script.

marcello pushed a change to branch master
in repository bank.

    from 9430850  more diagnostics for #5033
     new 85fea9b  addressing #5013
     new 32bde8f  first tests under erroneous circumstances
     new 40dbd51  Add manual authentication before logging a user in. Just 
calling login() without authenticating the user before, returns 200 even for 
wrong login attempts.
     new a3aa430  testing operations with wrong currencies
     new e96c9fb  removing unneeded comments
     new 05d86a1  commenting out faults-injected tests

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Makefile.am                              |   1 +
 bank-check.conf => bank-check-alt.conf   |   3 +
 bank-check.conf                          |   1 +
 talerbank/app/amounts.py                 |  13 +++-
 talerbank/app/tests.py                   |  15 ++++-
 talerbank/app/{tests.py => tests_err.py} |  72 ++++++++++++++++----
 talerbank/app/views.py                   | 110 +++++++++++++++++++++----------
 7 files changed, 164 insertions(+), 51 deletions(-)
 copy bank-check.conf => bank-check-alt.conf (66%)
 copy talerbank/app/{tests.py => tests_err.py} (79%)

diff --git a/Makefile.am b/Makefile.am
index b6194ea..70b02ce 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,6 +23,7 @@ install-dev:
 
 check:
        @export DJANGO_SETTINGS_MODULE="talerbank.settings" 
TALER_PREFIX="@prefix@" TALER_CONFIG_FILE="bank-check.conf" && python3 -m 
django test talerbank.app.tests
+#      @export DJANGO_SETTINGS_MODULE="talerbank.settings" 
TALER_PREFIX="@prefix@" TALER_CONFIG_FILE="bank-check-alt.conf" && python3 -m 
django test talerbank.app.tests_err
 
 check_with_wrapper:
        @export DJANGO_SETTINGS_MODULE="talerbank.settings" 
TALER_PREFIX="@prefix@" TALER_CONFIG_FILE="bank-check.conf" && python3 
run_tests.py
diff --git a/bank-check.conf b/bank-check-alt.conf
similarity index 66%
copy from bank-check.conf
copy to bank-check-alt.conf
index dc78564..9c77a2a 100644
--- a/bank-check.conf
+++ b/bank-check-alt.conf
@@ -1,3 +1,6 @@
+# Config file containing intentional errors, used
+# to test how the bank reacts.
+
 [taler]
 
 CURRENCY = KUDOS
diff --git a/bank-check.conf b/bank-check.conf
index dc78564..b38ccd0 100644
--- a/bank-check.conf
+++ b/bank-check.conf
@@ -1,3 +1,4 @@
+
 [taler]
 
 CURRENCY = KUDOS
diff --git a/talerbank/app/amounts.py b/talerbank/app/amounts.py
index f201594..f9bdd02 100644
--- a/talerbank/app/amounts.py
+++ b/talerbank/app/amounts.py
@@ -26,10 +26,19 @@ logger = logging.getLogger(__name__)
 FRACTION = 100000000
 
 class CurrencyMismatchException(Exception):
-    pass
+    def __init__(self, msg=None, status_code=0):
+        self.msg = msg
+        # HTTP status code to be returned as response for
+        # this exception
+        self.status_code = status_code
 
 class BadFormatAmount(Exception):
-    pass
+    def __init__(self, msg=None, status_code=0):
+        self.msg = msg
+        # HTTP status code to be returned as response for
+        # this exception
+        self.status_code = status_code
+
 
 def check_currency(a1, a2):
     if a1["currency"] != a2["currency"]:
diff --git a/talerbank/app/tests.py b/talerbank/app/tests.py
index 4de125e..092d21c 100644
--- a/talerbank/app/tests.py
+++ b/talerbank/app/tests.py
@@ -123,6 +123,20 @@ class AddIncomingTestCase(TestCase):
                           content_type="application/json",
                           follow=True, **{"HTTP_X_TALER_BANK_USERNAME": 
"user_user", "HTTP_X_TALER_BANK_PASSWORD": "user_password"})
         self.assertEqual(200, response.status_code)
+        data = '{"auth": {"type": "basic"}, \
+                 "credit_account": 1, \
+                 "wtid": "TESTWTID", \
+                 "exchange_url": "https://exchange.test";, \
+                 "amount": \
+                   {"value": 1, \
+                    "fraction": 0, \
+                    "currency": "%s"}}' \
+               % "WRONGCURRENCY"
+        response = c.post(reverse("add-incoming", urlconf=urls),
+                          data=data,
+                          content_type="application/json",
+                          follow=True, **{"HTTP_X_TALER_BANK_USERNAME": 
"user_user", "HTTP_X_TALER_BANK_PASSWORD": "user_password"})
+        self.assertEqual(406, response.status_code)
 
 class HistoryTestCase(TestCase):
 
@@ -171,7 +185,6 @@ class HistoryTestCase(TestCase):
         response = c.get(reverse("history", urlconf=urls), {"auth": "basic", 
"delta": "1", "start": "11"},
                          **{"HTTP_X_TALER_BANK_USERNAME": "User", 
"HTTP_X_TALER_BANK_PASSWORD": "Password"})
         response_txt = response.content.decode("utf-8")
-        logger.info(response_txt)
         self.assertEqual(204, response.status_code)
         # Get credit records
         response = c.get(reverse("history", urlconf=urls), {"auth": "basic", 
"delta": "+1", "direction": "credit"},
diff --git a/talerbank/app/tests.py b/talerbank/app/tests_err.py
similarity index 79%
copy from talerbank/app/tests.py
copy to talerbank/app/tests_err.py
index 4de125e..26b1ae7 100644
--- a/talerbank/app/tests.py
+++ b/talerbank/app/tests_err.py
@@ -39,7 +39,8 @@ class RegisterTestCase(TestCase):
 
     def setUp(self):
         bank = User.objects.create_user(username='Bank')
-        ba = BankAccount(user=bank, currency=settings.TALER_CURRENCY)
+        # Activating this user with a faulty currency.
+        ba = BankAccount(user=bank, currency="XYZ")
         ba.account_no = 1
         ba.save() 
 
@@ -52,9 +53,11 @@ class RegisterTestCase(TestCase):
                           {"username": "test_register",
                            "password": "test_register"},
                            follow=True)
-        self.assertIn(("/profile", 302), response.redirect_chain)
-        # this assertion tests "/profile""s view
-        self.assertEqual(200, response.status_code)
+        # A currency mismatch is expected when the 100 KUDOS will be
+        # attempted to be given to the new user.
+        # This scenario expects a 500 Internal server error response to
+        # be returned.
+        self.assertEqual(500, response.status_code)
 
 
 class LoginTestCase(TestCase):
@@ -72,22 +75,30 @@ class LoginTestCase(TestCase):
     
     def test_login(self):
         c = Client()
+        # Sending non existent credentials.
         response = c.post(reverse("login", urlconf=urls),
                           {"username": "test_user",
-                           "password": "test_password"},
+                           "password": "test_passwordoo"},
                            follow=True)
-        self.assertIn(("/profile", 302), response.redirect_chain)
+        # The current logic -- django's default -- returns 200 OK
+        # even when the login didn't succeed.
+        # So the test here ensures that the bank just doesn't crash.
+        self.assertEqual(200, response.status_code)
 
 
 class AmountTestCase(TestCase):
     
+    # Trying to compare amount of different currencies
     def test_cmp(self):
         a1 = dict(value=1, fraction=0, currency="X")
-        _a1 = dict(value=1, fraction=0, currency="X")
-        a2 = dict(value=2, fraction=0, currency="X")
-        self.assertEqual(-1, amounts.amount_cmp(a1, a2))
-        self.assertEqual(1, amounts.amount_cmp(a2, a1))
-        self.assertEqual(0, amounts.amount_cmp(a1, _a1))
+        a2 = dict(value=2, fraction=0, currency="Y")
+        try:
+            amounts.amount_cmp(a1, a2)
+        except amounts.CurrencyMismatchException:
+            self.assertTrue(True)
+            return
+        # Should never get here
+        self.assertTrue(False)
 
 class AddIncomingTestCase(TestCase):
     """Test money transfer's API"""
@@ -104,6 +115,11 @@ class AddIncomingTestCase(TestCase):
         bank_account.save()
         user_account.save()
 
+        no1 = BankAccount.objects.get(account_no=1)
+        no2 = BankAccount.objects.get(account_no=2)
+        logger.info("1 username: %s" % no1.user.username)
+        logger.info("2 username: %s" % no2.user.username)
+
     def tearDown(self):
         clearDb()
 
@@ -118,11 +134,42 @@ class AddIncomingTestCase(TestCase):
                     "fraction": 0, \
                     "currency": "%s"}}' \
                % settings.TALER_CURRENCY
+        # Trying with wrong credentials
+        response = c.post(reverse("add-incoming", urlconf=urls),
+                          data=data,
+                          content_type="application/json",
+                          follow=True, **{"HTTP_X_TALER_BANK_USERNAME": 
"user_useroo", "HTTP_X_TALER_BANK_PASSWORD": "user_passwordoo"})
+        self.assertEqual(401, response.status_code)
+        data = '{"auth": {"type": "basic"}, \
+                 "credit_account": 1, \
+                 "wtid": "TESTWTID", \
+                 "exchange_url": "https://exchange.test";, \
+                 "amount": \
+                   {"value": 1, \
+                    "fraction": 0, \
+                    "currency": "%s"}}' \
+               % "WRONGCURRENCY"
+        # Trying with wrong currency
+        response = c.post(reverse("add-incoming", urlconf=urls),
+                          data=data,
+                          content_type="application/json",
+                          follow=True, **{"HTTP_X_TALER_BANK_USERNAME": 
"user_user", "HTTP_X_TALER_BANK_PASSWORD": "user_password"})
+        self.assertEqual(406, response.status_code)
+        # Trying to go debit
+        data = '{"auth": {"type": "basic"}, \
+                 "credit_account": 1, \
+                 "wtid": "TESTWTID", \
+                 "exchange_url": "https://exchange.test";, \
+                 "amount": \
+                   {"value": 60, \
+                    "fraction": 0, \
+                    "currency": "%s"}}' \
+               % settings.TALER_CURRENCY
         response = c.post(reverse("add-incoming", urlconf=urls),
                           data=data,
                           content_type="application/json",
                           follow=True, **{"HTTP_X_TALER_BANK_USERNAME": 
"user_user", "HTTP_X_TALER_BANK_PASSWORD": "user_password"})
-        self.assertEqual(200, response.status_code)
+
 
 class HistoryTestCase(TestCase):
 
@@ -171,7 +218,6 @@ class HistoryTestCase(TestCase):
         response = c.get(reverse("history", urlconf=urls), {"auth": "basic", 
"delta": "1", "start": "11"},
                          **{"HTTP_X_TALER_BANK_USERNAME": "User", 
"HTTP_X_TALER_BANK_PASSWORD": "Password"})
         response_txt = response.content.decode("utf-8")
-        logger.info(response_txt)
         self.assertEqual(204, response.status_code)
         # Get credit records
         response = c.get(reverse("history", urlconf=urls), {"auth": "basic", 
"delta": "+1", "direction": "credit"},
diff --git a/talerbank/app/views.py b/talerbank/app/views.py
index c3bed3e..3607de7 100644
--- a/talerbank/app/views.py
+++ b/talerbank/app/views.py
@@ -232,6 +232,13 @@ def pin_tan_verify(request):
         logger.warning("Withdrawal impossible due to debt limit exceeded")
         request.session["debt_limit"] = True
         return redirect("profile")
+    except amounts.BadFormatAmount as e:
+        return HttpResponse(e.msg, status=e.status_code) 
+    except amounts.CurrencyMismatchException as e:
+        return HttpResponse(e.msg, status=e.status_code) 
+    except SameAccountException:
+        logger.error("Odd situation: SameAccountException should NOT occur in 
this function")
+        return HttpResponse("internal server error", status=500)
 
     request_url = urljoin(exchange_url, "admin/add/incoming")
     res = requests.post(request_url, json=json_body)
@@ -274,6 +281,14 @@ def register(request):
     except DebtLimitExceededException:
         logger.info("Debt situation encountered")
         request.session["no_initial_bonus"] = True
+    except amounts.CurrencyMismatchException as e:
+        return HttpResponse(e.msg, status=e.status_code)
+    except amounts.BadFormatAmount as e:
+        return HttpResponse(e.msg, status=e.status_code)
+    except SameAccountException:
+        logger.error("Odd situation: SameAccountException should NOT occur in 
this function")
+        return HttpResponse("internal server error", status=500)
+        
     request.session["just_registered"] = True
     user = django.contrib.auth.authenticate(username=username, 
password=password)
     django.contrib.auth.login(request, user)
@@ -471,14 +486,15 @@ def add_incoming(request):
                                     credit_account,
                                     subject)
         return JsonResponse(dict(serial_id=transaction.id, 
timestamp="/Date(%s)/" % int(transaction.date.timestamp())))
-    except amounts.BadFormatAmount:
-        logger.error("Amount specified in TALER_MAX_DEBT or 
TALER_MAX_DEBT_BANK is malformed")
-        return HttpResponse(status=500)
+    except amounts.BadFormatAmount as e:
+        return JsonResponse(dict(error=e.msg), status=e.status_code)
     except SameAccountException:
         return JsonResponse(dict(error="debit and credit account are the 
same"), status=422)
     except DebtLimitExceededException:
         return JsonResponse(dict(error="debit count has reached its debt 
limit", status=403 ),
                              status=403)
+    except amounts.CurrencyMismatchException as e:
+        return JsonResponse(dict(error=e.msg), status=e.status_code)
 
 @login_required
 @require_POST
@@ -515,42 +531,66 @@ def wire_transfer(amount,
                                        debit_account=debit_account,
                                        subject=subject)
 
-    if debit_account.debit:
-        debit_account.balance_obj = 
amounts.amount_add(debit_account.balance_obj,
-                                                       amount)
-
-    elif -1 == amounts.amount_cmp(debit_account.balance_obj, amount):
-        debit_account.debit = True
-        debit_account.balance_obj = amounts.amount_sub(amount,
-                                                       
debit_account.balance_obj)
-    else:
-        debit_account.balance_obj = 
amounts.amount_sub(debit_account.balance_obj,
-                                                       amount)
-
-    if False == credit_account.debit:
-        credit_account.balance_obj = 
amounts.amount_add(credit_account.balance_obj,
-                                                        amount)
-
-    elif 1 == amounts.amount_cmp(amount, credit_account.balance_obj):
-        credit_account.debit = False
-        credit_account.balance_obj = amounts.amount_sub(amount,
-                                                        
credit_account.balance_obj)
-    else:
-        credit_account.balance_obj = 
amounts.amount_sub(credit_account.balance_obj,
-                                                        amount)
+    try:
+        if debit_account.debit:
+            debit_account.balance_obj = 
amounts.amount_add(debit_account.balance_obj,
+                                                           amount)
+    
+        elif -1 == amounts.amount_cmp(debit_account.balance_obj, amount):
+            debit_account.debit = True
+            debit_account.balance_obj = amounts.amount_sub(amount,
+                                                           
debit_account.balance_obj)
+        else:
+            debit_account.balance_obj = 
amounts.amount_sub(debit_account.balance_obj,
+                                                           amount)
+
+        if False == credit_account.debit:
+            credit_account.balance_obj = 
amounts.amount_add(credit_account.balance_obj,
+                                                            amount)
+    
+        elif 1 == amounts.amount_cmp(amount, credit_account.balance_obj):
+            credit_account.debit = False
+            credit_account.balance_obj = amounts.amount_sub(amount,
+                                                            
credit_account.balance_obj)
+        else:
+            credit_account.balance_obj = 
amounts.amount_sub(credit_account.balance_obj,
+                                                            amount)
+    except amounts.CurrencyMismatchException:
+        msg = "The amount to be transferred (%s) doesn't match the bank's 
currency (%s)" % (amount["currency"], settings.TALER_CURRENCY)
+        status_code = 406
+        if settings.TALER_CURRENCY != credit_account.balance_obj["currency"]:
+            logger.error("Internal inconsistency: credit account's currency 
(%s) differs from bank's (%s)" % (credit_account.balance_obj["currency"], 
settings.TALER_CURRENCY))
+            msg = "Internal server error"
+            status_code = 500
+        elif settings.TALER_CURRENCY != debit_account.balance_obj["currency"]:
+            logger.error("Internal inconsistency: debit account's currency 
(%s) differs from bank's (%s)" % (debit_account.balance_obj["currency"], 
settings.TALER_CURRENCY))
+            msg = "Internal server error"
+            status_code = 500
+        logger.error(msg)
+        raise amounts.CurrencyMismatchException(msg=msg, 
status_code=status_code)
 
     # Check here if any account went beyond the allowed
     # debit threshold.
 
-    threshold = amounts.parse_amount(settings.TALER_MAX_DEBT)
-    if debit_account.user.username == "Bank":
-        threshold = amounts.parse_amount(settings.TALER_MAX_DEBT_BANK)
-    if 1 == amounts.amount_cmp(debit_account.balance_obj, threshold) \
-       and 0 != amounts.amount_cmp(amounts.get_zero(), threshold) \
-       and debit_account.debit:
-        logger.error("Negative balance '%s' not allowed." % 
json.dumps(debit_account.balance_obj))
-        logger.info("%s's threshold is: '%s'." % (debit_account.user.username, 
json.dumps(threshold)))
-        raise DebtLimitExceededException()
+    try:
+        threshold = amounts.parse_amount(settings.TALER_MAX_DEBT)
+
+        if debit_account.user.username == "Bank":
+            threshold = amounts.parse_amount(settings.TALER_MAX_DEBT_BANK)
+    except amounts.BadFormatAmount:
+        logger.error("MAX_DEBT|MAX_DEBT_BANK had the wrong format")
+        raise amounts.BadFormatAmount(msg="internal server error", 
status_code=500)
+
+    try:
+        if 1 == amounts.amount_cmp(debit_account.balance_obj, threshold) \
+           and 0 != amounts.amount_cmp(amounts.get_zero(), threshold) \
+           and debit_account.debit:
+            logger.error("Negative balance '%s' not allowed." % 
json.dumps(debit_account.balance_obj))
+            logger.info("%s's threshold is: '%s'." % 
(debit_account.user.username, json.dumps(threshold)))
+            raise DebtLimitExceededException()
+    except amounts.CurrencyMismatchException:
+        logger.error("(Internal) currency mismatch between debt threshold and 
debit account")
+        raise amounts.CurrencyMismatchException(msg="internal server error", 
status_code=500)
 
     with transaction.atomic():
         debit_account.save()

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]