from django.contrib.auth.models import User from django.http import HttpResponse from .models import * from .db_create import * from .db_read import * from .db_delete import * from .db_validate import * from .user_funcs import * from .db_read import ( get_all_binwalk_raw_data_from_file, get_all_strings_raw_data_from_file, get_strings_by_type, get_all_binwalk_analyzed_data_from_file, get_all_strings_analyzed_data_from_file, get_critical_strings_by_severity, get_raw_data_by_file_extended ) import os import json def get_all_files(folder_path): try: files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))] return files except Exception as e: print(f"An error occurred: {e}") return [] from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from django.core.serializers import serialize from rest_framework import serializers from django.http import JsonResponse class ManufacturerSerializer(serializers.ModelSerializer): class Meta: model = Manufacturer fields = ['id', 'name', 'created'] class DeviceSerializer(serializers.ModelSerializer): class Meta: model = Device fields = ['id', 'device_name', 'created'] class DeviceTypeSerializer(serializers.ModelSerializer): class Meta: model = DeviceType fields = ['id', 'device_type'] class FileSerializer(serializers.ModelSerializer): class Meta: model = File fields = ['file_id', 'filename', 'upload_time', 'status', 'device_id'] class HashSerializer(serializers.ModelSerializer): class Meta: model = File fields = ['hash_id', 'hash_value', 'cracked', 'cracked_value', 'executed_at'] class ProductSerializer(serializers.ModelSerializer): class Meta: model = Product fields = ['id', 'manufacturer', 'device_type', 'product_name', 'created'] class FirmwareSerializer(serializers.ModelSerializer): class Meta: model = Firmware fields = ['id', 'product', 'version', 'created'] class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['username', 'password', 'role'] class LoginSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['username', 'password'] class IdSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['id'] class ExampleAPI(APIView): def get(self, request, pk, py, *args, **kwargs): queryset = get_device_type_by_id(pk) queryset = get_all_device_types() #queryset = get_files_by_device(pk) return Response(queryset) def post(self, request, pk, py): received_data = request.data response_data = {"received": received_data} return Response(response_data, status=status.HTTP_201_CREATED) class CreateFirmware(APIView): def post(self, request): serializer = FirmwareSerializer(data=request.data) if serializer.is_valid(): product_id = serializer.validated_data.get("product").id version = serializer.validated_data.get("version") response = create_firmware(product_id, version) return response return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class CreateProduct(APIView): def post(self, request, *args, **kwargs): serializer = ProductSerializer(data=request.data) if serializer.is_valid(): manufacturer_id = serializer.validated_data.get("manufacturer").id device_type_id = serializer.validated_data.get("device_type").id product_name = serializer.validated_data.get("product_name") response = create_product(manufacturer_id, device_type_id, product_name) return response return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class CreateDeviceType(APIView): def post(self, request): serializer = DeviceTypeSerializer(data=request.data) if serializer.is_valid(): device_type = serializer.data.get("device_type") respone = create_device_type(device_type) return respone return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class CreateManufacturer(APIView): def post(self, request, *args, **kwargs): serializer = ManufacturerSerializer(data=request.data) if serializer.is_valid(): name = serializer.data.get("name") response = create_manufacturer(name) return response return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class CreateDeviceSerializer(serializers.Serializer): device_type_id = serializers.IntegerField() device_name = serializers.CharField(max_length=255) serial = serializers.CharField(max_length=255) manufacturer_id = serializers.IntegerField() comment = serializers.CharField(max_length=255, required=False, allow_blank=True) def create(self, validated_data): return validated_data class CreateDevice(APIView): def post(self, request, *args, **kwargs): serializer = CreateDeviceSerializer(data=request.data) if serializer.is_valid(): device_type_id = serializer.validated_data.get("device_type_id") device_name = serializer.validated_data.get("device_name") serial = serializer.validated_data.get("serial") manufacturer_id = serializer.validated_data.get("manufacturer_id") comment = serializer.validated_data.get("comment", None) response = create_new_device(manufacturer_id, device_type_id, device_name, serial, comment) return response return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class CreateFileWithFirmware(APIView): def post(self, request): device_id = request.data.get('device_id') firmware_version = request.data.get('firmware_version') filename = request.data.get('filename') ip_address = request.data.get('ip_address') file_status = request.data.get('status') response = create_file_with_firmware_version(device_id, firmware_version, filename, ip_address, file_status) return response class FilesForDevice(APIView): def get(self, request, pk, *args, **kwargs): device_queryset = Device.objects.prefetch_related('file_set').get(device_id=pk) device_serializer = DeviceSerializer(device_queryset) file_serializer = FileSerializer(device_queryset.file_set.all(), many=True) response_data = { 'device': device_serializer.data, 'files': file_serializer.data } return Response(response_data, status=status.HTTP_200_OK) class HashesFromFile(APIView): def get(self, request, pk, *args, **kwargs): file_queryset = Device.objects.prefetch_related('file_set').get(file_id=pk) file_serializer = FileSerializer(file_queryset) hash_serializer = FileSerializer(file_queryset.file_set.all(), many=True) response_data = { 'file': file_serializer.data, 'hashes': hash_serializer.data } return Response(response_data, status=status.HTTP_200_OK) class GetObject(APIView): def get(self, request, model_name, *args, **kwargs): model_class = globals().get(model_name) if not model_class: return Response({'status': 'error', 'message': 'Invalid model name'}, status=status.HTTP_400_BAD_REQUEST) filter_kwargs = request.query_params.dict() select_related_fields = request.query_params.getlist('select_related') try: data = generic_get_objects(model_class, filter_kwargs, select_related_fields) return Response({'status': 'success', 'data': data}, status=status.HTTP_200_OK) except ObjectDoesNotExist as e: return Response({'status': 'error', 'message': str(e)}, status=status.HTTP_404_NOT_FOUND) except Exception as e: return Response({'status': 'error', 'message': 'An error occurred'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) class GetManufacturers(APIView): def get(self, request, *args, **kwargs): manufacturers = get_all_manufacturers() return Response(manufacturers, status=status.HTTP_200_OK) class GetDeviceTypes(APIView): def get(self, request, *args, **kwargs): devicetypes = get_all_device_types() return Response(devicetypes, status=status.HTTP_200_OK) class RegisterUser(APIView): def post(self, request, *args, **kwargs): serializer = UserSerializer(data=request.data) if serializer.is_valid(): username = serializer.validated_data.get("username") password = serializer.validated_data.get("password") if serializer.validated_data.get("role") == 'admin': is_superuser = True is_staff = True else: is_superuser = False is_staff = True response = register_user(request, username, password, is_superuser, is_staff) if isinstance(response, JsonResponse): return response return Response(response, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class ListUser(APIView): def get(self, request,*args, **kwargs): return Response(list_users(request), status=status.HTTP_200_OK) class DeleteUser(APIView): def post(self, request, *args, **kwargs): user_id = request.data.get("id") if not user_id: return Response({"error": "Missing user_id"}, status=status.HTTP_400_BAD_REQUEST) try: user_id = int(user_id) except ValueError: return Response({"error": "Invalid user_id"}, status=status.HTTP_400_BAD_REQUEST) response = delete_user(request, user_id) if isinstance(response, JsonResponse): return response return Response(response, status=status.HTTP_200_OK) class Login(APIView): def post(self, request, *args, **kwargs): username = request.data.get("username") password = request.data.get("password") if not username or not password: return Response({"error": "Missing required fields"}, status=status.HTTP_400_BAD_REQUEST) response = login_user(request, username, password) if isinstance(response, JsonResponse): return response return Response(response, status=status.HTTP_200_OK) class SetPassword(APIView): def post(self, request, *args, **kwargs): user_id = request.data.get("user_id") new_password = request.data.get("new_password") if not user_id or not new_password: return Response({"error": "Missing required fields"}, status=status.HTTP_400_BAD_REQUEST) try: user_id = int(user_id) except ValueError: return Response({"error": "Invalid user_id"}, status=status.HTTP_400_BAD_REQUEST) try: response = set_password(request, user_id, new_password) if isinstance(response, JsonResponse): return response return Response(response, status=status.HTTP_200_OK) except ValidationError as e: return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) except Exception as e: return Response({"error": "An error occurred"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) class ChangePassword(APIView): def post(self, request, *args, **kwargs): user_id = request.data.get("user_id") new_password = request.data.get("new_password") if not user_id or not new_password: return Response({"error": "Missing required fields"}, status=status.HTTP_400_BAD_REQUEST) try: user_id = int(user_id) except ValueError: return Response({"error": "Invalid user_id"}, status=status.HTTP_400_BAD_REQUEST) try: response = change_password(request, user_id, new_password) if isinstance(response, JsonResponse): return response return Response(response, status=status.HTTP_200_OK) except ValidationError as e: return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) except Exception as e: return Response({"error": "An error occurred"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) class RegisterUser(APIView): def post(self, request, *args, **kwargs): username = request.data.get("username") password = request.data.get("password") role = request.data.get("role") if not username or not password or not role: return Response({"error": "Missing required fields"}, status=status.HTTP_400_BAD_REQUEST) if role == 'admin': is_superuser = True is_staff = True else: is_superuser = False is_staff = True response = register_user(request, username, password, is_superuser, is_staff) if isinstance(response, JsonResponse): return response return Response(response, status=status.HTTP_201_CREATED) class Logout(APIView): def post(self, request, *args, **kwargs): user_id = request.data.get("user_id") if not user_id: return Response({"error": "Missing user_id"}, status=status.HTTP_400_BAD_REQUEST) try: user_id = int(user_id) except ValueError: return Response({"error": "Invalid user_id"}, status=status.HTTP_400_BAD_REQUEST) try: response = logout_user(request, user_id) if isinstance(response, JsonResponse): return response return Response(response, status=status.HTTP_200_OK) except ValidationError as e: return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) class DeleteUserView(APIView): def delete(self, request, user_id, *args, **kwargs): try: response = delete_user(request, user_id) if isinstance(response, JsonResponse): return response return Response(response, status=status.HTTP_200_OK) except ValidationError as e: return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) except Exception as e: return Response({"error": "An error occurred"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) class GetDevices(APIView): def get(self, request, *args, **kwargs): devices = get_all_devices() return Response(devices, status=status.HTTP_200_OK) class GetDeviceById(APIView): def get(self, request, device_id, *args, **kwargs): device = get_device_by_id(device_id) return Response(device, status=status.HTTP_200_OK) class GetFileByDevice(APIView): def get(self, request, device_id, *args, **kwargs): files = get_files_by_device(device_id) return Response(files, status=status.HTTP_200_OK) class GetRawHashesByFile(APIView): def get(self, request, file_id, *args, **kwargs): hash_data = get_all_hash_raw_data_from_file(file_id) if isinstance(hash_data, JsonResponse): return hash_data return Response(hash_data, status=status.HTTP_200_OK) class GetRawUrlsByFile(APIView): def get(self, request, file_id, *args, **kwargs): url_data = get_all_url_raw_data_from_file(file_id) if isinstance(url_data, JsonResponse): return url_data return Response(url_data, status=status.HTTP_200_OK) class GetAnalyzedUrlsByFile(APIView): def get(self, request, file_id, *args, **kwargs): url_data = get_all_url_analyzed_data_from_file(file_id) if isinstance(url_data, JsonResponse): return url_data return Response(url_data, status=status.HTTP_200_OK) class GetAnalyzedDataByFile(APIView): def get(self, request, file_id, *args, **kwargs): url_data = get_analyzed_data_by_file(file_id) if isinstance(url_data, JsonResponse): return url_data return Response(url_data, status=status.HTTP_200_OK) class GetAnalyzedUrlsByRawUrlId(APIView): def get(self, request, raw_url_id, *args, **kwargs): url_data = get_all_url_analyzed_by_raw_url_id(raw_url_id) if isinstance(url_data, JsonResponse): return url_data return Response(url_data, status=status.HTTP_200_OK) class GetAnalyzedHashesByRawUrlId(APIView): def get(self, request, raw_hash_id, *args, **kwargs): url_data = get_all_hash_analyzed_by_raw_hash_id(raw_hash_id) if isinstance(url_data, JsonResponse): return url_data return Response(url_data, status=status.HTTP_200_OK) class DeleteDevice(APIView): def delete(self, request, device_id, *args, **kwargs): deleteted = delete_device(device_id) return Response(deleteted, status=status.HTTP_200_OK) class DeleteManufacturer(APIView): def delete(self, request, manufacturer_id, *args, **kwargs): deleteted = delete_manufacturer(manufacturer_id) return Response(deleteted, status=status.HTTP_200_OK) class DeleteDeviceType(APIView): def delete(self, request, device_type_id, *args, **kwargs): deleted = delete_device_type(device_type_id) return Response(deleted, status=status.HTTP_200_OK) class GetBinwalkRawByFile(APIView): """ GET /api/get_binwalk_raw_data_from_file/ Returns all Binwalk raw data for a file. """ def get(self, request, file_id, *args, **kwargs): binwalk_data = get_all_binwalk_raw_data_from_file(file_id) if isinstance(binwalk_data, JsonResponse): return binwalk_data return Response(binwalk_data, status=status.HTTP_200_OK) class GetStringsRawByFile(APIView): """ GET /api/get_strings_raw_data_from_file/ Returns all Strings raw data for a file. """ def get(self, request, file_id, *args, **kwargs): strings_data = get_all_strings_raw_data_from_file(file_id) if isinstance(strings_data, JsonResponse): return strings_data return Response(strings_data, status=status.HTTP_200_OK) class GetStringsByType(APIView): """ GET /api/get_strings_by_type// Returns strings filtered by type (url, ip, path, etc.). """ def get(self, request, file_id, string_type, *args, **kwargs): strings_data = get_strings_by_type(file_id, string_type) if isinstance(strings_data, JsonResponse): return strings_data return Response(strings_data, status=status.HTTP_200_OK) class GetBinwalkAnalyzedByFile(APIView): """ GET /api/get_binwalk_analyzed_data_from_file/ Returns analyzed Binwalk data for a file. """ def get(self, request, file_id, *args, **kwargs): binwalk_data = get_all_binwalk_analyzed_data_from_file(file_id) if isinstance(binwalk_data, JsonResponse): return binwalk_data return Response(binwalk_data, status=status.HTTP_200_OK) class GetStringsAnalyzedByFile(APIView): """ GET /api/get_strings_analyzed_data_from_file/ Returns analyzed Strings data for a file. """ def get(self, request, file_id, *args, **kwargs): strings_data = get_all_strings_analyzed_data_from_file(file_id) if isinstance(strings_data, JsonResponse): return strings_data return Response(strings_data, status=status.HTTP_200_OK) class GetCriticalStrings(APIView): """ GET /api/get_critical_strings/?severity=medium Returns critical strings filtered by severity. """ def get(self, request, file_id, *args, **kwargs): min_severity = request.query_params.get('severity', 'medium') strings_data = get_critical_strings_by_severity(file_id, min_severity) if isinstance(strings_data, JsonResponse): return strings_data return Response(strings_data, status=status.HTTP_200_OK) class GetRawDataExtended(APIView): """ GET /api/get_raw_data_extended/ Returns ALL raw data including firmware data. """ def get(self, request, file_id, *args, **kwargs): raw_data = get_raw_data_by_file_extended(file_id) if isinstance(raw_data, JsonResponse): return raw_data return Response(raw_data, status=status.HTTP_200_OK) class UploadFirmware(APIView): """ POST /api/upload_firmware Uploads a .bin firmware and starts automatic analysis. Body: { "device_id": int, "firmware_version": str, "filename": str, "ip_address": str, "status": str } """ def post(self, request): device_id = request.data.get('device_id') firmware_version = request.data.get('firmware_version') filename = request.data.get('filename') ip_address = request.data.get('ip_address') file_status = request.data.get('status') # Validation if not all([device_id, firmware_version, filename, ip_address, file_status]): return Response( {"error": "Missing required fields"}, status=status.HTTP_400_BAD_REQUEST ) # Check whether it is a .bin file if not filename.lower().endswith('.bin'): return Response( {"error": "Only .bin files are supported for firmware analysis"}, status=status.HTTP_400_BAD_REQUEST ) # Create file (as with PCAP) response = create_file_with_firmware_version( device_id, firmware_version, filename, ip_address, file_status ) # If file creation was successful, start firmware analysis if isinstance(response, JsonResponse): response_data = json.loads(response.content.decode('utf-8')) if response_data.get('status') == 'success': file_id = response_data['data']['id'] # Raw dataset was already created in create_file_with_firmware_version # Trigger firmware analysis (analogous to analyze_pcap_file) from .analyze.analyze_firmware import analyze_firmware_file from .models import RawDataset try: raw_dataset = RawDataset.objects.get(file_id=file_id) analyze_firmware_file(filename, raw_dataset.id) except Exception as e: logger.error(f"Firmware analysis failed: {e}") # Convert JsonResponse to Response return Response(response_data, status=response.status_code) # If response is not a JsonResponse, return it directly return response # Add import statements at the top of views.py: # from .db_read import ( # get_all_binwalk_raw_data_from_file, # get_all_strings_raw_data_from_file, # get_strings_by_type, # get_all_binwalk_analyzed_data_from_file, # get_all_strings_analyzed_data_from_file, # get_critical_strings_by_severity, # get_raw_data_by_file_extended # )