[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] [taler-bank] branch master updated: implement /reject,
gnunet <=