initial commit
This commit is contained in:
commit
7deffc93a4
58
gas3/__init__.py
Normal file
58
gas3/__init__.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# standard imports
|
||||||
|
import os
|
||||||
|
import urllib.parse
|
||||||
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
|
# external imports
|
||||||
|
from leveldir.uuid import UUIDDir
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from gas3.base import do_yield
|
||||||
|
from gas3.register import do_register
|
||||||
|
import gas3.error
|
||||||
|
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
logg = logging.getLogger()
|
||||||
|
|
||||||
|
data_path = os.environ.get('GAS3_DATA_DIR', 'data')
|
||||||
|
data_dir = UUIDDir(data_path)
|
||||||
|
|
||||||
|
re_yield = re.compile('^/yield')
|
||||||
|
re_register = re.compile('^/register')
|
||||||
|
|
||||||
|
|
||||||
|
def application(env, start_response):
|
||||||
|
req = urllib.parse.urlparse(env['REQUEST_URI'])
|
||||||
|
scode = 200
|
||||||
|
stext = 'OK'
|
||||||
|
|
||||||
|
r = ''
|
||||||
|
if re.match(re_yield, req.path):
|
||||||
|
r = do_yield(req, env, data_dir)
|
||||||
|
elif re.match(re_register, req.path):
|
||||||
|
try:
|
||||||
|
r = do_register(req, env, data_dir)
|
||||||
|
except gas3.error.Used:
|
||||||
|
scode = 410
|
||||||
|
stext = 'Code already used'
|
||||||
|
except gas3.error.InvalidInput as e:
|
||||||
|
scode = 400
|
||||||
|
stext = 'Malformed request url'
|
||||||
|
r = str(e)
|
||||||
|
except FileNotFoundError:
|
||||||
|
scode = 403
|
||||||
|
stext = 'No such code'
|
||||||
|
except Exception as e:
|
||||||
|
scode = 500
|
||||||
|
stext = 'Server error'
|
||||||
|
r = str(e)
|
||||||
|
else:
|
||||||
|
r = ''
|
||||||
|
|
||||||
|
|
||||||
|
l = len(r)
|
||||||
|
status = str(scode) + ' ' + stext
|
||||||
|
start_response(status, [('Content-Length', str(l))])
|
||||||
|
return [r.encode('utf-8')]
|
19
gas3/base.py
Normal file
19
gas3/base.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# standard imports
|
||||||
|
import uuid
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def do_yield(req, env, data_dir):
|
||||||
|
u = uuid.uuid4()
|
||||||
|
data_dir.add(u, b'\x00')
|
||||||
|
return str(u)
|
||||||
|
|
||||||
|
|
||||||
|
def check(s, data_dir):
|
||||||
|
p = data_dir.to_filepath(s)
|
||||||
|
f = open(p, 'rb')
|
||||||
|
r = f.read(20)
|
||||||
|
f.close()
|
||||||
|
return len(r) == 1
|
6
gas3/error.py
Normal file
6
gas3/error.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
class InvalidInput(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Used(Exception):
|
||||||
|
pass
|
39
gas3/register.py
Normal file
39
gas3/register.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# standard imports
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# external imports
|
||||||
|
from chainlib.eth.address import to_checksum_address
|
||||||
|
from hexathon import strip_0x
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from gas3.error import InvalidInput
|
||||||
|
from gas3.error import Used
|
||||||
|
from gas3.base import check
|
||||||
|
|
||||||
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def register_address(a):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def do_register(req, env, data_dir):
|
||||||
|
i = req.path.find('/', 1)
|
||||||
|
if i == -1:
|
||||||
|
raise InvalidInput(env.path)
|
||||||
|
p = req.path[i+1:]
|
||||||
|
r = None
|
||||||
|
r = check(p, data_dir)
|
||||||
|
if not r:
|
||||||
|
raise Used('already used: ' + p)
|
||||||
|
|
||||||
|
v = env['wsgi.input'].read(42)
|
||||||
|
if type(v) == bytes:
|
||||||
|
v = v.decode('utf-8')
|
||||||
|
try:
|
||||||
|
v = strip_0x(v)
|
||||||
|
v = to_checksum_address(v)
|
||||||
|
except:
|
||||||
|
raise InvalidInput('invalid address: ' + str(v))
|
||||||
|
|
||||||
|
data_dir.add(p, bytes.fromhex(v))
|
||||||
|
return v
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
leveldir~=0.3.3rc1
|
||||||
|
chainlib-eth~=0.5.2
|
4
test_requirements.txt
Normal file
4
test_requirements.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
eth_tester==0.5.0b3
|
||||||
|
py-evm==0.3.0a20
|
||||||
|
rlp==2.0.1
|
||||||
|
coverage==5.5
|
59
tests/test_register.py
Normal file
59
tests/test_register.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# standard imports
|
||||||
|
import io
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
import tempfile
|
||||||
|
import shutil
|
||||||
|
import logging
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
# external imports
|
||||||
|
from chainlib.eth.unittest.ethtester import EthTesterCase
|
||||||
|
from hexathon import same as is_same_hex
|
||||||
|
from leveldir.uuid import UUIDDir
|
||||||
|
from gas3.base import do_yield
|
||||||
|
from gas3.base import check
|
||||||
|
from gas3.register import do_register
|
||||||
|
import gas3.error
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
|
|
||||||
|
class TestRegister(EthTesterCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestRegister, self).setUp()
|
||||||
|
self.data_path = tempfile.mkdtemp()
|
||||||
|
self.data_dir = UUIDDir(self.data_path)
|
||||||
|
|
||||||
|
|
||||||
|
def test_yield(self):
|
||||||
|
u = do_yield(None, {}, self.data_dir)
|
||||||
|
p = check(u, self.data_dir)
|
||||||
|
self.assertTrue(os.path.exists(p))
|
||||||
|
|
||||||
|
|
||||||
|
def test_register(self):
|
||||||
|
u = do_yield(None, {}, self.data_dir)
|
||||||
|
req = urllib.parse.urlparse('http://localhost/register/' + u)
|
||||||
|
address_file = io.StringIO()
|
||||||
|
address_file.write(self.accounts[0] + '\n')
|
||||||
|
address_file.seek(0)
|
||||||
|
env = {
|
||||||
|
'wsgi.input': address_file,
|
||||||
|
}
|
||||||
|
r = do_register(req, env, self.data_dir)
|
||||||
|
self.assertEqual(len(r), 40)
|
||||||
|
with self.assertRaises(gas3.error.Used):
|
||||||
|
r = do_register(req, env, self.data_dir)
|
||||||
|
|
||||||
|
fp = self.data_dir.to_filepath(u)
|
||||||
|
f = open(fp, 'rb')
|
||||||
|
r = f.read()
|
||||||
|
f.close()
|
||||||
|
self.assertTrue(is_same_hex(r.hex(), self.accounts[0]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
Reference in New Issue
Block a user