video_monitor/app/middleware.py

79 lines
3.0 KiB
Python
Raw Normal View History

2026-08-30 22:22:11 +08:00
from django.http import HttpResponseRedirect, JsonResponse
from app.security import verify_internal_request
try:
from django.utils.deprecation import MiddlewareMixin
except ImportError:
MiddlewareMixin = object
PUBLIC_EXACT_PATHS = frozenset(('/login', '/logout', '/user/openCaptcha'))
PUBLIC_PREFIXES = ('/static/',)
ROLE_SYSTEM_ADMIN = "system_admin"
ROLE_ALGORITHM_ADMIN = "algorithm_admin"
ROLE_OPERATOR = "operator"
def _required_role(path, method):
if path.startswith(("/system/", "/user/")) or path == "/index/openMediaControl":
return ROLE_SYSTEM_ADMIN
if path.startswith(("/smallmodel/", "/algorithm/", "/llm/")):
return ROLE_ALGORITHM_ADMIN
if method != "GET" and path.startswith(("/stream/", "/nvr/", "/control/", "/zone/", "/alarm/")):
return ROLE_OPERATOR
2026-09-06 22:26:35 +08:00
if method != "GET" and path.startswith("/workshop/"):
return ROLE_OPERATOR
2026-08-30 22:22:11 +08:00
if path.startswith(("/analysis/openStart", "/analysis/openStop", "/analysis/openReload")):
return ROLE_OPERATOR
2026-09-04 18:16:14 +08:00
if path.startswith(("/analysis/openPreviewStart", "/analysis/openPreviewStop")):
return ROLE_OPERATOR
2026-08-30 22:22:11 +08:00
if path.startswith(("/analysis/openUpdate", "/analysis/openToggle", "/analysis/openRestart")):
return ROLE_ALGORITHM_ADMIN
return ""
def _has_role(user, required):
if user.is_superuser:
return True
roles = set(user.groups.values_list("name", flat=True))
if ROLE_SYSTEM_ADMIN in roles:
return True
if required == ROLE_ALGORITHM_ADMIN:
return ROLE_ALGORITHM_ADMIN in roles
if required == ROLE_OPERATOR:
return ROLE_OPERATOR in roles or ROLE_ALGORITHM_ADMIN in roles
return True
class SimpleMiddleware(MiddlewareMixin):
def process_request(self, request):
path = request.path_info
2026-09-04 18:16:14 +08:00
if path in ('/setup', '/license', '/license/status', '/license/request', '/license/import'):
from monitor_runtime.paths import DESKTOP
if DESKTOP:
return None # Dedicated views enforce local bootstrap/admin access.
2026-08-30 22:22:11 +08:00
if path.startswith('/inner/'):
if verify_internal_request(request):
return None
return JsonResponse({"code": 0, "msg": "forbidden"}, status=403)
if path in PUBLIC_EXACT_PATHS or any(path.startswith(prefix) for prefix in PUBLIC_PREFIXES):
return None
if getattr(request, "user", None) is not None and request.user.is_authenticated:
if path.startswith("/login"):
return HttpResponseRedirect("/")
required = _required_role(path, request.method)
if required and not _has_role(request.user, required):
if "/open" in path:
return JsonResponse({"code": 0, "msg": "forbidden"}, status=403)
return HttpResponseRedirect("/forbidden")
return None
return HttpResponseRedirect("/login")
def process_response(self, request, response):
return response