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: implement /reject


From: gnunet
Subject: [GNUnet-SVN] [taler-bank] branch master updated: implement /reject
Date: Fri, 08 Dec 2017 16:04:39 +0100

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

marcello pushed a commit to branch master
in repository bank.

The following commit(s) were added to refs/heads/master by this push:
     new 94b2977  implement /reject
94b2977 is described below

commit 94b29779c175b3b71de4a8633c5bba11965d0554
Author: Marcello Stanisci <address@hidden>
AuthorDate: Fri Dec 8 16:00:17 2017 +0100

    implement /reject
---
 talerbank/app/schemas.py | 18 +++++++++--
 talerbank/app/tests.py   | 79 +++++++++++++++++++++++++++++++++++++++++++++---
 talerbank/app/urls.py    |  1 +
 talerbank/app/views.py   | 41 +++++++++++++++++++++----
 4 files changed, 125 insertions(+), 14 deletions(-)

diff --git a/talerbank/app/schemas.py b/talerbank/app/schemas.py
index f441ee5..810f33f 100644
--- a/talerbank/app/schemas.py
+++ b/talerbank/app/schemas.py
@@ -69,16 +69,25 @@ WIREDETAILS_SCHEMA = {
 AUTH_SCHEMA = {
     "type": "object",
     "properties": {
-        "type": {"type": "string"},
+        "type": {"type": "string",
+                 "pattern": "^basic$"},
         "data": {"type": "object", "required": False}
     }
 }
 
+REJECT_REQUEST_SCHEMA = {
+    "type": "object",
+    "properties": {
+        "auth": AUTH_SCHEMA,
+        "row_id": {"type": "integer"},
+        "account_number": {"type": "integer"}
+    }
+}
+
 HISTORY_REQUEST_SCHEMA = {
     "type": "object",
     "properties": {
-        "auth": {"type": "string",
-                 "patter": "^basic$"},
+        "auth": {"type": "string", "pattern": "^basic$"},
         "delta": {"type": "string",
                   "pattern": r"^([\+-])?([0-9])+$"},
         "start": {"type": "string",
@@ -133,6 +142,9 @@ def validate_pin_tan_args(pin_tan_args):
         "wiredetails_string": validate_pintan_types}
     validictory.validate(pin_tan_args, PIN_TAN_ARGS, 
format_validators=format_dict)
 
+def validate_reject_request(reject_request):
+    validictory.validate(reject_request, REJECT_REQUEST_SCHEMA)
+
 def validate_history_request(history_request):
     validictory.validate(history_request, HISTORY_REQUEST_SCHEMA)
 
diff --git a/talerbank/app/tests.py b/talerbank/app/tests.py
index b19ceb0..1787537 100644
--- a/talerbank/app/tests.py
+++ b/talerbank/app/tests.py
@@ -31,6 +31,8 @@ LOGGER = logging.getLogger()
 LOGGER.setLevel(logging.WARNING)
 
 def clear_db():
+    # FIXME: this way we do not reset autoincrement
+    # fields.
     User.objects.all().delete()
     BankAccount.objects.all().delete()
     BankTransaction.objects.all().delete()
@@ -50,7 +52,10 @@ class WithdrawTestCase(TestCase):
             account_no=99).save()
         self.client = Client()
 
-    @patch('hashlib.new') # Need to patch update() and hexdigest() methods.
+    def tearDown(self):
+        clear_db()
+
+    @patch('hashlib.new')
     @patch('requests.post')
     @patch('time.time')
     def test_withdraw(self, mocked_time, mocked_post, mocked_hashlib):
@@ -113,6 +118,9 @@ class InternalWireTransferTestCase(TestCase):
         BankAccount(user=User.objects.create_user(username='take_money'),
                     account_no=88).save()
 
+    def tearDown(self):
+        clear_db()
+
     def test_internal_wire_transfer(self):
         client = Client()
         client.login(username="give_money", password="gm")
@@ -124,8 +132,6 @@ class InternalWireTransferTestCase(TestCase):
                                        
BankAccount.objects.get(account_no=88).amount))
         self.assertEqual(200, response.status_code)
 
-    def tearDown(self):
-        clear_db()
 
 class RegisterTestCase(TestCase):
     """User registration"""
@@ -207,6 +213,57 @@ class AmountTestCase(TestCase):
         with self.assertRaises(CurrencyMismatch):
             Amount.cmp(amount1, amount2)
 
+class RejectTestCase(TestCase):
+
+    def setUp(self):
+        BankAccount(
+            user=User.objects.create_user(
+                username="rejected_user",
+                password="rejected_password")).save()
+        BankAccount(
+            user=User.objects.create_user(
+                username="rejecting_user",
+                password="rejecting_password")).save()
+
+    def tearDown(self):
+        clear_db()
+
+    def test_reject(self):
+        client = Client()
+        rejecting = User.objects.get(username="rejecting_user")
+        data = '{"auth": {"type": "basic"}, \
+                 "credit_account": %d, \
+                 "subject": "TESTWTID", \
+                 "exchange_url": "https://exchange.test";, \
+                 "amount": \
+                   {"value": 5, \
+                    "fraction": 0, \
+                    "currency": "%s"}}' \
+               % (rejecting.bankaccount.account_no,
+                  settings.TALER_CURRENCY)
+        response = client.post(
+            reverse("add-incoming", urlconf=urls),
+            data=data,
+            content_type="application/json",
+            follow=True, **{
+                "HTTP_X_TALER_BANK_USERNAME": "rejected_user",
+                "HTTP_X_TALER_BANK_PASSWORD": "rejected_password"})
+
+        data = response.content.decode("utf-8")
+        jdata = json.loads(data)
+        rejected = User.objects.get(username="rejected_user")
+        response = client.put(
+            reverse("reject", urlconf=urls),
+            data='{"row_id": %d, \
+                   "auth": {"type": "basic"}, \
+                   "account_number": %d}' \
+                  % (jdata["row_id"], rejected.bankaccount.account_no),
+            content_type="application/json",
+            **{"HTTP_X_TALER_BANK_USERNAME": "rejecting_user",
+               "HTTP_X_TALER_BANK_PASSWORD": "rejecting_password"})
+        self.assertEqual(response.status_code, 204)
+
+
 class AddIncomingTestCase(TestCase):
     """Test money transfer's API"""
 
@@ -336,8 +393,12 @@ class HistoryTestCase(TestCase):
 
 class DBAmountSubtraction(TestCase):
     def setUp(self):
-        BankAccount(user=User.objects.create_user(username='U'),
-                    amount=Amount(settings.TALER_CURRENCY, 3)).save()
+        BankAccount(
+            user=User.objects.create_user(username='U'),
+            amount=Amount(settings.TALER_CURRENCY, 3)).save()
+
+    def tearDown(self):
+        clear_db()
 
     def test_subtraction(self):
         user_bankaccount = BankAccount.objects.get(
@@ -356,6 +417,9 @@ class DBCustomColumnTestCase(TestCase):
         BankAccount(
             user=User.objects.create_user(username='U')).save()
 
+    def tearDown(self):
+        clear_db()
+
     def test_exists(self):
         user_bankaccount = BankAccount.objects.get(
             user=User.objects.get(username='U'))
@@ -370,6 +434,9 @@ class DebitTestCase(TestCase):
         BankAccount(
             user=User.objects.create_user(username='U0')).save()
 
+    def tearDown(self):
+        clear_db()
+
     def test_green(self):
         user_bankaccount = BankAccount.objects.get(
             user=User.objects.get(username='U'))
@@ -438,6 +505,8 @@ class MeasureHistory(TestCase):
                           self.user_bankaccount0,
                           user_bankaccount,
                           "bulk")
+    def tearDown(self):
+        clear_db()
 
     def test_extract_history(self):
 
diff --git a/talerbank/app/urls.py b/talerbank/app/urls.py
index ca7006a..9cf4223 100644
--- a/talerbank/app/urls.py
+++ b/talerbank/app/urls.py
@@ -29,6 +29,7 @@ urlpatterns = [
     url(r'^accounts/register/$', views.register, name="register"),
     url(r'^profile$', views.profile_page, name="profile"),
     url(r'^history$', views.serve_history, name="history"),
+    url(r'^reject$', views.reject, name="reject"),
     url(r'^withdraw$', views.withdraw_nojs, name="withdraw-nojs"),
     url(r'^public-accounts$', views.serve_public_accounts, 
name="public-accounts"),
     url(r'^public-accounts/(?P<name>[a-zA-Z0-9 ]+)$',
diff --git a/talerbank/app/views.py b/talerbank/app/views.py
index 0b0e68b..b5209db 100644
--- a/talerbank/app/views.py
+++ b/talerbank/app/views.py
@@ -45,7 +45,8 @@ from simplemathcaptcha.fields import MathCaptchaField, 
MathCaptchaWidget
 from .models import BankAccount, BankTransaction
 from .amount import Amount, CurrencyMismatch, BadFormatAmount
 from .schemas import (validate_pin_tan_args, check_withdraw_session,
-                      validate_history_request, validate_incoming_request)
+                      validate_history_request, validate_incoming_request,
+                      validate_reject_request)
 
 LOGGER = logging.getLogger(__name__)
 
@@ -424,7 +425,7 @@ def auth_and_login(request):
        credentials, False if errors occur"""
 
     auth_type = None
-    if request.method == "POST":
+    if request.method in ["POST", "PUT"]:
         data = json.loads(request.body.decode("utf-8"))
         auth_type = data["auth"]["type"]
     if request.method == "GET":
@@ -442,6 +443,33 @@ def auth_and_login(request):
     return django.contrib.auth.authenticate(username=username,
                                             password=password)
 
address@hidden
+def reject(request, user_account):
+    data = json.loads(request.body.decode("utf-8"))
+    try:
+        validate_reject_request(data)
+    except (FVE, RFVE) as exc:
+        return JsonResponse({"error": "invalid '%s'" % exc.fieldname}, 
status=400)
+    try:
+        trans = BankTransaction.objects.get(id=data["row_id"])
+    except BankTransaction.DoesNotExist:
+        return JsonResponse({"error": "unknown transaction"}, status=404)
+
+    # WARNING: here the bank must make sure 'row_id' points to
+    # a transaction where the requesting user owns the credit account.
+    # Not even a bug number exists on this.
+
+    try:
+        wire_transfer(trans.amount, user_account.bankaccount,
+                      trans.debit_account, "/reject: reimbursement",
+                      cancelled=True)
+    except WireTransferException as exc:
+        # Logging the error is taken care of wire_transfer()
+        return exc.response
+
+    return HttpResponse(status=204)
+
+
 @csrf_exempt
 @require_POST
 @login_via_headers
@@ -464,17 +492,17 @@ def add_incoming(request, user_account):
 
     subject = "%s %s" % (data["subject"], data["exchange_url"])
     try:
-        credit_account = BankAccount.objects.get(user=data["credit_account"])
+        credit_account = 
BankAccount.objects.get(account_no=data["credit_account"])
         wtrans = wire_transfer(Amount(**data["amount"]),
                                user_account.bankaccount,
                                credit_account,
                                subject)
     except BankAccount.DoesNotExist:
-        return JsonResponse({"error": "credit_account not found"},
+        return JsonResponse({"error": "credit_account (%d) not found" % 
data["credit_account"]},
                             status=404)
     except WireTransferException as exc:
         return exc.response
-    return JsonResponse({"serial_id": wtrans.id,
+    return JsonResponse({"row_id": wtrans.id,
                          "timestamp":
                              "/Date(%s)/" % int(wtrans.date.timestamp())})
 
@@ -537,7 +565,8 @@ def wire_transfer(amount, debit_account, credit_account, 
subject, **kwargs):
         transaction_item = BankTransaction(amount=amount,
                                            credit_account=credit_account,
                                            debit_account=debit_account,
-                                           subject=subject)
+                                           subject=subject,
+                                           cancelled=kwargs.get("cancelled", 
False))
         if debit_account.debit:
             debit_account.amount.add(amount)
 

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



reply via email to

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