diff --git a/controllers/room.py b/controllers/room.py index ab1821ec31a05afe35907e4df144f0e91230e544..0fcd9ea31292a0e5d116bb7a6970f01b664c5034 100644 --- a/controllers/room.py +++ b/controllers/room.py @@ -1,21 +1,25 @@ -from utils import JSON_BODY +from parameter_util import JSON_BODY, JSON_CONTAINS +from http_util import FAIL, CODE_JSON, CODE_MISSING, CODE_SEMANTIC -import json import random def create(): parameters = JSON_BODY(request) if parameters == None: - response.status = 406 - return(406) + return(FAIL(CODE_JSON)) - if not 'player_max' in parameters: - response.status = 400 - return(400) + if not JSON_CONTAINS(parameters, [('player_max', int)]): + return(FAIL(CODE_MISSING)) - player_max = int(parameters['player_max']) + player_max = parameters['player_max'] - ret = {"room_code": str(random.randint(1000,9999)), "room_uid": str(random.randint(10000,99999))} + if player_max <= 0: + return(FAIL(CODE_SEMANTIC)) - return(response.json(ret)+"\n") + room_id = db.Room.insert(player_max=player_max) + room_record = db(db.Room.id == room_id).select().first() + + json = {"room_id": room_id, "room_code": room_record.code, "room_pw": room_record.hashcode} + + return(response.json(json)) diff --git a/models/b_dummy.py b/models/b_dummy.py index 838980eb8cb2f9f481777eaaaea7ea29e9799a9b..3f8e10812dd43af178f72f478a085bc097d3f333 100644 --- a/models/b_dummy.py +++ b/models/b_dummy.py @@ -3,6 +3,7 @@ from gluon import current current.db = db #Expose db to modules current.auth = auth #Expose auth to modules current.request = request #Expose request to modules +current.response = response #Expose response to module #Reload every module on change from gluon.custom_import import track_changes; track_changes(True) diff --git a/models/f_room.py b/models/f_room.py new file mode 100644 index 0000000000000000000000000000000000000000..8b985dc0956a3833c25289715543cd8d0f0538fa --- /dev/null +++ b/models/f_room.py @@ -0,0 +1,34 @@ +import random +from hashlib import blake2b + +db.define_table( + 'Room', + Field('code', 'string', notnull=True, requires=IS_NOT_EMPTY(), writable=False, unique=True), + Field('hashcode', 'string', notnull=True, requires=IS_NOT_EMPTY(), writable=False), + Field('player_max', 'integer', notnull=True, requires=IS_NOT_EMPTY()), + Field('creation', 'datetime', default=request.now, notnull=True, requires=IS_NOT_EMPTY()), + Field('heartbeat', 'datetime', default=request.now, notnull=True, requires=IS_NOT_EMPTY()) +) + +def generateRoomCode(_record): + code = None + + while not code or db(db.Room.code == code).count() > 0: + code = "" + for i in range(4): + # Removed characters which could be confused like 0 and O + code = code + random.choice("346789ABCDEFGHJKLMNPQRTUVWXY") + + return(code) + +def generateHashCode(_record): + code = "" + digest = blake2b(digest_size=32) + digest.update(_record.code.encode("utf-8")) + digest.update(str(_record.player_max).encode("utf-8")) + digest.update(str(_record.creation).encode("utf-8")) + digest.update(str(random.random()).encode("utf-8")) + return (digest.hexdigest()) + +db.Room.code.compute = generateRoomCode +db.Room.hashcode.compute = generateHashCode diff --git a/modules/http_util.py b/modules/http_util.py new file mode 100644 index 0000000000000000000000000000000000000000..e641fd6c4f26d9ca79e2cd50ea246fab59e473dc --- /dev/null +++ b/modules/http_util.py @@ -0,0 +1,9 @@ +from gluon import * + +CODE_MISSING = 400 +CODE_JSON = 406 +CODE_SEMANTIC = 422 + +def FAIL(_code): + current.response.status = _code + return(_code) diff --git a/modules/parameter_util.py b/modules/parameter_util.py new file mode 100644 index 0000000000000000000000000000000000000000..2fed05cf85717d8185fb0d9dcfba5e8a97f86d44 --- /dev/null +++ b/modules/parameter_util.py @@ -0,0 +1,29 @@ +from gluon import * + +import json + +def JSON_BODY(_request): + try: + ret = json.loads(_request.body.read()) + + if not ret: + ret = {} + + if not isinstance(ret, dict): + return(None) + + return (ret) + except json.decoder.JSONDecodeError as error: + return (None) + + +def JSON_CONTAINS(_json, _list): + for pair in _list: + + element = pair[0] + t = pair[1] + + if not element in _json or not isinstance(_json[element], t): + return (False) + + return (True) diff --git a/modules/utils.py b/modules/utils.py deleted file mode 100644 index bd522b28c46af70dbf992a1a92c98f5b762c3de8..0000000000000000000000000000000000000000 --- a/modules/utils.py +++ /dev/null @@ -1,13 +0,0 @@ -from gluon import * - -import json - -def JSON_BODY(_request): - try: - ret = json.loads(_request.body.read()) - if not ret: - ret = {} - - return (ret) - except json.decoder.JSONDecodeError as error: - return (None)