# Foro integrado (app `forum`) Foro de comunidad reimplementado en Django dentro de NovaWoW, con el **diseño del propio sitio** (usa los `partials` head/header/footer). Portado desde la app Symfony *NovaWeb-main*, contra las **mismas tablas** en la base de datos `acore_web`. ## Arquitectura - **BD**: `acore_web` (5ª conexión Django, `DB_NAME_WEB`). Acceso por SQL directo (`connections['acore_web']`), mismo estilo que el resto del proyecto. - **Tablas**: `forum_categories`, `forums`, `forum_topics`, `forum_posts`, `forum_reads`. (La tabla legacy `forum_forums` NO se usa.) - **Identidad del autor**: la cuenta de juego en sesión de NovaWoW (`session['account_id']` / `session['username']`). No usa las cookies del proyecto original. ## Funcionalidad (completa) - Portada con categorías y foros (contadores de temas/mensajes, último tema). - Ver foro: lista de temas paginada. - Ver tema: posts paginados, con panel de autor (rol, registro, nº de mensajes). - Crear tema, responder, editar y borrar el post propio. - Moderación: fijar/desfijar, bloquear/desbloquear, mover, borrar/restaurar temas y posts. - Buscador de temas (por título y contenido) **paginado** en `/es/forum/search`. - Contador de **visitas** por tema (columna opcional `forum_topics.views`). - Perfil público básico (`/es/profile/`). - El autor se muestra con un **nombre legible** (parte local del email de la cuenta) en vez de `#1`. Rutas bajo `/es/forum...` (idénticas al original: `app_forum`, `forum_view`, `forum_topic`, `forum_create_topic`, etc.). ## Modelo de permisos (simplificado) En vez de la matriz `group_level`×`permission` del original (enrevesada y con acciones que quedaban deshabilitadas por falta de filas), se usa un modelo claro en `forum/permissions.py`: - **Ver**: foros públicos (`visibility=1`, `deleted=0`) visibles para todos. - **Publicar / responder / crear tema**: cualquier usuario con sesión iniciada y cuenta de juego seleccionada. - **Editar / borrar** un post: su autor, o un moderador. - **Moderar**: cuentas con `gmlevel >= FORUM_MOD_GMLEVEL` (por defecto **2**), leído de `acore_auth.account_access`. ## Seguridad - El texto de los posts se **sanea con `nh3`** (allowlist de etiquetas) al guardar — `forum/sanitize.py` — evitando el XSS que tenía el original (que renderizaba HTML del editor sin filtrar). Se renderiza con `|safe` ya saneado. - **Todas** las acciones que modifican datos (publicar, responder, editar, mover, bloquear/desbloquear, fijar, borrar/restaurar temas y posts) van por **POST**, y las vistas mutadoras llevan **`@csrf_protect`** (fuerza la validación CSRF por vista aunque el middleware global no esté activo). - El HTML de los posts también se **sanea al renderizar** con el filtro `forum_safe` (defensa en profundidad frente a datos heredados sin sanear). - Acceso a temas de foros ocultos/borrados bloqueado también por URL directa (no solo en los listados). > ✅ **CSRF global activado** (todo el portal): `novawow/settings.py` ya incluye > `django.middleware.csrf.CsrfViewMiddleware`. Las peticiones AJAX (jQuery) envían > la cabecera `X-CSRFToken` automáticamente (`$.ajaxSetup` en `partials/head.html`), > los formularios nativos llevan `{% csrf_token %}`, y solo los webhooks externos > (`stripe_webhook`, `sumup_webhook`) mantienen `@csrf_exempt`. ## Editor Los mensajes se escriben con **CKEditor 5** (el mismo editor que usa el resto de NovaWoW), vía `forum/forms.py` (`TopicForm`, `ReplyForm`, `EditPostForm`). El HTML que produce el editor se **sanea con nh3** al guardar, así que el rich text es seguro. ## Despliegue 1. Crear/usar la BD `acore_web` y aplicar el esquema: ```bash mysql acore_web < sql/forum_schema.sql ``` (Si ya existe la BD del portal Symfony con esas tablas, apunta `DB_NAME_WEB` a ella y omite este paso.) - Opcional (contador de visitas): `mysql acore_web < sql/forum_views.sql`. El foro detecta la columna automáticamente y funciona sin ella. 2. Configurar variables de entorno: ``` DB_NAME_WEB=acore_web FORUM_MOD_GMLEVEL=2 FORUM_TOPICS_PER_PAGE=20 FORUM_POSTS_PER_PAGE=15 ``` 3. El enlace «FOROS» del menú COMUNIDAD ya apunta al foro interno (`/es/forum`). ## Notas / posibles mejoras - Sistema de nicks propio del foro (ahora el nombre visible es la parte local del email de la cuenta). - Avatares de usuario y firmas.