If a PUT or DELETE operation is attempted on a non-existant object, 404 is returned
This commit is contained in:
parent
4531eda8f1
commit
0d7861ec36
@ -23,7 +23,7 @@ bp = Blueprint('shipcalls', __name__)
|
|||||||
def GetShipcalls():
|
def GetShipcalls():
|
||||||
try:
|
try:
|
||||||
if 'Authorization' in request.headers:
|
if 'Authorization' in request.headers:
|
||||||
token = request.headers.get('Authorization') # see impl/login to see the token encoding, which is a JWT token.
|
token = request.headers.get('Authorization') # see impl/login to see the token encoding, which is a JWT token.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from BreCal.services.jwt_handler import decode_jwt
|
from BreCal.services.jwt_handler import decode_jwt
|
||||||
@ -34,14 +34,14 @@ def GetShipcalls():
|
|||||||
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
||||||
"""
|
"""
|
||||||
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
||||||
options = {}
|
options = {}
|
||||||
options["past_days"] = request.args.get("past_days", default=1, type=int)
|
options["past_days"] = request.args.get("past_days", default=1, type=int)
|
||||||
options["participant_id"] = payload["participant_id"]
|
options["participant_id"] = payload["participant_id"]
|
||||||
|
|
||||||
return impl.shipcalls.GetShipcalls(options)
|
return impl.shipcalls.GetShipcalls(options)
|
||||||
else:
|
else:
|
||||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||||
|
|
||||||
@ -62,10 +62,10 @@ def PostShipcalls():
|
|||||||
# validate the posted shipcall data & the user's authority
|
# validate the posted shipcall data & the user's authority
|
||||||
InputValidationShipcall.evaluate_post_data(user_data, loadedModel, content)
|
InputValidationShipcall.evaluate_post_data(user_data, loadedModel, content)
|
||||||
return impl.shipcalls.PostShipcalls(loadedModel)
|
return impl.shipcalls.PostShipcalls(loadedModel)
|
||||||
|
|
||||||
except ValidationError as ex:
|
except ValidationError as ex:
|
||||||
return create_validation_error_response(ex=ex, status_code=400)
|
return create_validation_error_response(ex=ex, status_code=400)
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logging.error(traceback.format_exc())
|
logging.error(traceback.format_exc())
|
||||||
return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format")
|
return create_dynamic_exception_response(ex=ex, status_code=400, message="bad format")
|
||||||
@ -77,23 +77,26 @@ def PutShipcalls():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
verify_if_request_is_json(request)
|
verify_if_request_is_json(request)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
# 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()
|
||||||
|
|
||||||
|
if not InputValidationShipcall.exists_shipcall_by_id(loadedModel.get("id")):
|
||||||
|
return create_dynamic_exception_response(ex=None, status_code=404, message="no shipcall found with the provided id")
|
||||||
|
|
||||||
# validate the PUT shipcall data and the user's authority
|
# validate the PUT shipcall data and the user's authority
|
||||||
InputValidationShipcall.evaluate_put_data(user_data, loadedModel, content)
|
InputValidationShipcall.evaluate_put_data(user_data, loadedModel, content)
|
||||||
return impl.shipcalls.PutShipcalls(loadedModel)
|
return impl.shipcalls.PutShipcalls(loadedModel)
|
||||||
|
|
||||||
except ValidationError as ex:
|
except ValidationError as ex:
|
||||||
return create_validation_error_response(ex=ex, status_code=400)
|
return create_validation_error_response(ex=ex, status_code=400)
|
||||||
|
|
||||||
except werkzeug.exceptions.Forbidden as ex:
|
except werkzeug.exceptions.Forbidden as ex:
|
||||||
return create_werkzeug_error_response(ex=ex, status_code=403)
|
return create_werkzeug_error_response(ex=ex, status_code=403)
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logging.error(traceback.format_exc())
|
logging.error(traceback.format_exc())
|
||||||
return create_dynamic_exception_response(ex=None, status_code=400, message="bad format")
|
return create_dynamic_exception_response(ex=None, status_code=400, message="bad format")
|
||||||
|
|||||||
@ -23,7 +23,7 @@ def GetShips():
|
|||||||
return impl.ships.GetShips(token)
|
return impl.ships.GetShips(token)
|
||||||
else:
|
else:
|
||||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ def PostShip():
|
|||||||
is_bsmd = check_if_user_is_bsmd_type(user_data)
|
is_bsmd = check_if_user_is_bsmd_type(user_data)
|
||||||
if not is_bsmd:
|
if not is_bsmd:
|
||||||
raise ValidationError({"participant_type":f"current user does not belong to BSMD. Cannot post shipcalls. Found user data: {user_data}"})
|
raise ValidationError({"participant_type":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)
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ def PostShip():
|
|||||||
|
|
||||||
except ValidationError as ex:
|
except ValidationError as ex:
|
||||||
return create_validation_error_response(ex=ex, status_code=400)
|
return create_validation_error_response(ex=ex, status_code=400)
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
return create_dynamic_exception_response(ex=ex, status_code=400, message=None)
|
return create_dynamic_exception_response(ex=ex, status_code=400, message=None)
|
||||||
|
|
||||||
@ -71,13 +71,16 @@ def PutShip():
|
|||||||
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)
|
||||||
|
|
||||||
|
if not InputValidationShip.exists_ship_by_dict(model=loadedModel):
|
||||||
|
return create_dynamic_exception_response(ex=None, status_code=404, message="no ship found with the provided id")
|
||||||
|
|
||||||
# validate the request data & user permissions
|
# validate the request data & user permissions
|
||||||
InputValidationShip.evaluate_put_data(user_data, loadedModel, content)
|
InputValidationShip.evaluate_put_data(user_data, loadedModel, content)
|
||||||
return impl.ships.PutShip(loadedModel)
|
return impl.ships.PutShip(loadedModel)
|
||||||
|
|
||||||
except ValidationError as ex:
|
except ValidationError as ex:
|
||||||
return create_validation_error_response(ex=ex, status_code=400)
|
return create_validation_error_response(ex=ex, status_code=400)
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||||
|
|
||||||
@ -88,10 +91,10 @@ def DeleteShip():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
verify_if_request_is_json(request)
|
verify_if_request_is_json(request)
|
||||||
|
|
||||||
# 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()
|
||||||
|
|
||||||
if 'id' in request.args:
|
if 'id' in request.args:
|
||||||
options = {}
|
options = {}
|
||||||
options["id"] = request.args.get("id")
|
options["id"] = request.args.get("id")
|
||||||
@ -100,12 +103,16 @@ def DeleteShip():
|
|||||||
|
|
||||||
# validate the request data & user permissions
|
# validate the request data & user permissions
|
||||||
ship_id = request.args.get("id")
|
ship_id = request.args.get("id")
|
||||||
|
|
||||||
|
if not InputValidationShip.exists_ship_by_id(id=ship_id):
|
||||||
|
return create_dynamic_exception_response(ex=None, status_code=404, message="no ship found with the provided id")
|
||||||
|
|
||||||
InputValidationShip.evaluate_delete_data(user_data, ship_id)
|
InputValidationShip.evaluate_delete_data(user_data, ship_id)
|
||||||
return impl.ships.DeleteShip(options)
|
return impl.ships.DeleteShip(options)
|
||||||
|
|
||||||
except ValidationError as ex:
|
except ValidationError as ex:
|
||||||
return create_validation_error_response(ex=ex, status_code=400)
|
return create_validation_error_response(ex=ex, status_code=400)
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@ def GetTimes():
|
|||||||
options = {}
|
options = {}
|
||||||
options["shipcall_id"] = request.args.get("shipcall_id")
|
options["shipcall_id"] = request.args.get("shipcall_id")
|
||||||
return impl.times.GetTimes(options)
|
return impl.times.GetTimes(options)
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||||
|
|
||||||
@ -60,13 +60,16 @@ def PutTimes():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
verify_if_request_is_json(request)
|
verify_if_request_is_json(request)
|
||||||
|
|
||||||
content = request.get_json(force=True)
|
content = request.get_json(force=True)
|
||||||
loadedModel = model.TimesSchema().load(data=content, many=False, partial=True)
|
loadedModel = model.TimesSchema().load(data=content, many=False, partial=True)
|
||||||
|
|
||||||
# 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()
|
||||||
|
|
||||||
|
if not InputValidationTimes.exists_times_by_id(loadedModel.get("id")):
|
||||||
|
return create_dynamic_exception_response(ex=None, status_code=404, message="no times found with the provided id")
|
||||||
|
|
||||||
# validate the request
|
# validate the request
|
||||||
InputValidationTimes.evaluate_put_data(user_data, loadedModel, content)
|
InputValidationTimes.evaluate_put_data(user_data, loadedModel, content)
|
||||||
return impl.times.PutTimes(loadedModel)
|
return impl.times.PutTimes(loadedModel)
|
||||||
@ -91,13 +94,16 @@ def DeleteTimes():
|
|||||||
# 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()
|
||||||
|
|
||||||
|
if not InputValidationTimes.exists_times_by_id(options["id"]):
|
||||||
|
return create_dynamic_exception_response(ex=None, status_code=404, message="no times found with the provided id")
|
||||||
|
|
||||||
# validate the request
|
# validate the request
|
||||||
InputValidationTimes.evaluate_delete_data(user_data, times_id = request.args.get("id"))
|
InputValidationTimes.evaluate_delete_data(user_data, times_id = request.args.get("id"))
|
||||||
|
|
||||||
return impl.times.DeleteTimes(options)
|
return impl.times.DeleteTimes(options)
|
||||||
else:
|
else:
|
||||||
return create_dynamic_exception_response(ex=None, status_code=400, message="Times delete missing argument: id")
|
return create_dynamic_exception_response(ex=None, status_code=400, message="Times delete missing argument: id")
|
||||||
|
|
||||||
except ValidationError as ex:
|
except ValidationError as ex:
|
||||||
return create_validation_error_response(ex=ex, status_code=400)
|
return create_validation_error_response(ex=ex, status_code=400)
|
||||||
|
|
||||||
|
|||||||
@ -4,19 +4,27 @@ import datetime
|
|||||||
def get_user_data_for_id(user_id:int, expiration_time:int=90):
|
def get_user_data_for_id(user_id:int, expiration_time:int=90):
|
||||||
"""debugging function, which is useful to pull user_data from the database, which may be used to create stub data and unit tests"""
|
"""debugging function, which is useful to pull user_data from the database, which may be used to create stub data and unit tests"""
|
||||||
query = "SELECT * FROM user where id = ?id?"
|
query = "SELECT * FROM user where id = ?id?"
|
||||||
pdata = execute_sql_query_standalone(query=query, param={"id":user_id})
|
pdata = execute_sql_query_standalone(query=query, param={"id":user_id}, command_type="single_or_none")
|
||||||
pdata = pdata[0] if len(pdata)>0 else None
|
|
||||||
assert pdata is not None, f"could not find user with id {user_id}"
|
assert pdata is not None, f"could not find user with id {user_id}"
|
||||||
|
|
||||||
user_data = {k:v for k,v in pdata.items() if k in ['id','participant_id','first_name','last_name','user_name','user_phone','user_email']}
|
user_data = {k:v for k,v in pdata.items() if k in ['id','participant_id','first_name','last_name','user_name','user_phone','user_email']}
|
||||||
user_data["exp"] = (datetime.datetime.now()+datetime.timedelta(minutes=expiration_time)).timestamp()
|
user_data["exp"] = (datetime.datetime.now()+datetime.timedelta(minutes=expiration_time)).timestamp()
|
||||||
return user_data
|
return user_data
|
||||||
|
|
||||||
|
|
||||||
def get_times_data_for_id(times_id:int):
|
def get_times_data_for_id(times_id:int):
|
||||||
"""helper function to load previous times data from the database"""
|
"""helper function to load previous times data from the database"""
|
||||||
query = "SELECT * FROM times where id = ?id?"
|
query = "SELECT * FROM times where id = ?id?"
|
||||||
pdata = execute_sql_query_standalone(query=query, param={"id":times_id})
|
pdata = execute_sql_query_standalone(query=query, param={"id":times_id}, command_type="single_or_none")
|
||||||
pdata = pdata[0] if len(pdata)>0 else None
|
return pdata
|
||||||
assert pdata is not None, f"could not find times with id {times_id}"
|
|
||||||
|
def get_ship_data_for_id(ship_id:int):
|
||||||
|
"""helper function to load previous ship data from the database"""
|
||||||
|
query = "SELECT * FROM ship where id = ?id?"
|
||||||
|
pdata = execute_sql_query_standalone(query=query, param={"id":ship_id}, command_type="single_or_none")
|
||||||
|
return pdata
|
||||||
|
|
||||||
|
def get_shipcall_data_for_id(shipcall_id:int):
|
||||||
|
"""helper function to load previous shipcall data from the database"""
|
||||||
|
query = "SELECT * FROM shipcall where id = ?id?"
|
||||||
|
pdata = execute_sql_query_standalone(query=query, param={"id":shipcall_id}, command_type="single_or_none")
|
||||||
return pdata
|
return pdata
|
||||||
@ -6,8 +6,9 @@ from marshmallow import ValidationError
|
|||||||
from string import ascii_letters, digits
|
from string import ascii_letters, digits
|
||||||
|
|
||||||
from BreCal.schemas.model import Ship, Shipcall, Berth, User, Participant, ShipcallType
|
from BreCal.schemas.model import Ship, Shipcall, Berth, User, Participant, ShipcallType
|
||||||
from BreCal.database.sql_handler import execute_sql_query_standalone
|
from BreCal.database.sql_handler import execute_sql_query_standalone
|
||||||
from BreCal.database.sql_queries import SQLQuery
|
from BreCal.database.sql_queries import SQLQuery
|
||||||
|
from BreCal.database.sql_utils import get_ship_data_for_id
|
||||||
from BreCal.impl.participant import GetParticipant
|
from BreCal.impl.participant import GetParticipant
|
||||||
from BreCal.impl.ships import GetShips
|
from BreCal.impl.ships import GetShips
|
||||||
from BreCal.impl.berths import GetBerths
|
from BreCal.impl.berths import GetBerths
|
||||||
@ -17,6 +18,7 @@ from BreCal.validators.input_validation_utils import check_if_user_is_bsmd_type,
|
|||||||
from BreCal.database.sql_handler import execute_sql_query_standalone
|
from BreCal.database.sql_handler import execute_sql_query_standalone
|
||||||
from BreCal.validators.validation_base_utils import check_if_int_is_valid_flag
|
from BreCal.validators.validation_base_utils import check_if_int_is_valid_flag
|
||||||
from BreCal.validators.validation_base_utils import check_if_string_has_special_characters
|
from BreCal.validators.validation_base_utils import check_if_string_has_special_characters
|
||||||
|
|
||||||
import werkzeug
|
import werkzeug
|
||||||
|
|
||||||
class InputValidationShip():
|
class InputValidationShip():
|
||||||
@ -27,23 +29,34 @@ class InputValidationShip():
|
|||||||
Example:
|
Example:
|
||||||
InputValidationShip.evaluate(user_data, loadedModel, content)
|
InputValidationShip.evaluate(user_data, loadedModel, content)
|
||||||
|
|
||||||
When the data violates one of the rules, a marshmallow.ValidationError is raised, which details the issues.
|
When the data violates one of the rules, a marshmallow.ValidationError is raised, which details the issues.
|
||||||
"""
|
"""
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def exists_ship_by_dict(model:dict):
|
||||||
|
ship_id = model.get("id")
|
||||||
|
if(ship_id is not None):
|
||||||
|
return get_ship_data_for_id(ship_id) is not None
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def exists_ship_by_id(id:int):
|
||||||
|
return get_ship_data_for_id(id) is not None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def evaluate_post_data(user_data:dict, loadedModel:dict, content:dict):
|
def evaluate_post_data(user_data:dict, loadedModel:dict, content:dict):
|
||||||
# 1.) Only users of type BSMD are allowed to POST
|
# 1.) Only users of type BSMD are allowed to POST
|
||||||
InputValidationShip.check_user_is_bsmd_type(user_data)
|
InputValidationShip.check_user_is_bsmd_type(user_data)
|
||||||
|
|
||||||
# 2.) The ship IMOs are used as matching keys. They must be unique in the database.
|
# 2.) The ship IMOs are used as matching keys. They must be unique in the database.
|
||||||
InputValidationShip.check_ship_imo_already_exists(loadedModel)
|
InputValidationShip.check_ship_imo_already_exists(loadedModel)
|
||||||
|
|
||||||
# 3.) Check for reasonable Values (see BreCal.schemas.model.ShipSchema)
|
# 3.) Check for reasonable Values (see BreCal.schemas.model.ShipSchema)
|
||||||
InputValidationShip.optionally_evaluate_bollard_pull_value(content)
|
InputValidationShip.optionally_evaluate_bollard_pull_value(content)
|
||||||
return
|
return
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def evaluate_put_data(user_data:dict, loadedModel:dict, content:dict):
|
def evaluate_put_data(user_data:dict, loadedModel:dict, content:dict):
|
||||||
# 1.) Only users of type BSMD are allowed to PUT
|
# 1.) Only users of type BSMD are allowed to PUT
|
||||||
@ -58,20 +71,20 @@ class InputValidationShip():
|
|||||||
# 4.) Check for reasonable Values (see BreCal.schemas.model.ShipSchema)
|
# 4.) Check for reasonable Values (see BreCal.schemas.model.ShipSchema)
|
||||||
InputValidationShip.optionally_evaluate_bollard_pull_value(content)
|
InputValidationShip.optionally_evaluate_bollard_pull_value(content)
|
||||||
return
|
return
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def evaluate_delete_data(user_data:dict, ship_id:typing.Optional[int]):
|
def evaluate_delete_data(user_data:dict, ship_id:typing.Optional[int]):
|
||||||
if ship_id is None:
|
if ship_id is None:
|
||||||
raise ValidationError({"id":f"The ship id must be provided."})
|
raise ValidationError({"id":f"The ship id must be provided."})
|
||||||
ship_id = int(ship_id)
|
ship_id = int(ship_id)
|
||||||
|
|
||||||
# 1.) Only users of type BSMD are allowed to PUT
|
# 1.) Only users of type BSMD are allowed to PUT
|
||||||
InputValidationShip.check_user_is_bsmd_type(user_data)
|
InputValidationShip.check_user_is_bsmd_type(user_data)
|
||||||
|
|
||||||
# 2.) The dataset entry may not be deleted already
|
# 2.) The dataset entry may not be deleted already
|
||||||
InputValidationShip.check_if_entry_is_already_deleted(ship_id)
|
InputValidationShip.check_if_entry_is_already_deleted(ship_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def optionally_evaluate_bollard_pull_value(content:dict):
|
def optionally_evaluate_bollard_pull_value(content:dict):
|
||||||
bollard_pull = content.get("bollard_pull",None)
|
bollard_pull = content.get("bollard_pull",None)
|
||||||
@ -89,7 +102,7 @@ class InputValidationShip():
|
|||||||
is_bsmd = check_if_user_is_bsmd_type(user_data)
|
is_bsmd = check_if_user_is_bsmd_type(user_data)
|
||||||
if not is_bsmd:
|
if not is_bsmd:
|
||||||
raise ValidationError({"participant_type":f"current user does not belong to BSMD. Cannot post, put or delete ships. Found user data: {user_data}"})
|
raise ValidationError({"participant_type":f"current user does not belong to BSMD. Cannot post, put or delete ships. Found user data: {user_data}"})
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_ship_imo_already_exists(loadedModel:dict):
|
def check_ship_imo_already_exists(loadedModel:dict):
|
||||||
# get the ships, convert them to a list of JSON dictionaries
|
# get the ships, convert them to a list of JSON dictionaries
|
||||||
@ -104,28 +117,28 @@ class InputValidationShip():
|
|||||||
if imo_already_exists:
|
if imo_already_exists:
|
||||||
raise ValidationError({"imo":f"the provided ship IMO {loadedModel.get('imo')} already exists. A ship may only be added, if there is no other ship with the same IMO number."})
|
raise ValidationError({"imo":f"the provided ship IMO {loadedModel.get('imo')} already exists. A ship may only be added, if there is no other ship with the same IMO number."})
|
||||||
return
|
return
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def put_content_may_not_contain_imo_number(content:dict):
|
def put_content_may_not_contain_imo_number(content:dict):
|
||||||
# IMO is a required field, so it will never be None outside of tests. If so, there is no violation
|
# IMO is a required field, so it will never be None outside of tests. If so, there is no violation
|
||||||
put_data_ship_imo = content.get("imo",None)
|
put_data_ship_imo = content.get("imo",None)
|
||||||
if put_data_ship_imo is None:
|
if put_data_ship_imo is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# grab the ship by its ID and compare, whether the IMO is unchanged
|
# grab the ship by its ID and compare, whether the IMO is unchanged
|
||||||
ship = execute_sql_query_standalone(SQLQuery.get_ship_by_id(), param={"id":content.get("id")}, command_type="single", model=Ship)
|
ship = execute_sql_query_standalone(SQLQuery.get_ship_by_id(), param={"id":content.get("id")}, command_type="single", model=Ship)
|
||||||
|
|
||||||
if put_data_ship_imo != ship.imo:
|
if put_data_ship_imo != ship.imo:
|
||||||
raise ValidationError({"imo":f"The IMO number field may not be changed since it serves the purpose of a primary (matching) key."})
|
raise ValidationError({"imo":f"The IMO number field may not be changed since it serves the purpose of a primary (matching) key."})
|
||||||
return
|
return
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def content_contains_ship_id(content:dict):
|
def content_contains_ship_id(content:dict):
|
||||||
put_data_ship_id = content.get('id',None)
|
put_data_ship_id = content.get('id',None)
|
||||||
if put_data_ship_id is None:
|
if put_data_ship_id is None:
|
||||||
raise ValidationError({"id":f"The id field is required."})
|
raise ValidationError({"id":f"The id field is required."})
|
||||||
return
|
return
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_if_entry_is_already_deleted(ship_id:typing.Optional[int]):
|
def check_if_entry_is_already_deleted(ship_id:typing.Optional[int]):
|
||||||
"""
|
"""
|
||||||
@ -147,4 +160,4 @@ class InputValidationShip():
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@ from BreCal.impl.ships import GetShips
|
|||||||
from BreCal.impl.berths import GetBerths
|
from BreCal.impl.berths import GetBerths
|
||||||
|
|
||||||
from BreCal.database.enums import ParticipantType, ParticipantFlag
|
from BreCal.database.enums import ParticipantType, ParticipantFlag
|
||||||
|
from BreCal.database.sql_utils import get_shipcall_data_for_id
|
||||||
from BreCal.validators.input_validation_utils import check_if_user_is_bsmd_type, check_if_ship_id_is_valid, check_if_berth_id_is_valid, check_if_participant_ids_are_valid, check_if_participant_ids_and_types_are_valid, get_shipcall_id_dictionary, get_participant_type_from_user_data
|
from BreCal.validators.input_validation_utils import check_if_user_is_bsmd_type, check_if_ship_id_is_valid, check_if_berth_id_is_valid, check_if_participant_ids_are_valid, check_if_participant_ids_and_types_are_valid, get_shipcall_id_dictionary, get_participant_type_from_user_data
|
||||||
from BreCal.database.sql_handler import get_assigned_participant_of_type
|
from BreCal.database.sql_handler import get_assigned_participant_of_type
|
||||||
from BreCal.database.sql_handler import execute_sql_query_standalone
|
from BreCal.database.sql_handler import execute_sql_query_standalone
|
||||||
@ -98,6 +99,10 @@ class InputValidationShipcall():
|
|||||||
InputValidationShipcall.check_shipcall_is_canceled(loadedModel, content)
|
InputValidationShipcall.check_shipcall_is_canceled(loadedModel, content)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def exists_shipcall_by_id(id:int):
|
||||||
|
return get_shipcall_data_for_id(id) is not None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_shipcall_values(loadedModel:dict, content:dict, forbidden_keys:list=["evaluation", "evaluation_message"], is_put_data:bool=False):
|
def check_shipcall_values(loadedModel:dict, content:dict, forbidden_keys:list=["evaluation", "evaluation_message"], is_put_data:bool=False):
|
||||||
"""
|
"""
|
||||||
@ -127,7 +132,7 @@ class InputValidationShipcall():
|
|||||||
if is_put_data:
|
if is_put_data:
|
||||||
# the type of a shipcall may not be changed. It can only be set with the initial POST-request.
|
# the type of a shipcall may not be changed. It can only be set with the initial POST-request.
|
||||||
InputValidationShipcall.check_shipcall_type_is_unchanged(loadedModel)
|
InputValidationShipcall.check_shipcall_type_is_unchanged(loadedModel)
|
||||||
|
|
||||||
InputValidationShipcall.check_times_are_in_future(loadedModel, content)
|
InputValidationShipcall.check_times_are_in_future(loadedModel, content)
|
||||||
|
|
||||||
# some arguments must not be provided
|
# some arguments must not be provided
|
||||||
@ -365,7 +370,7 @@ class InputValidationShipcall():
|
|||||||
"""
|
"""
|
||||||
if (eta is None) and (etd is None):
|
if (eta is None) and (etd is None):
|
||||||
return
|
return
|
||||||
|
|
||||||
time_in_a_year = time_now.replace(time_now.year + 1)
|
time_in_a_year = time_now.replace(time_now.year + 1)
|
||||||
|
|
||||||
if type_ is None:
|
if type_ is None:
|
||||||
@ -419,7 +424,7 @@ class InputValidationShipcall():
|
|||||||
raise ValidationError({"eta":f"'eta' is more than a year in the future. ETA: {eta}."})
|
raise ValidationError({"eta":f"'eta' is more than a year in the future. ETA: {eta}."})
|
||||||
if etd > time_in_a_year:
|
if etd > time_in_a_year:
|
||||||
raise ValidationError({"etd":f"'etd' is more than a year in the future. ETD: {etd}."})
|
raise ValidationError({"etd":f"'etd' is more than a year in the future. ETD: {etd}."})
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -442,7 +447,7 @@ class InputValidationShipcall():
|
|||||||
if (tidal_window_to is not None) and (tidal_window_from is not None):
|
if (tidal_window_to is not None) and (tidal_window_from is not None):
|
||||||
if tidal_window_to < tidal_window_from:
|
if tidal_window_to < tidal_window_from:
|
||||||
raise ValidationError({"tidal_window_to_or_tidal_window_from":f"'tidal_window_to' must take place after 'tidal_window_from'. Incorrect datetime provided. Found 'tidal_window_to': {tidal_window_to}, 'tidal_window_from': {tidal_window_to}."})
|
raise ValidationError({"tidal_window_to_or_tidal_window_from":f"'tidal_window_to' must take place after 'tidal_window_from'. Incorrect datetime provided. Found 'tidal_window_to': {tidal_window_to}, 'tidal_window_from': {tidal_window_to}."})
|
||||||
|
|
||||||
if (tidal_window_to is not None and tidal_window_from is None) or (tidal_window_to is None and tidal_window_from is not None):
|
if (tidal_window_to is not None and tidal_window_from is None) or (tidal_window_to is None and tidal_window_from is not None):
|
||||||
raise ValidationError({"tidal_window_to_or_tidal_window_from":f"'tidal_window_to' and 'tidal_window_from' must both be provided."})
|
raise ValidationError({"tidal_window_to_or_tidal_window_from":f"'tidal_window_to' and 'tidal_window_from' must both be provided."})
|
||||||
|
|
||||||
|
|||||||
@ -128,6 +128,10 @@ class InputValidationTimes():
|
|||||||
InputValidationTimes.check_user_belongs_to_same_group_as_dataset_determines(user_data, loadedModel=None, times_id=times_id)
|
InputValidationTimes.check_user_belongs_to_same_group_as_dataset_determines(user_data, loadedModel=None, times_id=times_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def exists_times_by_id(id:int):
|
||||||
|
return get_times_data_for_id(id) is not None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_if_entry_is_already_deleted(times_id:int):
|
def check_if_entry_is_already_deleted(times_id:int):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user