mirror of
https://github.com/i701/sarlink-portal-api.git
synced 2025-06-28 22:03:59 +00:00
Refactor device management: add vendor field, enhance admin display, and improve MAC address handling
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 4m18s
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 4m18s
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
from attr import dataclass
|
||||
from rest_framework import generics, status
|
||||
from rest_framework.response import Response
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
@ -11,6 +12,8 @@ from .serializers import (
|
||||
from api.mixins import StaffEditorPermissionMixin
|
||||
from .filters import DeviceFilter
|
||||
import re
|
||||
import requests
|
||||
from decouple import config
|
||||
|
||||
|
||||
class DeviceListCreateAPIView(
|
||||
@ -26,7 +29,6 @@ class DeviceListCreateAPIView(
|
||||
def list(self, request, *args, **kwargs):
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
|
||||
# Filter devices by the logged-in user unless the user is a superuser
|
||||
if not request.user.is_superuser:
|
||||
queryset = queryset.filter(user=request.user)
|
||||
|
||||
@ -43,24 +45,31 @@ class DeviceListCreateAPIView(
|
||||
return CreateDeviceSerializer
|
||||
return DeviceSerializer
|
||||
|
||||
# @method_decorator(cache_page(10))
|
||||
def create(self, request, *args, **kwargs):
|
||||
mac = request.data.get("mac", None)
|
||||
if not re.match(r"^([0-9A-Fa-f]{2}([.:-]?)){5}[0-9A-Fa-f]{2}$", mac):
|
||||
MAC_REGEX = re.compile(r"^([0-9A-Fa-f]{2}([.:-]?)){5}[0-9A-Fa-f]{2}$")
|
||||
NORMALIZE_MAC_REGEX = re.compile(r"[^0-9A-Fa-f]")
|
||||
if not isinstance(mac, str) or not MAC_REGEX.match(mac):
|
||||
return Response({"message": "Invalid mac address."}, status=400)
|
||||
if Device.objects.filter(mac=mac).exists():
|
||||
return Response(
|
||||
{"message": "Device with this mac address already exists."}, status=400
|
||||
)
|
||||
mac_details = get_mac_address_details(mac)
|
||||
if mac_details.vendor == "Unknown":
|
||||
return Response({"message": "MAC address vendor not found."}, status=400)
|
||||
|
||||
# Normalize MAC address to use "-" as separators
|
||||
mac = re.sub(r"[^0-9A-Fa-f]", "-", mac).upper()
|
||||
mac = re.sub(NORMALIZE_MAC_REGEX, "-", mac).upper()
|
||||
request.data["mac"] = mac
|
||||
|
||||
return super().create(request, *args, **kwargs)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
serializer.save(user=self.request.user)
|
||||
mac_details = get_mac_address_details(serializer.validated_data.get("mac"))
|
||||
serializer.save(
|
||||
user=self.request.user,
|
||||
vendor=mac_details.vendor,
|
||||
)
|
||||
|
||||
|
||||
class DeviceDetailAPIView(StaffEditorPermissionMixin, generics.RetrieveAPIView):
|
||||
@ -138,3 +147,26 @@ class DeviceDestroyAPIView(StaffEditorPermissionMixin, generics.DestroyAPIView):
|
||||
{"message": f"Device '{device_name}' deleted."},
|
||||
status=status.HTTP_200_OK,
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class MacResponse:
|
||||
mac_address: str
|
||||
vendor: str
|
||||
detail: str | None = None
|
||||
|
||||
|
||||
def get_mac_address_details(mac: str) -> MacResponse:
|
||||
API_URL = config("MACVENDOR_API_URL")
|
||||
if not API_URL:
|
||||
raise ValueError("MACVENDOR API URL Not set. Please set it.")
|
||||
response = requests.get(f"{API_URL}/lookup/{mac}")
|
||||
json_data = response.json()
|
||||
if response.status_code == 200:
|
||||
return MacResponse(
|
||||
mac_address=json_data.get("mac_address", mac),
|
||||
vendor=json_data.get("vendor", ""),
|
||||
detail=json_data.get("detail"),
|
||||
)
|
||||
else:
|
||||
return MacResponse(mac_address=mac, vendor="Unknown", detail=None)
|
||||
|
Reference in New Issue
Block a user