Añade foro de comunidad integrado (app forum) con el diseño de NovaWoW

- app 'forum': portada (categorías/foros), ver foro y tema (paginado), crear tema,
  responder, editar/borrar posts y moderación (fijar, bloquear, mover, borrar/restaurar)
- lee/escribe la BD acore_web (5ª conexión, DB_NAME_WEB) por SQL directo, tablas
  forum_categories/forums/forum_topics/forum_posts/forum_reads (portado de NovaWeb-main)
- identidad = cuenta de juego en sesión; permisos simplificados por gmlevel
  (FORUM_MOD_GMLEVEL) en vez de la matriz group_level×permission del original
- saneado del HTML de posts con nh3 (evita el XSS del original); POST+CSRF en formularios
- plantillas con los partials del sitio; enlace 'FOROS' del menú apunta al foro interno
- sql/forum_schema.sql y docs/FORO.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 17:10:55 +00:00
parent 2162fe34d0
commit 2c30844bf7
21 changed files with 1385 additions and 1 deletions
+77
View File
@@ -0,0 +1,77 @@
# 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.
- Perfil público básico (`/es/profile/<usuario>`).
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.
- Formularios de publicar/responder/editar/mover van por **POST con CSRF**.
- ⚠️ Pendiente de endurecer: las acciones de moderación (bloquear, borrar,
restaurar, fijar) son enlaces **GET** (como en el original). Para producción se
recomienda pasarlas a POST con CSRF.
## 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.)
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
- Editor enriquecido (CKEditor/TinyMCE) en el textarea de posts (ahora es
texto/HTML saneado; los saltos de línea se respetan por CSS `pre-wrap`).
- El autor se muestra como el nombre de cuenta de juego (`<bnetId>#1`); se podría
mapear a un nick o al email como en «Mi cuenta».
- Endurecer las acciones de moderación a POST+CSRF.