Skip to content

Commit

Permalink
[IMP] Avoid retrieving twice the ioc from database by changing the bu…
Browse files Browse the repository at this point in the history
…siness layer update method signature
  • Loading branch information
c8y3 committed Oct 16, 2024
1 parent a32e1d6 commit 4017efa
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 22 deletions.
3 changes: 2 additions & 1 deletion source/app/blueprints/graphql/iocs.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ def mutate(root, info, ioc_id, type_id=None, tlp_id=None, value=None, descriptio
request['ioc_enrichment'] = ioc_enrichment
if modification_history:
request['modification_history'] = modification_history
ioc, _ = iocs_update(ioc_id, request)
ioc = iocs_get(ioc_id)
ioc, _ = iocs_update(ioc, request)
return IOCCreate(ioc=ioc)


Expand Down
3 changes: 2 additions & 1 deletion source/app/blueprints/rest/case/case_ioc_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ def case_update_ioc(cur_id, caseid):
ioc_schema = IocSchema()

try:
ioc, msg = iocs_update(cur_id, request.get_json())
ioc = iocs_get(cur_id)
ioc, msg = iocs_update(ioc, request.get_json())
return response_success(msg, data=ioc_schema.dump(ioc))
except BusinessProcessingError as e:
return response_error(e.get_message(), data=e.get_data())
Expand Down
11 changes: 4 additions & 7 deletions source/app/blueprints/rest/v2/case/api_v2_ioc_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,19 +143,16 @@ def get_case_ioc(identifier):
def update_ioc(identifier):
ioc_schema = IocSchemaForAPIV2()
try:
#TODO: We have a useless double get on the IOC object
# one for the access right, another one for the update of the object.
ioc = iocs_get(identifier)
if not ac_fast_check_current_user_has_case_access(ioc.case_id,
[CaseAccessLevel.full_access]):
return ac_api_return_access_denied(caseid=ioc.case_id)

try:
ioc, msg = iocs_update(identifier, request.get_json())
return response_api_success(ioc_schema.dump(ioc))
except BusinessProcessingError as e:
return response_error(e.get_message(), data=e.get_data())
ioc, _ = iocs_update(ioc, request.get_json())
return response_api_success(ioc_schema.dump(ioc))

except ObjectNotFoundError:
return response_api_not_found()

except BusinessProcessingError as e:
return response_error(e.get_message(), data=e.get_data())
8 changes: 2 additions & 6 deletions source/app/business/iocs.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,23 +79,19 @@ def iocs_create(request_json, case_identifier):
raise BusinessProcessingError('Unable to create IOC for internal reasons')


def iocs_update(identifier: int, request_json: dict):
def iocs_update(ioc: Ioc, request_json: dict):
"""
Identifier: the IOC identifier
Request JSON: the Request
"""
try:
ioc = get_ioc(identifier)
if not ioc:
raise BusinessProcessingError('Invalid IOC ID for this case')

# TODO ideally schema validation should be done before, outside the business logic in the REST API
# for that the hook should be called after schema validation
request_data = call_modules_hook('on_preload_ioc_update', data=request_json, caseid=ioc.case_id)

# validate before saving
ioc_schema = IocSchema()
request_data['ioc_id'] = identifier
request_data['ioc_id'] = ioc.ioc_id
request_data['case_id'] = ioc.case_id
ioc_sc = ioc_schema.load(request_data, instance=ioc, partial=True)
ioc_sc.user_id = current_user.id
Expand Down
14 changes: 7 additions & 7 deletions source/app/schema/marshables.py
Original file line number Diff line number Diff line change
Expand Up @@ -1075,28 +1075,28 @@ def verify_data(self, data: Dict[str, Any], **kwargs: Any) -> Dict[str, Any]:
"""
if data.get('ioc_type_id'):
assert_type_mml(input_var=data.get('ioc_type_id'), field_name="ioc_type_id", type=int)
assert_type_mml(input_var=data.get('ioc_type_id'), field_name='ioc_type_id', type=int)
ioc_type = IocType.query.filter(IocType.type_id == data.get('ioc_type_id')).first()
if not ioc_type:
raise marshmallow.exceptions.ValidationError("Invalid IOC type ID", field_name="ioc_type_id")
raise marshmallow.exceptions.ValidationError('Invalid IOC type ID', field_name='ioc_type_id')

if ioc_type.type_validation_regex:
if not re.fullmatch(ioc_type.type_validation_regex, data.get('ioc_value'), re.IGNORECASE):
error = f"The input doesn\'t match the expected format " \
f"(expected: {ioc_type.type_validation_expect or ioc_type.type_validation_regex})"
error = f'The input doesn\'t match the expected format ' \
f'(expected: {ioc_type.type_validation_expect or ioc_type.type_validation_regex})'
raise marshmallow.exceptions.ValidationError(error, field_name="ioc_ioc_value")

if data.get('ioc_tlp_id'):
assert_type_mml(input_var=data.get('ioc_tlp_id'), field_name="ioc_tlp_id", type=int,
assert_type_mml(input_var=data.get('ioc_tlp_id'), field_name='ioc_tlp_id', type=int,
max_val=POSTGRES_INT_MAX)

Tlp.query.filter(Tlp.tlp_id == data.get('ioc_tlp_id')).count()

if data.get('ioc_tags'):
for tag in data.get('ioc_tags').split(','):
if not isinstance(tag, str):
raise marshmallow.exceptions.ValidationError("All items in list must be strings",
field_name="ioc_tags")
raise marshmallow.exceptions.ValidationError('All items in list must be strings',
field_name='ioc_tags')
add_db_tag(tag.strip())

return data
Expand Down

0 comments on commit 4017efa

Please sign in to comment.