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/openPreviewStart", "/analysis/openPreviewStop")): 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 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. 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