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:
Max Metz 2024-04-29 18:50:46 +02:00
parent d81e0e2ecc
commit c1f91a3ef8
5 changed files with 59 additions and 13 deletions

View File

@ -4,7 +4,7 @@ from marshmallow import Schema, fields, ValidationError
from ..schemas import model
from .. import impl
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 json
@ -41,9 +41,6 @@ def PostShipcalls():
try:
content = request.get_json(force=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)
user_data = check_jwt()
@ -72,6 +69,15 @@ def PutShipcalls():
content = request.get_json(force=True)
logging.info(content)
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:
logging.error(ex)

View File

@ -1,11 +1,14 @@
from flask import Blueprint, request
from .. import impl
from ..services.auth_guard import auth_guard
from marshmallow import EXCLUDE
from ..services.auth_guard import auth_guard, check_jwt
from marshmallow import EXCLUDE, ValidationError
from ..schemas import model
import json
import logging
from BreCal.validators.input_validation import check_if_user_is_bsmd_type
bp = Blueprint('ships', __name__)
@bp.route('/ships', methods=['get'])
@ -24,6 +27,15 @@ def GetShips():
def PostShip():
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)
loadedModel = model.ShipSchema().load(data=content, many=False, partial=True)
except Exception as ex:
@ -39,6 +51,15 @@ def PostShip():
def PutShip():
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)
loadedModel = model.ShipSchema().load(data=content, many=False, partial=True, unknown=EXCLUDE)
except Exception as ex:
@ -53,8 +74,16 @@ def PutShip():
@auth_guard() # no restriction by role
def DeleteShip():
# TODO check if I am allowed to delete this thing by deriving the participant from the bearer token
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:
options = {}
options["id"] = request.args.get("id")

View File

@ -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,
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 = {
'ship_id': 1,
'type': 1,
'eta': (datetime.datetime.now()+datetime.timedelta(hours=3)).isoformat(),
'voyage': '43B',
'arrival_berth_id':142,
'tug_required': False,
'pilot_required': True,
'flags': 0,

View File

@ -26,6 +26,10 @@ def check_if_string_has_special_characters(text:str):
"""
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():
# 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"""
# #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 #####
# 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.
@ -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!")
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.")
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
# * assigned participant for agency