# pxy_dashboard/middleware.py import re from django.conf import settings from django.shortcuts import redirect from django.urls import reverse from django.utils.deprecation import MiddlewareMixin EXEMPT_URLS = [ reverse("account_login"), reverse("account_logout"), reverse("account_signup"), reverse("account_reset_password"), reverse("account_reset_password_done"), # These can't be reversed without args "/accounts/password/reset/key/done/", ] EXEMPT_URLS += [re.compile(r"^accounts/password/reset/key/.+$")] EXEMPT_URLS += [re.compile(expr) for expr in [ r"^admin/", r"^accounts/", r"^static/", r"^media/", ]] # ————— aquí añadimos los webhooks de WhatsApp ————— # Como path_info.lstrip("/") será "whatsapp/webhook/" y "whatsapp/webhook/verify/" EXEMPT_URLS += [ "pxy_whatsapp/webhook/", "pxy_whatsapp/webhook/verify/", ] EXEMPT_URLS += [ re.compile(r"^pxy_whatsapp/webhook/?$"), re.compile(r"^pxy_whatsapp/webhook/verify/?$"), ] # Webhook de Telegram EXEMPT_URLS += [ "bots/webhook/", # prefijo general re.compile(r"^bots/webhook/.+/$"), # con al final ] # Webhook de Facebook Pages (pxy_meta_pages) EXEMPT_URLS += [ re.compile(r"^pxy_meta_pages/webhook/?$"), ] # Webhook de Facebook Messenger EXEMPT_URLS += [ "messenger/webhook/", # exact string match (no leading slash) re.compile(r"^messenger/webhook/?$"), # regex with optional trailing slash ] # SAMI API (public for bot/agents; add auth later if needed) EXEMPT_URLS += [ re.compile(r"^api/sami/health$"), re.compile(r"^api/sami/run$"), ] # Routing API health (public for now) EXEMPT_URLS += [ re.compile(r"^api/routing/health$"), ] # Sites API (public for now) EXEMPT_URLS += [ re.compile(r"^api/sites/health$"), re.compile(r"^api/sites/search$"), ] # Routing API isochrone (público para demo) EXEMPT_URLS += [ re.compile(r"^api/routing/isochrone$"), ] # pxy_dashboard/middleware.py (añadir a EXEMPT_URLS) EXEMPT_URLS += [ re.compile(r"^api/sites/download/.+$"), ] EXEMPT_URLS += [ re.compile(r"^api/sites/geojson/.+$"), ] EXEMPT_URLS += [ re.compile(r"^api/sites/preview/.+$"), ] # Telegram webhook (with /api/ prefix) EXEMPT_URLS += [ "api/bots/webhook/", re.compile(r"^api/bots/webhook/.+/?$"), ] # (Optional) health, if you want it public EXEMPT_URLS += [ re.compile(r"^api/bots/health/?$") ] EXEMPT_URLS += [ re.compile(r"^api/bots/echo_render$") ] # pxy_dashboard/middleware.py (append to EXEMPT_URLS) EXEMPT_URLS += [ re.compile(r"^api/bots/template_reply$"), ] # LangChain API (public for bots) EXEMPT_URLS += [ re.compile(r"^api/langchain/chat/?$"), ] EXEMPT_URLS += [ re.compile(r"^api/openai/transcribe$"), ] EXEMPT_URLS += [ re.compile(r"^api/openai/voice_chat$"), ] # Contracts (public for interop/coral tooling) EXEMPT_URLS += [ re.compile(r"^api/contracts/(sami|sites)\.json$"), ] # Coral-style agents catalog & execute (public for MVP) EXEMPT_URLS += [ re.compile(r"^api/agents/list$"), re.compile(r"^api/agents/execute$"), ] class LoginRequiredMiddleware(MiddlewareMixin): def process_request(self, request): if not request.user.is_authenticated: path = request.path_info.lstrip("/") if not any(url.match(path) if hasattr(url, 'match') else path == url.lstrip("/") for url in EXEMPT_URLS): return redirect(settings.LOGIN_URL)