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 (9714707 -> 79734f4)


From: gnunet
Subject: [GNUnet-SVN] [taler-bank] branch master updated (9714707 -> 79734f4)
Date: Fri, 31 May 2019 18:56:35 +0200

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

marcello pushed a change to branch master
in repository bank.

    from 9714707  porting /history-range
     new 992a339  5715
     new 79734f4  porting add-incoming

The 2 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:
 talerbank/app/schemas.py | 113 ++++++++++++++++++++++++++++-------------------
 talerbank/app/views.py   |  52 +++++++++++-----------
 2 files changed, 93 insertions(+), 72 deletions(-)

diff --git a/talerbank/app/schemas.py b/talerbank/app/schemas.py
index 01503a2..d44a03b 100644
--- a/talerbank/app/schemas.py
+++ b/talerbank/app/schemas.py
@@ -31,6 +31,19 @@ from django.core.validators import RegexValidator
 
 
 ##
+# Constant value for the biggest number the bank handles.
+# This value is just equal to the biggest number that JavaScript
+# can handle (because of the wallet).
+# FIXME: also defined in views.py.  Need a common.py to contain
+# such definitions ?
+UINT64_MAX = (2**64) - 1
+
+
+##
+# Pattern for amounts, plain RegEx.
+AMOUNT_REGEX = "^[A-Za-z0-9_-]+:([0-9]+)\.?([0-9]+)?$"
+
+##
 # Exception class to be raised when at least one expected URL
 # parameter is either not found or malformed.
 class URLParamValidationError(ValidationError):
@@ -39,7 +52,7 @@ class URLParamValidationError(ValidationError):
     # Init method.
     #
     # @param self the object itself.
-    # @param param the missing URL parameter name.
+    # @param error object containing the hint.
     # @param http_status_code the HTTP response code to return
     #        to the caller (client).
     def __init__(self, error, http_status_code):
@@ -47,6 +60,46 @@ class URLParamValidationError(ValidationError):
         self.http_status_code = http_status_code
         super().__init__()
 
+class AuthForm(forms.Form):
+
+    type = forms.CharField(
+        validators=[RegexValidator(
+            "^basic$",
+            message="Only 'basic' method provided for now")])
+
+    # Just any value is good here.
+    data = forms.Field(required=False) 
+
+class AuthField(forms.Field):
+    ##
+    # No need to touch the input.  Dict is good
+    # and gets validated by the "validate()" method.
+    def to_python(self, value):
+        return value
+
+    ##
+    # Validate input.
+    def validate(self, value):
+        af = AuthForm(value)
+        if not af.is_valid():
+            raise ValidationError(
+                json.dumps(af.errors.as_json()))
+
+class RejectData(forms.Form):
+    auth = AuthField()
+    # FIXME: adjust min/max values.
+    row_id = forms.IntegerField()
+    account_number = forms.IntegerField()
+
+class AddIncomingData(forms.Form):
+    auth = AuthField()
+    amount = forms.CharField(validators=[
+        RegexValidator(AMOUNT_REGEX,
+        message="Format CURRENCY:X[.Y] not respected")])
+    subject = forms.CharField()
+    credit_account = forms.IntegerField(min_value=1)
+    exchange_url = forms.URLField()
+
 ##
 # Form specification that validates GET parameters from a
 # /history request.
@@ -80,6 +133,14 @@ class HistoryParamsBase(forms.Form):
 
 
 class HistoryParams(HistoryParamsBase):
+    
+    def clean_start(self):
+        delta = self.cleaned_data.get("delta")        
+        start = self.cleaned_data.get("start")
+        if None == start:
+            return 0 if 0 <= delta else UINT64_MAX
+        return start
+
     # FIXME: adjust min/max values.
     delta = forms.IntegerField()
     start = forms.IntegerField(required=False)
@@ -133,11 +194,11 @@ class JSONFieldException(ValueError):
     # Init method.
     #
     # @param self the object itself.
-    # @param hint the hint to be displayed along the error.
-    # @param http_status_code HTTP response code to be returned
-    #        along the error.
-    def __init__(self, hint, http_status_code):
-        self.hint = hint
+    # @param error object containing the hint.
+    # @param http_status_code the HTTP response code to return
+    #        to the caller (client).
+    def __init__(self, error, http_status_code):
+        self.hint = json.dumps(error.as_json())
         self.http_status_code = http_status_code
         super().__init__()
 
@@ -196,29 +257,6 @@ AUTH_SCHEMA = {
 
 
 ##
-# Definition for reject request bodies.
-REJECT_REQUEST_SCHEMA = {
-    "type": "object",
-    "properties": {
-        "auth": AUTH_SCHEMA,
-        "row_id": {"type": "integer"},
-        "account_number": {"type": "integer"}
-    }
-}
-
-##
-# Definition for /add/incoming request bodies.
-INCOMING_REQUEST_SCHEMA = {
-    "type": "object",
-    "properties": {
-        "amount": {"type": AMOUNT_SCHEMA},
-        "subject": {"type": "string"},
-        "credit_account": {"type": "integer"},
-        "auth": AUTH_SCHEMA
-    }
-}
-
-##
 # Definition for PIN/TAN request URL parameters.
 PIN_TAN_ARGS = {
     "type": "object",
@@ -268,13 +306,6 @@ def validate_pin_tan(data):
     validate(data, PIN_TAN_ARGS, format_validators=format_dict)
 
 ##
-# Check if the /reject request is valid.
-#
-# @param data POST/PUT body.
-def validate_reject(data):
-    validate(data, REJECT_REQUEST_SCHEMA)
-
-##
 # Check wire details
 # (regardless of which endpoint triggered the check)
 #
@@ -283,14 +314,6 @@ def validate_wiredetails(wiredetails):
     validate(wiredetails, WIREDETAILS_SCHEMA)
 
 ##
-# Check input data for a wire transfer commanded via the
-# HTTP REST service.
-#
-# @param data POST body sent along the request.
-def validate_add_incoming(data):
-    validate(data, INCOMING_REQUEST_SCHEMA)
-
-##
 # Check that the state corresponds to a withdrawal session.
 #
 # @param data the dict representing the server state.  So not
@@ -311,8 +334,6 @@ def check_withdraw_session(data):
 #        request.
 def validate_data(request, data):
     switch = {
-        "/reject": validate_reject,
-        "/admin/add/incoming": validate_add_incoming,
         "/pin/verify": check_withdraw_session,
         "/pin/question": validate_pin_tan
     }
diff --git a/talerbank/app/views.py b/talerbank/app/views.py
index 34a5b70..88e5742 100644
--- a/talerbank/app/views.py
+++ b/talerbank/app/views.py
@@ -44,7 +44,8 @@ from django.shortcuts import render, redirect
 from datetime import datetime
 from .models import BankAccount, BankTransaction
 from .amount import Amount
-from .schemas import validate_data, HistoryParams, HistoryRangeParams, 
URLParamValidationError
+from .schemas import validate_data, HistoryParams, HistoryRangeParams, 
URLParamValidationError, RejectData, AddIncomingData, JSONFieldException
+
 LOGGER = logging.getLogger(__name__)
 
 ##
@@ -743,16 +744,10 @@ def serve_history(request, user_account):
     if not get_params.is_valid():
         raise URLParamValidationError(get_params.errors, 400)
 
-    delta = get_params.cleaned_data.get("delta")
-    start = get_params.cleaned_data.get("start")
-
-    if None == start:
-        start = 0 if 0 <= delta else UINT64_MAX
-
     qs = query_history(user_account.bankaccount,
                        get_params.cleaned_data.get("direction"),
-                       delta,
-                       start,
+                       get_params.cleaned_data.get("delta"),
+                       get_params.cleaned_data.get("start"),
                        get_params.cleaned_data.get("ordering"))
 
     history = build_history_response(
@@ -794,9 +789,6 @@ def auth_and_login(request):
     return django.contrib.auth.authenticate(
         username=username,
         password=password)
-
-
-
 ##
 # Serve a request of /reject (for rejecting wire transfers).
 #
@@ -811,8 +803,12 @@ def auth_and_login(request):
 @login_via_headers
 def reject(request, user_account):
     data = json.loads(request.body.decode("utf-8"))
-    validate_data(request, data)
-    trans = BankTransaction.objects.get(id=data["row_id"])
+    data = RejectData(data)
+
+    if not data.is_valid():
+        raise JSONFieldException(data.errors, 400)
+
+    trans = BankTransaction.objects.get(id=data.cleaned_data.get("row_id"))
     if trans.credit_account.account_no != \
             user_account.bankaccount.account_no:
         raise RejectNoRightsException()
@@ -822,8 +818,6 @@ def reject(request, user_account):
     trans.save()
     return HttpResponse(status=204)
 
-
-
 ##
 # Serve a request to make a wire transfer.  Allows fintech
 # providers to issues payments in a programmatic way.
@@ -837,21 +831,27 @@ def reject(request, user_account):
 @login_via_headers
 def add_incoming(request, user_account):
     data = json.loads(request.body.decode("utf-8"))
-    validate_data(request, data)
-    subject = "%s %s" % (data["subject"], data["exchange_url"])
+    data = AddIncomingData(data)
+
+    if not data.is_valid():
+        raise JSONFieldException(data.errors, 400)
+
+    subject = "%s %s" % (data.cleaned_data["subject"],
+                         data.cleaned_data["exchange_url"])
+
     credit_account = BankAccount.objects.get(
-        account_no=data["credit_account"])
-    wtrans = wire_transfer(Amount.parse(data["amount"]),
-                           user_account.bankaccount,
-                           credit_account,
-                           subject)
+        account_no=data.cleaned_data["credit_account"])
+
+    wtrans = wire_transfer(
+        Amount.parse(data.cleaned_data["amount"]),
+        user_account.bankaccount,
+        credit_account,
+        subject)
+
     return JsonResponse(
         {"row_id": wtrans.id,
          "timestamp": "/Date(%s)/" % int(wtrans.date.timestamp())})
 
-
-
-
 ##
 # Serve a Taler withdrawal request; takes the amount chosen
 # by the user, and builds a response to trigger the wallet into

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



reply via email to

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