diff --git a/bigchaindb/web/views/parameters.py b/bigchaindb/web/views/parameters.py new file mode 100644 index 00000000..9968a659 --- /dev/null +++ b/bigchaindb/web/views/parameters.py @@ -0,0 +1,30 @@ +import re + + +def valid_txid(txid): + if re.match('^[a-fA-F0-9]{64}$', txid): + return txid.lower() + raise ValueError("Invalid hash") + + +def valid_bool(val): + if val == 'true': + return True + if val == 'false': + return False + raise ValueError('Boolean value must be "true" or "false" (lowercase)') + + +def valid_ed25519(key): + if (re.match('^[1-9a-zA-Z]{43,44}$', key) and not + re.match('.*[Il0O]', key)): + return key + raise ValueError("Invalid base58 ed25519 key") + + +def valid_operation(op): + if op == 'CREATE': + return 'CREATE' + if op == 'TRANSFER': + return 'TRANSFER' + raise ValueError('Operation must be "CREATE" or "TRANSFER') diff --git a/bigchaindb/web/views/transactions.py b/bigchaindb/web/views/transactions.py index fa544f65..e61a791f 100644 --- a/bigchaindb/web/views/transactions.py +++ b/bigchaindb/web/views/transactions.py @@ -5,9 +5,11 @@ For more information please refer to the documentation on ReadTheDocs: http-client-server-api.html """ import logging +import re from flask import current_app, request -from flask_restful import Resource +from flask_restful import Resource, reqparse + from bigchaindb.common.exceptions import ( AmountError, @@ -25,6 +27,7 @@ from bigchaindb.common.exceptions import ( import bigchaindb from bigchaindb.models import Transaction from bigchaindb.web.views.base import make_error +from bigchaindb.web.views import parameters logger = logging.getLogger(__name__) @@ -51,6 +54,16 @@ class TransactionApi(Resource): class TransactionListApi(Resource): + def get(self): + parser = reqparse.RequestParser() + parser.add_argument('operation', type=parameters.valid_operation) + parser.add_argument('unspent', type=parameters.valid_bool) + parser.add_argument('public_key', type=parameters.valid_ed25519, + action="append") + parser.add_argument('asset_id', type=parameters.valid_txid) + args = parser.parse_args() + return args + def post(self): """API endpoint to push transactions to the Federation. diff --git a/tests/web/test_parameters.py b/tests/web/test_parameters.py new file mode 100644 index 00000000..4044a273 --- /dev/null +++ b/tests/web/test_parameters.py @@ -0,0 +1,79 @@ +import pytest + + +def test_valid_txid(): + from bigchaindb.web.views.parameters import valid_txid + + valid = ['18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4', + '18AC3E7343F016890C510E93F935261169D9E3F565436429830FAF0934F4F8E4'] + for h in valid: + assert valid_txid(h) == h.lower() + + non = ['18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e', + '18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e45', + '18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8eg', + '18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e ', + ''] + for h in non: + with pytest.raises(ValueError): + valid_txid(h) + + +def test_valid_bool(): + from bigchaindb.web.views.parameters import valid_bool + + assert valid_bool('true') == True + valid_bool('false') == False + + with pytest.raises(ValueError): + valid_bool('TRUE') + with pytest.raises(ValueError): + valid_bool('FALSE') + with pytest.raises(ValueError): + valid_bool('0') + with pytest.raises(ValueError): + valid_bool('1') + with pytest.raises(ValueError): + valid_bool('yes') + with pytest.raises(ValueError): + valid_bool('no') + + +def test_valid_ed25519(): + from bigchaindb.web.views.parameters import valid_ed25519 + + valid = ['123456789abcdefghijkmnopqrstuvwxyz1111111111', + '123456789ABCDEFGHJKLMNPQRSTUVWXYZ1111111111'] + for h in valid: + assert valid_ed25519(h) == h + + with pytest.raises(ValueError): + valid_ed25519('1234556789abcdefghijkmnopqrstuvwxyz1111111') + with pytest.raises(ValueError): + valid_ed25519('1234556789abcdefghijkmnopqrstuvwxyz1111111111') + with pytest.raises(ValueError): + valid_ed25519('123456789abcdefghijkmnopqrstuvwxyz111111111l') + with pytest.raises(ValueError): + valid_ed25519('123456789abcdefghijkmnopqrstuvwxyz111111111I') + with pytest.raises(ValueError): + valid_ed25519('1234556789abcdefghijkmnopqrstuvwxyz11111111O') + with pytest.raises(ValueError): + valid_ed25519('1234556789abcdefghijkmnopqrstuvwxyz111111110') + + +def test_valid_operation(): + from bigchaindb.web.views.parameters import valid_operation + + assert valid_operation('CREATE') == 'CREATE' + assert valid_operation('TRANSFER') == 'TRANSFER' + + with pytest.raises(ValueError): + valid_operation('create') + with pytest.raises(ValueError): + valid_operation('transfer') + with pytest.raises(ValueError): + valid_operation('GENESIS') + with pytest.raises(ValueError): + valid_operation('blah') + with pytest.raises(ValueError): + valid_operation('')