implementing more input-validation-functions for shipcalls and ships. Beginning to refactor some of the validation functions into more readable Python classes.
This commit is contained in:
parent
78d7fcbd5b
commit
6349e4a73c
@ -4,7 +4,7 @@ from marshmallow import Schema, fields, ValidationError
|
|||||||
from ..schemas import model
|
from ..schemas import model
|
||||||
from .. import impl
|
from .. import impl
|
||||||
from ..services.auth_guard import auth_guard, check_jwt
|
from ..services.auth_guard import auth_guard, check_jwt
|
||||||
from BreCal.validators.input_validation import validate_posted_shipcall_data
|
from BreCal.validators.input_validation import validate_posted_shipcall_data, check_if_user_is_bsmd_type
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
@ -41,9 +41,6 @@ def PostShipcalls():
|
|||||||
try:
|
try:
|
||||||
content = request.get_json(force=True)
|
content = request.get_json(force=True)
|
||||||
loadedModel = model.ShipcallSchema().load(data=content, many=False, partial=True)
|
loadedModel = model.ShipcallSchema().load(data=content, many=False, partial=True)
|
||||||
logging.log(20, loadedModel)
|
|
||||||
logging.log(20, "dev. above: loaded model, below: content")
|
|
||||||
logging.log(20, content)
|
|
||||||
|
|
||||||
# read the user data from the JWT token (set when login is performed)
|
# read the user data from the JWT token (set when login is performed)
|
||||||
user_data = check_jwt()
|
user_data = check_jwt()
|
||||||
@ -72,6 +69,15 @@ def PutShipcalls():
|
|||||||
content = request.get_json(force=True)
|
content = request.get_json(force=True)
|
||||||
logging.info(content)
|
logging.info(content)
|
||||||
loadedModel = model.ShipcallSchema().load(data=content, many=False, partial=True)
|
loadedModel = model.ShipcallSchema().load(data=content, many=False, partial=True)
|
||||||
|
|
||||||
|
# read the user data from the JWT token (set when login is performed)
|
||||||
|
user_data = check_jwt()
|
||||||
|
|
||||||
|
# check, whether the user belongs to a participant, which is of type ParticipantType.BSMD
|
||||||
|
# as ParticipantType is an IntFlag, a user belonging to multiple groups is properly evaluated.
|
||||||
|
is_bsmd = check_if_user_is_bsmd_type(user_data)
|
||||||
|
if not is_bsmd:
|
||||||
|
raise ValidationError(f"current user does not belong to BSMD. Cannot post shipcalls. Found user data: {user_data}")
|
||||||
|
|
||||||
except ValidationError as ex:
|
except ValidationError as ex:
|
||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
from flask import Blueprint, request
|
from flask import Blueprint, request
|
||||||
from .. import impl
|
from .. import impl
|
||||||
from ..services.auth_guard import auth_guard
|
from ..services.auth_guard import auth_guard, check_jwt
|
||||||
from marshmallow import EXCLUDE
|
from marshmallow import EXCLUDE, ValidationError
|
||||||
from ..schemas import model
|
from ..schemas import model
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from BreCal.validators.input_validation import check_if_user_is_bsmd_type
|
||||||
|
|
||||||
|
|
||||||
bp = Blueprint('ships', __name__)
|
bp = Blueprint('ships', __name__)
|
||||||
|
|
||||||
@bp.route('/ships', methods=['get'])
|
@bp.route('/ships', methods=['get'])
|
||||||
@ -24,6 +27,15 @@ def GetShips():
|
|||||||
def PostShip():
|
def PostShip():
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# read the user data from the JWT token (set when login is performed)
|
||||||
|
user_data = check_jwt()
|
||||||
|
|
||||||
|
# check, whether the user belongs to a participant, which is of type ParticipantType.BSMD
|
||||||
|
# as ParticipantType is an IntFlag, a user belonging to multiple groups is properly evaluated.
|
||||||
|
is_bsmd = check_if_user_is_bsmd_type(user_data)
|
||||||
|
if not is_bsmd:
|
||||||
|
raise ValidationError(f"current user does not belong to BSMD. Cannot post shipcalls. Found user data: {user_data}")
|
||||||
|
|
||||||
content = request.get_json(force=True)
|
content = request.get_json(force=True)
|
||||||
loadedModel = model.ShipSchema().load(data=content, many=False, partial=True)
|
loadedModel = model.ShipSchema().load(data=content, many=False, partial=True)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
@ -39,6 +51,15 @@ def PostShip():
|
|||||||
def PutShip():
|
def PutShip():
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# read the user data from the JWT token (set when login is performed)
|
||||||
|
user_data = check_jwt()
|
||||||
|
|
||||||
|
# check, whether the user belongs to a participant, which is of type ParticipantType.BSMD
|
||||||
|
# as ParticipantType is an IntFlag, a user belonging to multiple groups is properly evaluated.
|
||||||
|
is_bsmd = check_if_user_is_bsmd_type(user_data)
|
||||||
|
if not is_bsmd:
|
||||||
|
raise ValidationError(f"current user does not belong to BSMD. Cannot post shipcalls. Found user data: {user_data}")
|
||||||
|
|
||||||
content = request.get_json(force=True)
|
content = request.get_json(force=True)
|
||||||
loadedModel = model.ShipSchema().load(data=content, many=False, partial=True, unknown=EXCLUDE)
|
loadedModel = model.ShipSchema().load(data=content, many=False, partial=True, unknown=EXCLUDE)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
@ -53,8 +74,16 @@ def PutShip():
|
|||||||
@auth_guard() # no restriction by role
|
@auth_guard() # no restriction by role
|
||||||
def DeleteShip():
|
def DeleteShip():
|
||||||
|
|
||||||
# TODO check if I am allowed to delete this thing by deriving the participant from the bearer token
|
|
||||||
try:
|
try:
|
||||||
|
# read the user data from the JWT token (set when login is performed)
|
||||||
|
user_data = check_jwt()
|
||||||
|
|
||||||
|
# check, whether the user belongs to a participant, which is of type ParticipantType.BSMD
|
||||||
|
# as ParticipantType is an IntFlag, a user belonging to multiple groups is properly evaluated.
|
||||||
|
is_bsmd = check_if_user_is_bsmd_type(user_data)
|
||||||
|
if not is_bsmd:
|
||||||
|
raise ValidationError(f"current user does not belong to BSMD. Cannot post shipcalls. Found user data: {user_data}")
|
||||||
|
|
||||||
if 'id' in request.args:
|
if 'id' in request.args:
|
||||||
options = {}
|
options = {}
|
||||||
options["id"] = request.args.get("id")
|
options["id"] = request.args.get("id")
|
||||||
|
|||||||
@ -89,12 +89,15 @@ def create_postman_stub_shipcall():
|
|||||||
"""
|
"""
|
||||||
this function returns the common stub, which is used to POST data to shipcalls via POSTMAN. However,
|
this function returns the common stub, which is used to POST data to shipcalls via POSTMAN. However,
|
||||||
the stub-function is updated with a dynamic ETA in the future, so the POST-request does not fail.
|
the stub-function is updated with a dynamic ETA in the future, so the POST-request does not fail.
|
||||||
|
|
||||||
|
Also provides a stub arrival_berth_id, so the POST-request succeeds.
|
||||||
"""
|
"""
|
||||||
shipcall = {
|
shipcall = {
|
||||||
'ship_id': 1,
|
'ship_id': 1,
|
||||||
'type': 1,
|
'type': 1,
|
||||||
'eta': (datetime.datetime.now()+datetime.timedelta(hours=3)).isoformat(),
|
'eta': (datetime.datetime.now()+datetime.timedelta(hours=3)).isoformat(),
|
||||||
'voyage': '43B',
|
'voyage': '43B',
|
||||||
|
'arrival_berth_id':142,
|
||||||
'tug_required': False,
|
'tug_required': False,
|
||||||
'pilot_required': True,
|
'pilot_required': True,
|
||||||
'flags': 0,
|
'flags': 0,
|
||||||
|
|||||||
@ -26,6 +26,10 @@ def check_if_string_has_special_characters(text:str):
|
|||||||
"""
|
"""
|
||||||
return bool(set(text).difference(ascii_letters + digits))
|
return bool(set(text).difference(ascii_letters + digits))
|
||||||
|
|
||||||
|
def check_if_int_is_valid_flag(value, enum_object):
|
||||||
|
# e.g., when an IntFlag has the values 1,2,4; the maximum valid value is 7
|
||||||
|
max_int = sum([int(val) for val in list(enum_object._value2member_map_.values())])
|
||||||
|
return 0 < value <= max_int
|
||||||
|
|
||||||
def get_participant_id_dictionary():
|
def get_participant_id_dictionary():
|
||||||
# get all participants
|
# get all participants
|
||||||
@ -126,11 +130,6 @@ def validate_posted_shipcall_data(user_data:dict, loadedModel:dict, content:dict
|
|||||||
"""this function applies more complex validation functions to data, which is sent to a post-request of shipcalls"""
|
"""this function applies more complex validation functions to data, which is sent to a post-request of shipcalls"""
|
||||||
# #TODO_refactor: this function is pretty complex. One may instead build an object, which calls the methods separately.
|
# #TODO_refactor: this function is pretty complex. One may instead build an object, which calls the methods separately.
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.log(20, "dev")
|
|
||||||
logging.log(20, user_data)
|
|
||||||
logging.log(20, loadedModel)
|
|
||||||
logging.log(20, content)
|
|
||||||
##### Section 1: check user_data #####
|
##### Section 1: check user_data #####
|
||||||
# check, whether the user belongs to a participant, which is of type ParticipantType.BSMD
|
# check, whether the user belongs to a participant, which is of type ParticipantType.BSMD
|
||||||
# as ParticipantType is an IntFlag, a user belonging to multiple groups is properly evaluated.
|
# as ParticipantType is an IntFlag, a user belonging to multiple groups is properly evaluated.
|
||||||
@ -205,7 +204,16 @@ def validate_posted_shipcall_data(user_data:dict, loadedModel:dict, content:dict
|
|||||||
raise ValidationError(f"providing 'arrival_berth_id' & 'departure_berth_id' is mandatory. Missing key!")
|
raise ValidationError(f"providing 'arrival_berth_id' & 'departure_berth_id' is mandatory. Missing key!")
|
||||||
if (not eta >= time_now) or (not etd >= time_now) or (not eta >= etd):
|
if (not eta >= time_now) or (not etd >= time_now) or (not eta >= etd):
|
||||||
raise ValidationError(f"'eta' and 'etd' must be in the future. Incorrect datetime provided.")
|
raise ValidationError(f"'eta' and 'etd' must be in the future. Incorrect datetime provided.")
|
||||||
|
|
||||||
|
tidal_window_from = loadedModel.get("tidal_window_from", None)
|
||||||
|
tidal_window_to = loadedModel.get("tidal_window_to", None)
|
||||||
|
if tidal_window_to is not None:
|
||||||
|
if not tidal_window_to >= time_now:
|
||||||
|
raise ValidationError(f"'tidal_window_to' must be in the future. Incorrect datetime provided.")
|
||||||
|
|
||||||
|
if tidal_window_from is not None:
|
||||||
|
if not tidal_window_from >= time_now:
|
||||||
|
raise ValidationError(f"'tidal_window_from' must be in the future. Incorrect datetime provided.")
|
||||||
|
|
||||||
# #TODO: len of participants > 0, if agency
|
# #TODO: len of participants > 0, if agency
|
||||||
# * assigned participant for agency
|
# * assigned participant for agency
|
||||||
|
|||||||
Reference in New Issue
Block a user