718 lines
21 KiB
Python
718 lines
21 KiB
Python
from django.http import JsonResponse
|
|
import logging
|
|
|
|
from django.core.exceptions import ObjectDoesNotExist
|
|
|
|
from .analyze import analyze_hashes, analyze_url
|
|
from .models import *
|
|
from .exception_handling import handle_exceptions
|
|
from rest_framework.views import APIView
|
|
from rest_framework.response import Response
|
|
from rest_framework import status
|
|
|
|
# Logger configuration
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Generic function for retrieving objects with error handling and JSON response.
|
|
@handle_exceptions
|
|
def generic_get_objects(model_class, filter_kwargs=None, select_related_fields=None, message="Objekte"):
|
|
|
|
# Build queryset
|
|
queryset = model_class.objects.all()
|
|
|
|
if select_related_fields:
|
|
queryset = queryset.select_related(*select_related_fields)
|
|
|
|
if filter_kwargs:
|
|
queryset = queryset.filter(**filter_kwargs)
|
|
|
|
if not queryset.exists():
|
|
raise ObjectDoesNotExist(f'Keine {message} gefunden')
|
|
|
|
data_list = [obj.to_json() for obj in queryset]
|
|
return data_list
|
|
|
|
|
|
|
|
#Corrected because we need a dictionary as input for Rest
|
|
# return JsonResponse({
|
|
# 'status': 'success',
|
|
# 'message': f'{len(data_list)} {message} gefunden',
|
|
# 'data': data_list
|
|
# }, status=200)
|
|
|
|
# Generic function for retrieving a single object by its ID.
|
|
@handle_exceptions
|
|
def generic_get_object_by_id(model_class, object_id, select_related_fields=None, message="Objekt"):
|
|
# Build queryset
|
|
queryset = model_class.objects
|
|
|
|
if select_related_fields:
|
|
queryset = queryset.select_related(*select_related_fields)
|
|
|
|
# Get call raises ObjectDoesNotExist when not found
|
|
obj = queryset.get(id=object_id)
|
|
|
|
return (obj.to_json())
|
|
# return {
|
|
# 'status': 'success',
|
|
# 'message': f'{message} gefunden',
|
|
# 'data': [obj.to_json()]
|
|
# }
|
|
|
|
# @handle_exceptions does not need to be used for functions that only call generic functions,
|
|
# since the generic functions already contain error handling.
|
|
|
|
### Manufacturer Functions ###
|
|
# Returns all manufacturers.
|
|
def get_all_manufacturers():
|
|
|
|
return generic_get_objects(Manufacturer, message="Hersteller")
|
|
|
|
|
|
|
|
# Returns a single manufacturer by its ID.
|
|
def get_manufacturer_by_id(manufacturer_id):
|
|
|
|
return generic_get_object_by_id(Manufacturer, manufacturer_id, message="Hersteller")
|
|
|
|
### Device Type Functions ###
|
|
# Returns all device types.
|
|
def get_all_device_types():
|
|
|
|
return generic_get_objects(DeviceType, message="Gerätetypen")
|
|
|
|
# Returns a single device type by its ID.
|
|
def get_device_type_by_id(device_type_id):
|
|
|
|
return generic_get_object_by_id(DeviceType, device_type_id, message="Gerätetyp")
|
|
|
|
# Returns all device types of a specific manufacturer.
|
|
def get_device_types_by_manufacturer(manufacturer_id):
|
|
|
|
return generic_get_objects(
|
|
DeviceType,
|
|
filter_kwargs={'manufacturer': manufacturer_id},
|
|
select_related_fields=['manufacturer'],
|
|
message="Gerätetypen"
|
|
)
|
|
|
|
### Product Functions ###
|
|
# Returns all products.
|
|
def get_all_products():
|
|
|
|
return generic_get_objects(
|
|
Product,
|
|
select_related_fields=['manufacturer', 'device_type'],
|
|
message="Produkte"
|
|
)
|
|
|
|
# Returns a single product by its ID.
|
|
def get_product_by_id(product_id):
|
|
|
|
return generic_get_object_by_id(
|
|
Product,
|
|
product_id,
|
|
select_related_fields=['manufacturer', 'device_type'],
|
|
message="Produkt"
|
|
)
|
|
|
|
# Returns all products of a specific manufacturer.
|
|
def get_products_by_manufacturer(manufacturer_id):
|
|
|
|
return generic_get_objects(
|
|
Product,
|
|
filter_kwargs={'manufacturer': manufacturer_id},
|
|
select_related_fields=['manufacturer', 'device_type'],
|
|
message="Produkte"
|
|
)
|
|
|
|
# Returns all products of a specific device type.
|
|
def get_products_by_device_type(device_type_id):
|
|
|
|
return generic_get_objects(
|
|
Product,
|
|
filter_kwargs={'device_type': device_type_id},
|
|
select_related_fields=['manufacturer', 'device_type'],
|
|
message="Produkte"
|
|
)
|
|
|
|
### Firmware Functions ###
|
|
# Returns all firmwares.
|
|
def get_all_firmwares():
|
|
|
|
return generic_get_objects(
|
|
Firmware,
|
|
select_related_fields=['product'],
|
|
message="Firmwares"
|
|
)
|
|
|
|
# Returns a single firmware by its ID.
|
|
def get_firmware_by_id(firmware_id):
|
|
|
|
return generic_get_object_by_id(
|
|
Firmware,
|
|
firmware_id,
|
|
select_related_fields=['product'],
|
|
message="Firmware"
|
|
)
|
|
|
|
# Returns all firmwares of a specific product.
|
|
def get_firmwares_by_product(product_id):
|
|
|
|
return generic_get_objects(
|
|
Firmware,
|
|
filter_kwargs={'product': product_id},
|
|
select_related_fields=['product'],
|
|
message="Firmwares"
|
|
)
|
|
|
|
# Returns all firmwares of a specific device.
|
|
def get_firmwares_by_device(device_id):
|
|
|
|
return generic_get_objects(
|
|
Firmware,
|
|
filter_kwargs={'devices': device_id},
|
|
select_related_fields=['product'],
|
|
message="Firmwares"
|
|
)
|
|
|
|
### Device Functions ###
|
|
##Returns all test devices including the complete manufacturer dataset.
|
|
def get_all_devices():
|
|
|
|
devices = Device.objects.select_related('product', 'product__manufacturer', 'product__device_type')
|
|
device_data = []
|
|
for device in devices:
|
|
device_data.append({
|
|
'id': device.id,
|
|
'manufacturer_name': device.product.manufacturer.name,
|
|
'device_type': device.product.device_type.device_type,
|
|
'device_name': device.product.product_name,
|
|
'serial': device.serial,
|
|
'comment:': device.comment,
|
|
'created:': device.created,
|
|
})
|
|
return device_data
|
|
|
|
# Returns a single test device by its ID.
|
|
def get_devices_by_product(product_id):
|
|
|
|
return generic_get_objects(
|
|
Device,
|
|
filter_kwargs={'product': product_id},
|
|
select_related_fields=['product'],
|
|
message="Geräte"
|
|
)
|
|
|
|
# Returns a single test device by its ID.
|
|
def get_device_by_id(device_id):
|
|
|
|
return generic_get_object_by_id(
|
|
Device,
|
|
device_id,
|
|
select_related_fields=['product'],
|
|
message="Gerät"
|
|
)
|
|
|
|
### File Functions ###
|
|
# Returns all file entries.
|
|
def get_all_files():
|
|
|
|
return generic_get_objects(
|
|
File,
|
|
select_related_fields=['firmware', 'device'],
|
|
message="Dateien"
|
|
)
|
|
|
|
# Returns a single file entry by its ID.
|
|
def get_file_by_id(file_id):
|
|
|
|
return generic_get_object_by_id(
|
|
File,
|
|
file_id,
|
|
select_related_fields=['firmware', 'device'],
|
|
message="Datei"
|
|
)
|
|
|
|
# Returns all file entries of a specific device.
|
|
def get_files_by_device(device_id: int):
|
|
files = File.objects.filter(device_id=device_id).select_related('firmware', 'firmware__product')
|
|
|
|
device_data = []
|
|
for file in files:
|
|
device_data.append({
|
|
'id': file.id,
|
|
'filename': file.filename,
|
|
'ip': file.ip_address,
|
|
'state': file.status,
|
|
'upload': file.upload_time,
|
|
'firmware_version': file.firmware.version,
|
|
'product': file.firmware.product.product_name
|
|
})
|
|
return device_data
|
|
|
|
# Returns all file entries of a specific firmware.
|
|
def get_files_by_firmware(firmware_id):
|
|
|
|
return generic_get_objects(
|
|
File,
|
|
filter_kwargs={'firmware': firmware_id},
|
|
select_related_fields=['firmware', 'device'],
|
|
message="Dateien"
|
|
)
|
|
|
|
### Raw_Data Functions ###
|
|
# Returns all raw data from all files.
|
|
@handle_exceptions
|
|
def get_all_raw_data():
|
|
|
|
raw_datasets = RawDataset.objects.prefetch_related(
|
|
'file',
|
|
'dnsraw_set',
|
|
'hashraw_set',
|
|
'urlraw_set'
|
|
).all()
|
|
|
|
if not raw_datasets.exists():
|
|
raise ObjectDoesNotExist('Keine Rohdaten gefunden')
|
|
|
|
# Extended to_json function for complete data
|
|
def raw_dataset_to_detailed_json(dataset):
|
|
base_json = dataset.to_json()
|
|
base_json.update({
|
|
'dns_data': [dns.to_json() for dns in dataset.dnsraw_set.all()],
|
|
'hash_data': [hash.to_json() for hash in dataset.hashraw_set.all()],
|
|
'url_data': [url.to_json() for url in dataset.urlraw_set.all()]
|
|
})
|
|
return base_json
|
|
|
|
data_list = [raw_dataset_to_detailed_json(obj) for obj in raw_datasets]
|
|
|
|
return JsonResponse({
|
|
'status': 'success',
|
|
'message': f'{len(data_list)} Rohdaten gefunden',
|
|
'data': data_list
|
|
}, status=200)
|
|
|
|
# Tools
|
|
# Returns all used tools
|
|
def get_all_tools():
|
|
|
|
return generic_get_objects(
|
|
Tool,
|
|
message="Tools")
|
|
|
|
# Returns all raw data for the relevant file.
|
|
@handle_exceptions
|
|
def get_raw_data_by_file(file_id: int):
|
|
|
|
raw_dataset = RawDataset.objects.select_related(
|
|
'file'
|
|
).prefetch_related(
|
|
'dnsraw_set',
|
|
'hashraw_set',
|
|
'urlraw_set'
|
|
).get(file_id=file_id)
|
|
|
|
def raw_dataset_to_detailed_json(dataset):
|
|
base_json = dataset.to_json()
|
|
base_json.update({
|
|
'dns_data': [dns.to_json() for dns in dataset.dnsraw_set.all()],
|
|
'hash_data': [hash.to_json() for hash in dataset.hashraw_set.all()],
|
|
'url_data': [url.to_json() for url in dataset.urlraw_set.all()]
|
|
})
|
|
return base_json
|
|
|
|
detailed_data = raw_dataset_to_detailed_json(raw_dataset)
|
|
|
|
return {
|
|
'status': 'success',
|
|
'message': f'Rohdaten für File ID {file_id} gefunden',
|
|
'data': detailed_data
|
|
}
|
|
|
|
# Returns all found DNS raw data.
|
|
def get_all_dns_raw_data_from_file(file_id: int):
|
|
|
|
return generic_get_objects(
|
|
model_class=DnsRaw,
|
|
filter_kwargs={'raw_dataset__file_id': file_id},
|
|
select_related_fields=['raw_dataset'],
|
|
message="DNS Rohdaten"
|
|
)
|
|
|
|
# Returns all found hash raw data.
|
|
def get_all_hash_raw_data_from_file(file_id: int):
|
|
|
|
return generic_get_objects(
|
|
model_class=HashRaw,
|
|
filter_kwargs={'raw_dataset__file_id': file_id},
|
|
select_related_fields=['raw_dataset'],
|
|
message="Hash Rohdaten"
|
|
)
|
|
|
|
# Returns all found URL raw data.
|
|
def get_all_url_raw_data_from_file(file_id: int):
|
|
|
|
return generic_get_objects(
|
|
model_class=UrlRaw,
|
|
filter_kwargs={'raw_dataset__file_id': file_id},
|
|
select_related_fields=['raw_dataset'],
|
|
message="URL Rohdaten"
|
|
)
|
|
|
|
### Analyzed_Data Functions ###
|
|
# Returns all analyzed data from all files.
|
|
@handle_exceptions
|
|
def get_all_analyzed_data():
|
|
analyzed_datasets = AnalyzedDataset.objects.prefetch_related(
|
|
'file',
|
|
'dnsanalyzed_set',
|
|
'hashanalyzed_set',
|
|
'hashanalyzed_set__hash_type',
|
|
'urlanalyzed_set',
|
|
'urlanalyzed_set__ports',
|
|
'urlanalyzed_set__tls_versions',
|
|
'urlanalyzed_set__cipher_suites'
|
|
).all()
|
|
|
|
if not analyzed_datasets.exists():
|
|
raise ObjectDoesNotExist('Keine analysierten Daten gefunden')
|
|
|
|
def url_to_detailed_json(url):
|
|
|
|
return url.to_json()
|
|
|
|
def analyzed_dataset_to_detailed_json(dataset):
|
|
base_json = dataset.to_json()
|
|
base_json.update({
|
|
'dns_data': [dns.to_json() for dns in dataset.dnsanalyzed_set.all()],
|
|
'hash_data': [hash.to_json() for hash in dataset.hashanalyzed_set.all()],
|
|
'url_data': [url_to_detailed_json(url) for url in dataset.urlanalyzed_set.all()]
|
|
})
|
|
return base_json
|
|
|
|
data_list = [analyzed_dataset_to_detailed_json(obj) for obj in analyzed_datasets]
|
|
|
|
return{
|
|
'status': 'success',
|
|
'message': f'{len(data_list)} analysierte Daten gefunden',
|
|
'data': data_list
|
|
}
|
|
|
|
# Returns all analyzed data for the relevant file.
|
|
@handle_exceptions
|
|
def get_analyzed_data_by_file(file_id: int):
|
|
|
|
select_related_fields = ['file']
|
|
prefetch_related_fields = [
|
|
|
|
'hashanalyzed_set',
|
|
'urlanalyzed_set',
|
|
'urlanalyzed_set__ports',
|
|
'urlanalyzed_set__tls_versions',
|
|
'urlanalyzed_set__cipher_suites',
|
|
]
|
|
|
|
# Build queryset
|
|
queryset = AnalyzedDataset.objects.select_related(*select_related_fields)
|
|
|
|
for field in prefetch_related_fields:
|
|
queryset = queryset.prefetch_related(field)
|
|
|
|
# Apply filter
|
|
queryset = queryset.filter(file_id=file_id)
|
|
|
|
if not queryset.exists():
|
|
raise ObjectDoesNotExist(f'Keine analysierten Daten für File ID {file_id} gefunden')
|
|
|
|
# Get single object, since we filter by ID
|
|
analyzed_dataset = queryset.get()
|
|
|
|
# Detail functions for the JSON conversion
|
|
def url_to_detailed_json(url):
|
|
return url.to_json()
|
|
|
|
def analyzed_dataset_to_detailed_json(dataset):
|
|
base_json = dataset.to_json()
|
|
base_json.update({
|
|
'dns_data': [dns.to_json() for dns in dataset.dnsanalyzed_set.all()],
|
|
'hash_data': [hash.to_json() for hash in dataset.hashanalyzed_set.all()],
|
|
'url_data': [url_to_detailed_json(url) for url in dataset.urlanalyzed_set.all()],
|
|
|
|
})
|
|
return base_json
|
|
|
|
detailed_data = analyzed_dataset_to_detailed_json(analyzed_dataset)
|
|
|
|
return {
|
|
'status': 'success',
|
|
'message': f'Analysierte Daten für File ID {file_id} gefunden',
|
|
'data': detailed_data
|
|
}
|
|
|
|
|
|
# Returns all analyzed DNS data.
|
|
def get_all_dns_analyzed_data_from_file(file_id: int):
|
|
|
|
return generic_get_objects(
|
|
model_class=DnsAnalyzed,
|
|
filter_kwargs={'analyzed_dataset__file_id': file_id},
|
|
select_related_fields=['analyzed_dataset'],
|
|
message="DNS analysierte Daten"
|
|
)
|
|
|
|
# Returns all analyzed hash data.
|
|
def get_all_hash_analyzed_data_from_file(file_id: int):
|
|
|
|
return generic_get_objects(
|
|
model_class=HashAnalyzed,
|
|
filter_kwargs={'analyzed_dataset__file_id': file_id},
|
|
select_related_fields=['analyzed_dataset'],
|
|
message="Hash analysierte Daten"
|
|
)
|
|
|
|
# Returns all analyzed URL data.
|
|
@handle_exceptions
|
|
def get_all_url_analyzed_data_from_file(file_id: int):
|
|
url_analyzed = UrlAnalyzed.objects.select_related(
|
|
'analyzed_dataset'
|
|
).prefetch_related(
|
|
'ports',
|
|
'tls_versions',
|
|
'cipher_suites'
|
|
).filter(analyzed_dataset__file_id=file_id)
|
|
|
|
if not url_analyzed.exists():
|
|
raise ObjectDoesNotExist('Keine Daten zu analysierten URL gefunden')
|
|
|
|
data_list = [url.to_json() for url in url_analyzed]
|
|
|
|
return ({
|
|
'status': 'success',
|
|
'message': f'Analysierte Daten zu {len(data_list)} URL(s) gefunden',
|
|
'data': data_list
|
|
})
|
|
|
|
# Returns all analyzed URL data for a specific raw_url.
|
|
@handle_exceptions
|
|
def get_all_url_analyzed_by_raw_url_id(raw_url_id: int): ## TODO
|
|
raw_url = UrlRaw.objects.get(id=raw_url_id)
|
|
|
|
analyze_url.get_urls_from_db(raw_url_id)
|
|
|
|
url_analyzed = UrlAnalyzed.objects.select_related(
|
|
'analyzed_dataset',
|
|
'tool'
|
|
).prefetch_related(
|
|
'ports',
|
|
'tls_versions',
|
|
'cipher_suites'
|
|
).filter(
|
|
analyzed_dataset__file=raw_url.raw_dataset.file,
|
|
).filter(
|
|
url=raw_url.url
|
|
)
|
|
|
|
if not url_analyzed.exists():
|
|
raise ObjectDoesNotExist(f'Keine analysierten Daten gefunden für URL: {raw_url.url}')
|
|
|
|
|
|
return {
|
|
'status': 'success',
|
|
'message': f'Analysierte Daten zu URL gefunden',
|
|
'data': [url.to_json() for url in url_analyzed]
|
|
}
|
|
|
|
|
|
|
|
# Returns all analyzed hash data for a specific raw_hash.
|
|
@handle_exceptions
|
|
def get_all_hash_analyzed_by_raw_hash_id(raw_hash_id: int):
|
|
raw_hash = HashRaw.objects.get(id=raw_hash_id)
|
|
|
|
analyze_hashes.crack_hashes_from_db(raw_hash_id)
|
|
|
|
hash_analyzed = (HashAnalyzed.objects.select_related(
|
|
'analyzed_dataset',
|
|
'tool'
|
|
).prefetch_related(
|
|
'hash_type',)
|
|
.filter(
|
|
analyzed_dataset__file=raw_hash.raw_dataset.file,
|
|
).filter(
|
|
hash_value=raw_hash.hash_value
|
|
))
|
|
if not hash_analyzed.exists():
|
|
raise ObjectDoesNotExist(f'Keine analysierten Daten gefunden für Hash: {raw_hash.hash_value}')
|
|
|
|
return {
|
|
'status': 'success',
|
|
'message': f'Analysierte Daten zu gefunden',
|
|
'data': [hash.to_json() for hash in hash_analyzed]
|
|
}
|
|
|
|
### Firmware analysis READ functions ###
|
|
|
|
# Returns all binwalk raw data of a file
|
|
def get_all_binwalk_raw_data_from_file(file_id: int):
|
|
"""
|
|
Returns all binwalk raw data for a specific file.
|
|
"""
|
|
return generic_get_objects(
|
|
model_class=BinwalkRaw,
|
|
filter_kwargs={'raw_dataset__file_id': file_id},
|
|
select_related_fields=['raw_dataset'],
|
|
message="Binwalk Rohdaten"
|
|
)
|
|
|
|
|
|
# Returns all strings raw data of a file
|
|
def get_all_strings_raw_data_from_file(file_id: int):
|
|
"""
|
|
Returns all strings raw data for a specific file.
|
|
"""
|
|
return generic_get_objects(
|
|
model_class=StringsRaw,
|
|
filter_kwargs={'raw_dataset__file_id': file_id},
|
|
select_related_fields=['raw_dataset'],
|
|
message="Strings Rohdaten"
|
|
)
|
|
|
|
|
|
# Returns filtered strings by type
|
|
def get_strings_by_type(file_id: int, string_type: str):
|
|
"""
|
|
Returns filtered strings by type (url, ip, path, etc.).
|
|
"""
|
|
return generic_get_objects(
|
|
model_class=StringsRaw,
|
|
filter_kwargs={
|
|
'raw_dataset__file_id': file_id,
|
|
'string_type': string_type
|
|
},
|
|
select_related_fields=['raw_dataset'],
|
|
message=f"Strings vom Typ {string_type}"
|
|
)
|
|
|
|
|
|
# Returns all analyzed binwalk data of a file
|
|
@handle_exceptions
|
|
def get_all_binwalk_analyzed_data_from_file(file_id: int):
|
|
"""
|
|
Returns all analyzed binwalk data for a specific file.
|
|
"""
|
|
binwalk_analyzed = BinwalkAnalyzed.objects.select_related(
|
|
'analyzed_dataset',
|
|
'tool'
|
|
).filter(analyzed_dataset__file_id=file_id)
|
|
|
|
if not binwalk_analyzed.exists():
|
|
raise ObjectDoesNotExist('Keine analysierten Binwalk-Daten gefunden')
|
|
|
|
data_list = [entry.to_json() for entry in binwalk_analyzed]
|
|
|
|
return {
|
|
'status': 'success',
|
|
'message': f'Analysierte Binwalk-Daten zu {len(data_list)} Einträgen gefunden',
|
|
'data': data_list
|
|
}
|
|
|
|
|
|
# Returns all analyzed strings data of a file
|
|
@handle_exceptions
|
|
def get_all_strings_analyzed_data_from_file(file_id: int):
|
|
"""
|
|
Returns all analyzed strings data for a specific file.
|
|
"""
|
|
strings_analyzed = StringsAnalyzed.objects.select_related(
|
|
'analyzed_dataset',
|
|
'tool'
|
|
).filter(analyzed_dataset__file_id=file_id)
|
|
|
|
if not strings_analyzed.exists():
|
|
raise ObjectDoesNotExist('Keine analysierten Strings-Daten gefunden')
|
|
|
|
data_list = [entry.to_json() for entry in strings_analyzed]
|
|
|
|
return {
|
|
'status': 'success',
|
|
'message': f'Analysierte Strings-Daten zu {len(data_list)} Einträgen gefunden',
|
|
'data': data_list
|
|
}
|
|
|
|
|
|
# Returns critical strings by severity
|
|
@handle_exceptions
|
|
def get_critical_strings_by_severity(file_id: int, min_severity: str = 'medium'):
|
|
"""
|
|
Returns critical strings filtered by minimum severity.
|
|
"""
|
|
severity_order = {'info': 0, 'low': 1, 'medium': 2, 'high': 3, 'critical': 4}
|
|
min_level = severity_order.get(min_severity, 0)
|
|
|
|
strings_analyzed = StringsAnalyzed.objects.select_related(
|
|
'analyzed_dataset',
|
|
'tool'
|
|
).filter(analyzed_dataset__file_id=file_id)
|
|
|
|
# Filter by severity
|
|
filtered_strings = [
|
|
entry for entry in strings_analyzed
|
|
if severity_order.get(entry.severity, 0) >= min_level
|
|
]
|
|
|
|
if not filtered_strings:
|
|
raise ObjectDoesNotExist(f'Keine Strings mit Severity >= {min_severity} gefunden')
|
|
|
|
data_list = [entry.to_json() for entry in filtered_strings]
|
|
|
|
return {
|
|
'status': 'success',
|
|
'message': f'{len(data_list)} kritische Strings gefunden',
|
|
'data': data_list
|
|
}
|
|
|
|
|
|
# Extended get_raw_data_by_file function (replaces the existing one)
|
|
@handle_exceptions
|
|
def get_raw_data_by_file_extended(file_id: int):
|
|
"""
|
|
Returns ALL raw data for a file (incl. firmware data).
|
|
"""
|
|
raw_dataset = RawDataset.objects.select_related(
|
|
'file'
|
|
).prefetch_related(
|
|
'dnsraw_set',
|
|
'hashraw_set',
|
|
'urlraw_set',
|
|
'binwalkraw_set',
|
|
'stringsraw_set'
|
|
).get(file_id=file_id)
|
|
|
|
def raw_dataset_to_detailed_json(dataset):
|
|
base_json = dataset.to_json()
|
|
base_json.update({
|
|
'dns_data': [dns.to_json() for dns in dataset.dnsraw_set.all()],
|
|
'hash_data': [hash.to_json() for hash in dataset.hashraw_set.all()],
|
|
'url_data': [url.to_json() for url in dataset.urlraw_set.all()],
|
|
'binwalk_data': [binwalk.to_json() for binwalk in dataset.binwalkraw_set.all()],
|
|
'strings_data': [string.to_json() for string in dataset.stringsraw_set.all()]
|
|
})
|
|
return base_json
|
|
|
|
detailed_data = raw_dataset_to_detailed_json(raw_dataset)
|
|
|
|
return {
|
|
'status': 'success',
|
|
'message': f'Vollständige Rohdaten für File ID {file_id} gefunden',
|
|
'data': detailed_data
|
|
}
|
|
|
|
|
|
# Add import statements at the beginning of db_read.py:
|
|
# from .models import BinwalkRaw, StringsRaw, BinwalkAnalyzed, StringsAnalyzed
|
|
|
|
|