import logging from datetime import datetime from django.core.exceptions import ValidationError, ObjectDoesNotExist from django.db import IntegrityError, DatabaseError, transaction from django.http import JsonResponse from .analyze.analyze_pcap import analyze_pcap_file from .models import * from .exception_handling import handle_exceptions from .db_validate import * from rest_framework import serializers, status from rest_framework.views import APIView from rest_framework.response import Response #Logger configuration logger = logging.getLogger(__name__) ### CREATE - functions ### # Create manufacturer @handle_exceptions @transaction.atomic def create_manufacturer(name: str): # Input validation if not name or not isinstance(name, str): # Checks for None, empty strings and non-strings raise ValidationError("Ungültiger Herstellername") # Manufacturer must not consist only of whitespace name = name.strip() if not name: # Checks again after stripping whitespace raise ValidationError("Herstellername darf nicht leer sein") # Check for duplicate if Manufacturer.objects.filter(name=name).exists(): raise ValidationError(f"Hersteller '{name}' existiert bereits") # Create manufacturer manufacturer = Manufacturer.objects.create( name=name, created=datetime.now() ) # Return manufacturer object as JSON logging.info(f"Hersteller erfolgreich erstellt: {name} (ID: {manufacturer.id})") return JsonResponse({ 'status': 'success', 'message': 'Hersteller wurde erfolgreich erstellt', 'data': manufacturer.to_json() }, status=201) # Create device type @handle_exceptions @transaction.atomic def create_device_type(device_type: str): # Input validation if not device_type or not isinstance(device_type, str): raise ValidationError("Ungültiger Gerätetyp") # Manufacturer must not consist only of whitespace device_type = device_type.strip() if not device_type: # Checks again after stripping whitespace raise ValidationError("Gerätetyp darf nicht leer sein") # Check for duplicate if DeviceType.objects.filter(device_type=device_type).exists(): raise ValidationError(f"Gerätetyp '{device_type}' existiert bereits") # Create type device_type_obj = DeviceType.objects.create( device_type=device_type ) logging.info(f"Gerätetyp erfolgreich erstellt: {device_type} (ID: {device_type_obj.id})") return JsonResponse({ 'status': 'success', 'message': 'Gerätetyp wurde erfolgreich erstellt', 'data': device_type_obj.to_json() }, status=201) # Create product @handle_exceptions @transaction.atomic def create_product(manufacturer_id: int, device_type_id: int, product_name: str): # Input validation if not product_name or not isinstance(product_name, str): raise ValidationError("Ungültiger Produktname") # Product name must not be empty product_name = product_name.strip() if not product_name: raise ValidationError("Produktname darf nicht leer sein") # Check manufacturer and device type manufacturer = Manufacturer.objects.get(id=manufacturer_id) device_type = DeviceType.objects.get(id=device_type_id) # Check for duplicate if Product.objects.filter( manufacturer=manufacturer, device_type=device_type, product_name=product_name ).exists(): raise ValidationError(f"Produkt '{product_name}' existiert bereits für diesen Hersteller und Gerätetyp") # Create product product = Product.objects.create( manufacturer=manufacturer, device_type=device_type, product_name=product_name, created=datetime.now() ) logging.info( f"Produkt erfolgreich erstellt: {product_name} (ID: {product.id}, Hersteller: {manufacturer.name}, Typ: {device_type.device_type})") return JsonResponse({ 'status': 'success', 'message': 'Produkt wurde erfolgreich erstellt', 'data': product.to_json() }, status=201) # Create firmware @handle_exceptions @transaction.atomic def create_firmware(product_id: int, version: str): # Input validation if not version or not isinstance(version, str): raise ValidationError("Ungültige Firmware-Version") # Version must not be empty version = version.strip() if not version: raise ValidationError("Firmware-Version darf nicht leer sein") # Check product product = Product.objects.get(id=product_id) # Check for duplicate if Firmware.objects.filter( product=product, version=version ).exists(): raise ValidationError(f"Firmware-Version '{version}' existiert bereits für dieses Produkt") # Create firmware firmware = Firmware.objects.create( product=product, version=version, created=datetime.now() ) logging.info( f"Firmware erfolgreich erstellt: Version {version} (ID: {firmware.id}, Produkt: {product.product_name})") return JsonResponse({ 'status': 'success', 'message': 'Firmware wurde erfolgreich erstellt', 'data': firmware.to_json() }, status=201) #Create device @handle_exceptions @transaction.atomic def create_new_device(manufacturer_id:int, device_type_id: int, device_name: str, serial: str, comment: str = None): # Input validation if not manufacturer_id or not isinstance(manufacturer_id, int): raise ValidationError("Ungültige Manufacturer ID") # Input validation if not device_type_id or not isinstance(device_type_id, int): raise ValidationError("Ungültige Device ID") # Input validation if not serial or not isinstance(serial, str): raise ValidationError("Ungültige Seriennummer") # Serial number must not be empty serial = serial.strip() if not serial: raise ValidationError("Seriennummer darf nicht leer sein") # Validate device name if not device_name or not isinstance(device_name, str): raise ValidationError("Ungültiger Gerätename") device_name = device_name.strip() if not device_name: raise ValidationError("Gerätename darf nicht leer sein") manufacturer = Manufacturer.objects.get(id=manufacturer_id) device_type = DeviceType.objects.get(id=device_type_id) # Find or create product try: product = Product.objects.get( product_name=device_name, manufacturer=manufacturer, device_type=device_type ) logging.info(f"Existierendes Produkt gefunden: {product.product_name}") except Product.DoesNotExist: product = Product.objects.create( product_name=device_name, manufacturer=manufacturer, device_type=device_type ) logging.info(f"Neues Produkt erstellt: {product.product_name}") # Check for duplicate if Device.objects.filter( product=product, serial=serial ).exists(): raise ValidationError(f"Gerät mit Seriennummer '{serial}' existiert bereits für dieses Produkt") # Create device device = Device.objects.create( product=product, serial=serial, comment=comment if comment else '', created=datetime.now() ) logging.info( f"Gerät erfolgreich erstellt: Seriennummer {serial} (ID: {device.id}, Produkt: {product.product_name})") return JsonResponse({ 'status': 'success', 'message': 'Gerät wurde erfolgreich erstellt', 'data': { 'device': device.to_json(), 'product_id': product.id } }, status=201) # Create file @handle_exceptions @transaction.atomic def create_file(device_id: int, firmware_id: int, filename: str, ip_address: str, status: str, upload_time: datetime = None): # Input validation if not filename or not isinstance(filename, str): raise ValidationError("Ungültiger Dateiname") # Filename must not be empty filename = filename.strip() if not filename: raise ValidationError("Dateiname darf nicht leer sein") if not ip_address or not isinstance(ip_address, str): raise ValidationError("Ungültige IP-Adresse") # IP address must not be empty ip_address = ip_address.strip() if not ip_address: raise ValidationError("IP-Adresse darf nicht leer sein") if not status or not isinstance(status, str): raise ValidationError("Ungültiger Status") if not re.match(r'^(\d{1,3}\.){3}\d{1,3}$', ip_address): raise ValidationError("Ungültige IP-Adresse") # Check device device = Device.objects.get(id=device_id) # Raises ObjectDoesNotExist # Check firmware firmware = Firmware.objects.get(id=firmware_id) # Raises ObjectDoesNotExist # Check for duplicate if File.objects.filter( device=device, firmware=firmware, filename=filename, ip_address=ip_address ).exists(): raise ValidationError(f"Datei '{filename}' existiert bereits für dieses Gerät und diese Firmware") # Create file file = File.objects.create( device=device, firmware=firmware, filename=filename, ip_address=ip_address, status=status, upload_time=upload_time if upload_time else datetime.now() ) logging.info( f"Datei erfolgreich erstellt: {filename} (ID: {file.id}, Gerät: {device.serial}, Firmware: {firmware.version})") #Link firmware with device create_firmware_to_device(device_id, firmware_id) return JsonResponse({ 'status': 'success', 'message': 'Datei wurde erfolgreich erstellt', 'data': file.to_json() }, status=201) # Create file @handle_exceptions @transaction.atomic def create_firmware_to_device(device_id: int, firmware_id: int): # Check device device = Device.objects.get(id=device_id) # Raises ObjectDoesNotExist # Check device firmware = Firmware.objects.get(id=firmware_id) # Raises ObjectDoesNotExist # Check for duplicate if FirmwareDevices.objects.filter( device=device_id, firmware=firmware_id, ).exists(): raise ValidationError(f"Firmware '{firmware}' existiert bereits!") # Create file firmware_device=FirmwareDevices.objects.create( device=device, firmware=firmware, created=datetime.now()) logging.info( f"Firmware erfolgreich mit device verknüpft: {firmware} (Gerät: {device})") return JsonResponse({ 'status': 'success', 'message': 'Firmware wurde erfolgreich verknüpft', 'data': firmware_device.to_json() }, status=201) # REPLACE the existing create_file_with_firmware_version function in db_create.py # with this extended version: @handle_exceptions @transaction.atomic def create_file_with_firmware_version(device_id: int, firmware_version: str, filename: str, ip_address: str, status: str): # Input validation (stays the same) if not firmware_version or not isinstance(firmware_version, str): raise ValidationError("Ungültige Firmware-Version") firmware_version = firmware_version.strip() if not firmware_version: raise ValidationError("Firmware-Version darf nicht leer sein") if not filename or not isinstance(filename, str): raise ValidationError("Ungültiger Dateiname") filename = filename.strip() if not filename: raise ValidationError("Dateiname darf nicht leer sein") if not ip_address or not isinstance(ip_address, str): raise ValidationError("Ungültige IP-Adresse") ip_address = ip_address.strip() if not ip_address: raise ValidationError("IP-Adresse darf nicht leer sein") if not status or not isinstance(status, str): raise ValidationError("Ungültiger Status") if not re.match(r'^(\d{1,3}\.){3}\d{1,3}$', ip_address): raise ValidationError("Ungültige IP-Adresse") # Get device device = Device.objects.get(id=device_id) # Get or create firmware try: firmware = Firmware.objects.get(version=firmware_version, product=device.product) except Firmware.DoesNotExist: firmware = Firmware.objects.create( version=firmware_version, product=device.product ) # Check for duplicates if File.objects.filter( device=device, firmware=firmware, filename=filename, ip_address=ip_address ).exists(): raise ValidationError(f"Datei '{filename}' existiert bereits für dieses Gerät und diese Firmware") # Create file file = File.objects.create( device=device, firmware=firmware, filename=filename, ip_address=ip_address, status=status, upload_time=datetime.now() ) logging.info( f"Datei erfolgreich erstellt: {filename} (ID: {file.id}, Gerät: {device.serial}, Firmware: {firmware.version})") # Link firmware with device create_firmware_to_device(device.id, firmware.id) # Create raw dataset response = create_raw_dataset(file.id) if not isinstance(response, JsonResponse): raise ValueError("Expected JsonResponse from create_raw_dataset") # Decode and parse the JsonResponse content raw_dataset_data = json.loads(response.content.decode('utf-8')) if raw_dataset_data['status'] != 'success': raise ValueError(f"Failed to create raw dataset: {raw_dataset_data.get('message', 'Unknown error')}") raw_dataset_id = raw_dataset_data['data']['id'] # *** NEW LOGIC: Distinguish between PCAP and firmware *** file_extension = filename.lower().split('.')[-1] if file_extension in ['pcap', 'pcapng', 'cap']: # PCAP analysis as before analyze_pcap_file(filename, raw_dataset_id) elif file_extension == 'bin': # Firmware analysis for .bin files from .analyze.analyze_firmware import analyze_firmware_file analyze_firmware_file(filename, raw_dataset_id) else: logging.warning(f"Unbekannter Dateityp: {file_extension}. Keine automatische Analyse.") return JsonResponse({ 'status': 'success', 'message': 'Datei wurde erfolgreich erstellt', 'data': file.to_json() }, status=201) # Create tool @handle_exceptions @transaction.atomic def create_tool(tool_name: str, version: str): # Input validation if not tool_name or not isinstance(tool_name, str): raise ValidationError("Ungültiger Tool-Name") tool_name = tool_name.strip() if not tool_name: raise ValidationError("Tool-Name darf nicht leer sein") if not version or not isinstance(version, str): raise ValidationError("Ungültige Version") version = version.strip() if not version: raise ValidationError("Version darf nicht leer sein") # Check for duplicate if Tool.objects.filter( tool_name=tool_name, version=version ).exists(): raise ValidationError(f"Tool '{tool_name}' mit Version '{version}' existiert bereits") # Create tool tool = Tool.objects.create( tool_name=tool_name, version=version, created=datetime.now() ) logging.info( f"Tool erfolgreich erstellt: {tool_name} Version {version} (ID: {tool.id})") return JsonResponse({ 'status': 'success', 'message': 'Tool wurde erfolgreich erstellt', 'data': tool.to_json() }, status=201) # Create raw dataset @handle_exceptions @transaction.atomic def create_raw_dataset(file_id: int): # Check file file = File.objects.get(id=file_id) # Not necessary, since File.objects.get() already raises an ObjectDoesNotExist exception """if not file.exists(): raise ValidationError(f"File mit Id '{file_id}' existiert nicht")""" # Create raw dataset raw_dataset = RawDataset.objects.create( file=file, created=datetime.now() ) logging.info(f"Raw Dataset erfolgreich erstellt für File: {file.filename} (ID: {raw_dataset.id})") return JsonResponse({ 'status': 'success', 'message': 'Raw Dataset wurde erfolgreich erstellt', 'data': raw_dataset.to_json() }, status=201) # Create raw_url entry @handle_exceptions @transaction.atomic def create_raw_url(raw_dataset_id: int, url: str): # Input validation if not url or not isinstance(url, str): raise ValidationError("Ungültige URL") url = url.strip() if not url: raise ValidationError("URL darf nicht leer sein") # Use raw dataset ID directly raw_url = UrlRaw.objects.create( raw_dataset_id=raw_dataset_id, url=url, created=datetime.now() ) logging.info(f"Raw URL erfolgreich erstellt: {url} (ID: {raw_url.id})") return JsonResponse({ 'status': 'success', 'message': 'Raw URL wurde erfolgreich erstellt', 'data': raw_url.to_json() }, status=201) # Create raw_dns entry @handle_exceptions @transaction.atomic def create_raw_dns(raw_dataset_id: int, dns_hostname: str): # Input validation if not dns_hostname or not isinstance(dns_hostname, str): raise ValidationError("Ungültiger DNS Hostname") dns_hostname = dns_hostname.strip() if not dns_hostname: raise ValidationError("DNS Hostname darf nicht leer sein") # Check for duplicate by ID if DnsRaw.objects.filter( raw_dataset_id=raw_dataset_id, dns_hostname=dns_hostname ).exists(): raise ValidationError(f"DNS Hostname '{dns_hostname}' existiert bereits") # Create raw DNS with ID raw_dns = DnsRaw.objects.create( raw_dataset_id=raw_dataset_id, dns_hostname=dns_hostname, created=datetime.now() ) logging.info(f"Raw DNS erfolgreich erstellt: {dns_hostname} (ID: {raw_dns.id})") return JsonResponse({ 'status': 'success', 'message': 'Raw DNS wurde erfolgreich erstellt', 'data': raw_dns.to_json() }, status=201) # Create raw_hash entry @handle_exceptions @transaction.atomic def create_raw_hash(raw_dataset_id: int, hash_value: str): # Input validation if not hash_value or not isinstance(hash_value, str): raise ValidationError("Ungültiger Hash-Wert") hash_value = hash_value.strip() if not hash_value: raise ValidationError("Hash-Wert darf nicht leer sein") # Use raw dataset ID directly raw_hash = HashRaw.objects.create( raw_dataset_id=raw_dataset_id, hash_value=hash_value, created=datetime.now() ) logging.info(f"Raw Hash erfolgreich erstellt: {hash_value} (ID: {raw_hash.id})") return JsonResponse({ 'status': 'success', 'message': 'Raw Hash wurde erfolgreich erstellt', 'data': raw_hash.to_json() }, status=201) # Create analyzed dataset @handle_exceptions @transaction.atomic def create_analyzed_dataset(file_id: int): # Check file file = File.objects.get(id=file_id) # Create analyzed dataset analyzed_dataset = AnalyzedDataset.objects.create( file=file, created=datetime.now() ) logging.info(f"Analyzed Dataset erfolgreich erstellt für File: {file.filename}") return JsonResponse({ 'status': 'success', 'message': 'Analyzed Dataset wurde erfolgreich erstellt', 'data': analyzed_dataset.to_json() }, status=201) # Analyzed Data - Create port @handle_exceptions @transaction.atomic def create_port(port_number: int): # Input validation if not isinstance(port_number, int): raise ValidationError("Port muss eine Ganzzahl sein") # Create port or return existing one port, created = Port.objects.get_or_create( port=port_number, # Note: field name is 'port', not 'port_number' defaults={'created': datetime.now()} ) logging.info(f"Port {'erstellt' if created else 'gefunden'}: {port_number}") return JsonResponse({ 'status': 'success', 'message': f"Port wurde {'erstellt' if created else 'gefunden'}", 'data': port.to_json() }, status=201 if created else 200) # Analyzed Data - Create TLS version @handle_exceptions @transaction.atomic def create_tls_version(version: str): # Input validation if not version or not isinstance(version, str): raise ValidationError("Ungültige TLS-Version") version = version.strip() if not version: raise ValidationError("TLS-Version darf nicht leer sein") # Create TLS version or return existing one tls_version, created = TlsVersion.objects.get_or_create( tls_version=version, # Note: field name is 'tls_version' defaults={'created': datetime.now()} ) logging.info(f"TLS-Version {'erstellt' if created else 'gefunden'}: {version}") return JsonResponse({ 'status': 'success', 'message': f"TLS-Version wurde {'erstellt' if created else 'gefunden'}", 'data': tls_version.to_json() }, status=201 if created else 200) # Analyzed Data - Create cipher suite @handle_exceptions @transaction.atomic def create_cipher_suite(name: str): # Input validation if not name or not isinstance(name, str): raise ValidationError("Ungültige Cipher Suite") name = name.strip() if not name: raise ValidationError("Cipher Suite darf nicht leer sein") # Create cipher suite or return existing one cipher_suite, created = CipherSuite.objects.get_or_create( cipher_suite=name, # Note: field name is 'cipher_suite' defaults={'created': datetime.now()} ) logging.info(f"Cipher Suite {'erstellt' if created else 'gefunden'}: {name}") return JsonResponse({ 'status': 'success', 'message': f"Cipher Suite wurde {'erstellt' if created else 'gefunden'}", 'data': cipher_suite.to_json() }, status=201 if created else 200) # Analyzed Data - Add data (ports, TLS version and cipher suites) to analyzed_URL @handle_exceptions @transaction.atomic def add_features_to_url(url_id: int, ports: list = None, tls_versions: list = None, cipher_suites: list = None): url = UrlAnalyzed.objects.get(id=url_id) if ports: for port_number in ports: port, _ = Port.objects.get_or_create( port=port_number, defaults={'created': datetime.now()} ) url.ports.add(port) if tls_versions: for version in tls_versions: tls, _ = TlsVersion.objects.get_or_create( tls_version=version, defaults={'created': datetime.now()} ) url.tls_versions.add(tls) if cipher_suites: for suite in cipher_suites: cipher, _ = CipherSuite.objects.get_or_create( cipher_suite=suite, defaults={'created': datetime.now()} ) url.cipher_suites.add(cipher) return JsonResponse({ 'status': 'success', 'message': 'Features wurden zur URL hinzugefügt', 'data': url.to_json() }, status=201) # Create analyzed_url entry @handle_exceptions @transaction.atomic def create_analyzed_url(analyzed_dataset_id: int, tool_id: int, url: str, ports: list = None, tls_versions: list = None, cipher_suites: list = None): # Input validation if not url or not isinstance(url, str): raise ValidationError("Ungültige URL") url = url.strip() if not url: raise ValidationError("URL darf nicht leer sein") # Check for duplicate if UrlAnalyzed.objects.filter( analyzed_dataset_id=analyzed_dataset_id, url=url ).exists(): raise ValidationError(f"URL '{url}' existiert bereits für dieses Analyzed Dataset") # Create URL analyzed_url = UrlAnalyzed.objects.create( analyzed_dataset_id=analyzed_dataset_id, tool_id=tool_id, url=url, created=datetime.now() ) # Add features if any([ports, tls_versions, cipher_suites]): add_features_to_url(analyzed_url.id, ports, tls_versions, cipher_suites) logging.info(f"Analyzed URL erfolgreich erstellt: {url} (ID: {analyzed_url.id})") # Return updated URL analyzed_url.refresh_from_db() return JsonResponse({ 'status': 'success', 'message': 'Analyzed URL wurde erfolgreich erstellt', 'data': analyzed_url.to_json() }, status=201) # Create analyzed_dns entry @handle_exceptions @transaction.atomic def create_analyzed_dns(analyzed_dataset_id: int, tool_id: int, dns_hostname: str, record_type: str): # Input validation if not dns_hostname or not isinstance(dns_hostname, str): raise ValidationError("Ungültiger DNS Hostname") dns_hostname = dns_hostname.strip() if not dns_hostname: raise ValidationError("DNS Hostname darf nicht leer sein") if not record_type or not isinstance(record_type, str): raise ValidationError("Ungültiger Record Type") record_type = record_type.strip() if not record_type: raise ValidationError("Record Type darf nicht leer sein") # Check for duplicate by IDs if DnsAnalyzed.objects.filter( analyzed_dataset_id=analyzed_dataset_id, dns_hostname=dns_hostname, record_type=record_type ).exists(): raise ValidationError( f"DNS '{dns_hostname}' mit Record Type '{record_type}' existiert bereits für dieses Analyzed Dataset") # Create analyzed DNS with IDs analyzed_dns = DnsAnalyzed.objects.create( analyzed_dataset_id=analyzed_dataset_id, tool_id=tool_id, dns_hostname=dns_hostname, record_type=record_type, created=datetime.now() ) logging.info( f"Analyzed DNS erfolgreich erstellt: {dns_hostname} (ID: {analyzed_dns.id}, Analyzed Dataset ID: {analyzed_dataset_id})") return JsonResponse({ 'status': 'success', 'message': 'Analyzed DNS wurde erfolgreich erstellt', 'data': analyzed_dns.to_json() }, status=201) # Create analyzed_hash entry @handle_exceptions @transaction.atomic def create_analyzed_hash(analyzed_dataset_id: int, tool_id: int, hash_type: str, hash_value: str, cracked: bool = False, cracked_value: str = None, crack_time: str = None): # Input validation if not hash_type or not isinstance(hash_type, str): raise ValidationError("Ungültiger Hash-Typ") hash_type = hash_type.strip() if not hash_type: raise ValidationError("Hash-Typ darf nicht leer sein") if not hash_value or not isinstance(hash_value, str): raise ValidationError("Ungültiger Hash-Wert") hash_value = hash_value.strip() if not hash_value: raise ValidationError("Hash-Wert darf nicht leer sein") if cracked and not cracked_value: raise ValidationError("Bei gecracktem Hash muss ein Wert angegeben werden") # Check for duplicate or fetch existing object for update existing_hash = HashAnalyzed.objects.filter( analyzed_dataset_id=analyzed_dataset_id, hash_value=hash_value ).first() if existing_hash: # Update existing hash if cracked: existing_hash.cracked = True existing_hash.cracked_value = cracked_value existing_hash.crack_time = crack_time existing_hash.save() logging.info(f"Analyzed Hash aktualisiert: {hash_value} (ID: {existing_hash.id})") return JsonResponse({ 'status': 'success', 'message': 'Analyzed Hash wurde erfolgreich aktualisiert', 'data': existing_hash.to_json() }, status=200) # Create HashType or find existing one hash_type_obj, created = HashType.objects.get_or_create( hash_type=hash_type, defaults={'created': datetime.now()} ) # Create analyzed hash analyzed_hash = HashAnalyzed.objects.create( analyzed_dataset_id=analyzed_dataset_id, tool_id=tool_id, hash_value=hash_value, cracked=cracked, cracked_value=cracked_value if cracked else None, crack_time=crack_time, created=datetime.now() ) # Add HashType to the many-to-many relationship analyzed_hash.hash_type.add(hash_type_obj) logging.info( f"Analyzed Hash erfolgreich erstellt: {hash_value} (ID: {analyzed_hash.id}, " f"Hash-Typ: {hash_type} ({hash_type_obj.id}), " f"Analyzed Dataset ID: {analyzed_dataset_id})") return JsonResponse({ 'status': 'success', 'message': 'Analyzed Hash wurde erfolgreich erstellt', 'data': analyzed_hash.to_json() }, status=201) ### Firmware analysis CREATE functions ### # Create BinwalkRaw entry @handle_exceptions @transaction.atomic def create_binwalk_raw(raw_dataset_id: int, offset: str, description: str, file_path: str = None): """ Creates a Binwalk raw data entry. """ # Input validation if not offset or not isinstance(offset, str): raise ValidationError("Ungültiger Offset") if not description or not isinstance(description, str): raise ValidationError("Ungültige Beschreibung") offset = offset.strip() description = description.strip() if not offset or not description: raise ValidationError("Offset und Beschreibung dürfen nicht leer sein") # Create Binwalk Raw binwalk_raw = BinwalkRaw.objects.create( raw_dataset_id=raw_dataset_id, offset=offset, description=description, file_path=file_path, created=datetime.now() ) logging.info(f"Binwalk Raw erfolgreich erstellt: {offset} (ID: {binwalk_raw.id})") return JsonResponse({ 'status': 'success', 'message': 'Binwalk Raw wurde erfolgreich erstellt', 'data': binwalk_raw.to_json() }, status=201) # Create StringsRaw entry @handle_exceptions @transaction.atomic def create_strings_raw(raw_dataset_id: int, string_value: str, string_type: str = 'generic'): """ Creates a Strings raw data entry. """ # Input validation if not string_value or not isinstance(string_value, str): raise ValidationError("Ungültiger String-Wert") string_value = string_value.strip() if not string_value: raise ValidationError("String-Wert darf nicht leer sein") if len(string_value) > 1000: raise ValidationError("String-Wert zu lang (max 1000 Zeichen)") # Create Strings Raw strings_raw = StringsRaw.objects.create( raw_dataset_id=raw_dataset_id, string_value=string_value, string_type=string_type, created=datetime.now() ) logging.info(f"Strings Raw erfolgreich erstellt: {string_type} (ID: {strings_raw.id})") return JsonResponse({ 'status': 'success', 'message': 'Strings Raw wurde erfolgreich erstellt', 'data': strings_raw.to_json() }, status=201) # Create BinwalkAnalyzed entry @handle_exceptions @transaction.atomic def create_binwalk_analyzed(analyzed_dataset_id: int, tool_id: int, component_type: str, offset: str, size: str = None, entropy: float = None): """ Creates an analyzed Binwalk entry. """ # Input validation if not component_type or not isinstance(component_type, str): raise ValidationError("Ungültiger Komponententyp") if not offset or not isinstance(offset, str): raise ValidationError("Ungültiger Offset") component_type = component_type.strip() offset = offset.strip() if not component_type or not offset: raise ValidationError("Komponententyp und Offset dürfen nicht leer sein") # Create Binwalk Analyzed binwalk_analyzed = BinwalkAnalyzed.objects.create( analyzed_dataset_id=analyzed_dataset_id, tool_id=tool_id, component_type=component_type, offset=offset, size=size, entropy=entropy, created=datetime.now() ) logging.info(f"Binwalk Analyzed erfolgreich erstellt: {component_type} (ID: {binwalk_analyzed.id})") return JsonResponse({ 'status': 'success', 'message': 'Binwalk Analyzed wurde erfolgreich erstellt', 'data': binwalk_analyzed.to_json() }, status=201) # Create StringsAnalyzed entry @handle_exceptions @transaction.atomic def create_strings_analyzed(analyzed_dataset_id: int, tool_id: int, string_value: str, category: str, severity: str = 'info'): """ Creates an analyzed Strings entry. """ # Input validation if not string_value or not isinstance(string_value, str): raise ValidationError("Ungültiger String-Wert") if not category or not isinstance(category, str): raise ValidationError("Ungültige Kategorie") string_value = string_value.strip() category = category.strip() if not string_value or not category: raise ValidationError("String-Wert und Kategorie dürfen nicht leer sein") # Validate severity valid_severities = ['critical', 'high', 'medium', 'low', 'info'] if severity not in valid_severities: raise ValidationError(f"Ungültiger Severity-Wert. Erlaubt: {', '.join(valid_severities)}") # Create Strings Analyzed strings_analyzed = StringsAnalyzed.objects.create( analyzed_dataset_id=analyzed_dataset_id, tool_id=tool_id, string_value=string_value[:1000], # Limit 1000 characters category=category, severity=severity, created=datetime.now() ) logging.info(f"Strings Analyzed erfolgreich erstellt: {category} (ID: {strings_analyzed.id})") return JsonResponse({ 'status': 'success', 'message': 'Strings Analyzed wurde erfolgreich erstellt', 'data': strings_analyzed.to_json() }, status=201) # Add import statements at the top of db_create.py: # from .models import BinwalkRaw, StringsRaw, BinwalkAnalyzed, StringsAnalyzed