From 788667b6877eb15dff5054f3667abebbe6d11385 Mon Sep 17 00:00:00 2001 From: dekzter Date: Wed, 11 Jun 2025 08:24:32 -0400 Subject: [PATCH] better error checking, only warn for UI blocking --- core/api_views.py | 53 +++++++++++++++++++++++++-------- frontend/src/pages/Settings.jsx | 39 +++++++++++++++++++++--- 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/core/api_views.py b/core/api_views.py index bf6ee2ba..2f01b503 100644 --- a/core/api_views.py +++ b/core/api_views.py @@ -5,7 +5,13 @@ import ipaddress from rest_framework import viewsets, status from rest_framework.response import Response from django.shortcuts import get_object_or_404 -from .models import UserAgent, StreamProfile, CoreSettings, STREAM_HASH_KEY +from .models import ( + UserAgent, + StreamProfile, + CoreSettings, + STREAM_HASH_KEY, + NETWORK_ACCESS, +) from .serializers import ( UserAgentSerializer, StreamProfileSerializer, @@ -63,18 +69,41 @@ class CoreSettingsViewSet(viewsets.ModelViewSet): def check(self, request, *args, **kwargs): data = request.data - client_ip = ipaddress.ip_address(get_client_ip(request)) - in_network = [] - key = data.get("key") - value = json.loads(data.get("value", "{}")) - for key, val in value.items(): - cidrs = val.split(",") - for cidr in cidrs: - network = ipaddress.ip_network(cidr) - if client_ip not in network: - in_network.append(cidr) + if data.get("key") == NETWORK_ACCESS: + client_ip = ipaddress.ip_address(get_client_ip(request)) - return Response(in_network, status=status.HTTP_200_OK) + in_network = {} + invalid = [] + + value = json.loads(data.get("value", "{}")) + for key, val in value.items(): + in_network[key] = [] + cidrs = val.split(",") + for cidr in cidrs: + try: + network = ipaddress.ip_network(cidr) + + if client_ip in network: + in_network[key] = [] + break + + in_network[key].append(cidr) + except: + invalid.append(cidr) + + if len(invalid) > 0: + return Response( + { + "error": True, + "message": "Invalid CIDR(s)", + "data": invalid, + }, + status=status.HTTP_200_OK, + ) + + return Response(in_network, status=status.HTTP_200_OK) + + return Response({}, status=status.HTTP_200_OK) @swagger_auto_schema( diff --git a/frontend/src/pages/Settings.jsx b/frontend/src/pages/Settings.jsx index b4fc37cc..073af337 100644 --- a/frontend/src/pages/Settings.jsx +++ b/frontend/src/pages/Settings.jsx @@ -34,6 +34,7 @@ const SettingsPage = () => { const [accordianValue, setAccordianValue] = useState(null); const [networkAccessSaved, setNetworkAccessSaved] = useState(false); + const [networkAccessError, setNetworkAccessError] = useState(null); const [networkAccessConfirmOpen, setNetworkAccessConfirmOpen] = useState(false); const [netNetworkAccessConfirmCIDRs, setNetNetworkAccessConfirmCIDRs] = @@ -316,6 +317,21 @@ const SettingsPage = () => { acc[key] = '0.0.0.0/0'; return acc; }, {}), + validate: Object.keys(NETWORK_ACCESS_OPTIONS).reduce((acc, key) => { + acc[key] = (value) => { + const cidrs = value.split(','); + for (const cidr of cidrs) { + if (cidr.match(/^([0-9]{1,3}\.){3}[0-9]{1,3}\/\d+$/)) { + continue; + } + + return 'Invalid CIDR range'; + } + + return null; + }; + return acc; + }, {}), }); useEffect(() => { @@ -383,16 +399,24 @@ const SettingsPage = () => { const onNetworkAccessSubmit = async () => { setNetworkAccessSaved(false); + setNetworkAccessError(null); const check = await API.checkSetting({ ...settings['network-access'], value: JSON.stringify(networkAccessForm.getValues()), }); - if (check.length == 0) { + if (check.error && check.message) { + setNetworkAccessError(`${check.message}: ${check.data}`); + return; + } + + // For now, only warn if we're blocking the UI + const blockedAccess = check.UI; + if (blockedAccess.length == 0) { return saveNetworkAccess(); } - setNetNetworkAccessConfirmCIDRs(check); + setNetNetworkAccessConfirmCIDRs(blockedAccess); setNetworkAccessConfirmOpen(true); }; @@ -627,6 +651,13 @@ const SettingsPage = () => { title="Saved Successfully" > )} + {networkAccessError && ( + + )} {Object.entries(NETWORK_ACCESS_OPTIONS).map( ([key, config]) => { return ( @@ -672,8 +703,8 @@ const SettingsPage = () => { message={ <> - Your client is included in the following CIDRs and could block - access Are you sure you want to proceed? + Your client is not included in the allowed networks for the web + UI. Are you sure you want to proceed?