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:
@@ -0,0 +1,71 @@
|
||||
"""
|
||||
Modelo de permisos del foro (versión simplificada y mantenible).
|
||||
|
||||
En lugar de la matriz group_level×permission del proyecto original, usamos
|
||||
reglas claras basadas en:
|
||||
* si el usuario ha iniciado sesión y tiene una cuenta de juego seleccionada
|
||||
(``request.session['account_id']``),
|
||||
* su nivel GM (``acore_auth.account_access.gmlevel``),
|
||||
* y la propiedad del contenido (autor == usuario).
|
||||
"""
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import connections
|
||||
|
||||
|
||||
def get_account_id(request):
|
||||
"""Id de la cuenta de juego seleccionada en sesión, o None."""
|
||||
return request.session.get('account_id')
|
||||
|
||||
|
||||
def is_authenticated(request):
|
||||
return bool(request.session.get('account_id'))
|
||||
|
||||
|
||||
def get_gmlevel(account_id):
|
||||
"""Nivel GM máximo de una cuenta (acore_auth.account_access). 0 si no tiene."""
|
||||
if not account_id:
|
||||
return 0
|
||||
try:
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
cursor.execute(
|
||||
"SELECT MAX(gmlevel) FROM account_access WHERE id = %s",
|
||||
[account_id],
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
return int(row[0]) if row and row[0] is not None else 0
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
|
||||
def is_moderator(request):
|
||||
"""¿El usuario puede moderar el foro?"""
|
||||
account_id = get_account_id(request)
|
||||
if not account_id:
|
||||
return False
|
||||
return get_gmlevel(account_id) >= settings.FORUM_MOD_GMLEVEL
|
||||
|
||||
|
||||
def can_post(request):
|
||||
"""¿Puede crear temas / responder? Cualquier usuario autenticado."""
|
||||
return is_authenticated(request)
|
||||
|
||||
|
||||
def can_edit_post(request, post):
|
||||
"""Puede editar/borrar un post: su autor o un moderador."""
|
||||
account_id = get_account_id(request)
|
||||
if not account_id:
|
||||
return False
|
||||
if post and int(post.get('poster_id') or 0) == int(account_id):
|
||||
return True
|
||||
return is_moderator(request)
|
||||
|
||||
|
||||
def forum_context(request):
|
||||
"""Datos comunes de permisos para las plantillas."""
|
||||
return {
|
||||
'forum_is_authenticated': is_authenticated(request),
|
||||
'forum_is_moderator': is_moderator(request),
|
||||
'forum_account_id': get_account_id(request),
|
||||
'forum_username': request.session.get('username'),
|
||||
}
|
||||
Reference in New Issue
Block a user