video_monitor/app/middleware.py
2026-08-30 22:23:12 +08:00

70 lines
2.5 KiB
Python

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
if path.startswith(("/analysis/openStart", "/analysis/openStop", "/analysis/openReload")):
return ROLE_OPERATOR
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
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