mirror of
https://github.com/fuckpiracyshield/service.git
synced 2024-05-20 05:56:17 +02:00
163 lines
5.3 KiB
Python
163 lines
5.3 KiB
Python
from __future__ import annotations
|
|
|
|
from piracyshield_service.base import BaseService
|
|
|
|
from piracyshield_component.security.identifier import Identifier
|
|
from piracyshield_component.utils.time import Time
|
|
from piracyshield_component.exception import ApplicationException
|
|
|
|
from piracyshield_data_model.forensic.archive.model import ForensicArchiveModel, ForensicArchiveModelNameException
|
|
from piracyshield_data_model.forensic.hash.model import ForensicHashModel, ForensicHashModelNotSupportedException, ForensicHashModelStringMissingException, ForensicHashModelNonValidException
|
|
from piracyshield_data_model.forensic.hash.rule import ForensicHashRule
|
|
|
|
from piracyshield_data_storage.forensic.storage import ForensicStorage, ForensicStorageCreateException, ForensicStorageGetException
|
|
|
|
from piracyshield_service.forensic.errors import ForensicErrorCode, ForensicErrorMessage
|
|
|
|
class ForensicCreateHashService(BaseService):
|
|
|
|
"""
|
|
Stores the evidence's hash during the ticket creation.
|
|
"""
|
|
|
|
data_storage = None
|
|
|
|
data_model = None
|
|
|
|
identifier = None
|
|
|
|
def __init__(self):
|
|
"""
|
|
Inizialize logger and required modules.
|
|
"""
|
|
|
|
super().__init__()
|
|
|
|
self._prepare_modules()
|
|
|
|
def execute(self, ticket_id: str, hash_list: list, reporter_id: str) -> bool | Exception:
|
|
for hash_type, hash_string in hash_list.items():
|
|
model = self._validate_parameters(
|
|
hash_type = hash_type,
|
|
hash_string = hash_string
|
|
)
|
|
|
|
document = self._build_document(
|
|
model = model,
|
|
forensic_id = self._generate_forensic_id(),
|
|
ticket_id = ticket_id,
|
|
created_by = reporter_id,
|
|
now = Time.now_iso8601()
|
|
)
|
|
|
|
# let's search for a pre-existent hash
|
|
existent_hash = self._hash_string_exists(hash_string)
|
|
|
|
# we got one, let's update our new entry with those values
|
|
if existent_hash:
|
|
if 'archive_name' in existent_hash:
|
|
document['archive_name'] = existent_hash.get('archive_name')
|
|
|
|
if 'status' in existent_hash:
|
|
document['status'] = existent_hash.get('status')
|
|
|
|
if 'reason' in existent_hash:
|
|
document['reason'] = existent_hash.get('reason')
|
|
|
|
try:
|
|
self.data_storage.insert(document)
|
|
|
|
except ForensicStorageCreateException as e:
|
|
self.logger.error(f"Could not update the ticket's forensic archive hash")
|
|
|
|
raise ApplicationException(ForensicErrorCode.GENERIC, ForensicErrorMessage.GENERIC, e)
|
|
|
|
self.logger.info(f'Created hash `{hash_string}` for ticket `{ticket_id}`')
|
|
|
|
return True
|
|
|
|
def _hash_string_exists(self, hash_string: str) -> bool | Exception:
|
|
try:
|
|
response = self.data_storage.exists_hash_string(
|
|
hash_string = hash_string
|
|
)
|
|
|
|
if response.empty():
|
|
return False
|
|
|
|
self.logger.debug(f'Found pre-existent hash for `{hash_string}`')
|
|
|
|
document = next(response, None)
|
|
|
|
return document
|
|
|
|
except ForensicStorageGetException as e:
|
|
self.logger.error(f'Could not verify `{hash_string}` existence')
|
|
|
|
raise ApplicationException(ForensicErrorCode.GENERIC, ForensicErrorMessage.GENERIC, e)
|
|
|
|
def _build_document(self, model: dict, forensic_id: str, ticket_id: str, created_by: str, now: str):
|
|
return {
|
|
'forensic_id': forensic_id,
|
|
'ticket_id': ticket_id,
|
|
'hash_type': model.get('hash_type'),
|
|
'hash_string': model.get('hash_string'),
|
|
'metadata': {
|
|
'created_at': now,
|
|
'updated_at': now,
|
|
'created_by': created_by
|
|
}
|
|
}
|
|
|
|
def _generate_forensic_id(self) -> str:
|
|
"""
|
|
Generates a UUIDv4.
|
|
|
|
:return: a randomly generated 32 characters string.
|
|
"""
|
|
|
|
return self.identifier.generate()
|
|
|
|
def _validate_parameters(self, hash_type: str, hash_string: str) -> dict | Exception:
|
|
"""
|
|
Validates the inputs.
|
|
|
|
:param hash_type: a supported hash algorithm.
|
|
:param hash_string: a valid hash string.
|
|
:return: the data converted into a usable dictionary.
|
|
"""
|
|
|
|
try:
|
|
model = self.data_model(
|
|
hash_type = hash_type,
|
|
hash_string = hash_string
|
|
)
|
|
|
|
return model.to_dict()
|
|
|
|
except ForensicHashModelNotSupportedException:
|
|
raise ApplicationException(ForensicErrorCode.HASH_TYPE_NOT_SUPPORTED, ForensicErrorMessage.HASH_TYPE_NOT_SUPPORTED)
|
|
|
|
except ForensicHashModelStringMissingException:
|
|
raise ApplicationException(ForensicErrorCode.HASH_STRING_EMPTY, ForensicErrorMessage.HASH_STRING_EMPTY)
|
|
|
|
except ForensicHashModelNonValidException:
|
|
raise ApplicationException(ForensicErrorCode.HASH_STRING_NON_VALID, ForensicErrorMessage.HASH_STRING_NON_VALID)
|
|
|
|
def _schedule_task(self):
|
|
pass
|
|
|
|
def _prepare_configs(self):
|
|
pass
|
|
|
|
def _prepare_modules(self):
|
|
"""
|
|
Initialize and set the instances.
|
|
"""
|
|
|
|
self.data_model = ForensicHashModel
|
|
|
|
self.data_storage = ForensicStorage()
|
|
|
|
self.identifier = Identifier()
|