Resumen
Función central de evaluación de permisos en el núcleo. Verifica si un usuario tiene acceso a una acción específica (scope/level) según una jerarquía de cuatro capas.
Función: core.utils.permissions.has_permission(user, scope: str, level: str = "view") -> bool
Módulo: core/utils/permissions.py
Arquitectura de evaluación (4 capas)
1. Role-based defaults (SaaSModule + Plan)
↓ (si existe)
2. TemporaryAccess (grants temporales por tiempo limitado)
↓ (si existe + si DB disponible)
3. ModulePermission (overrides explícitos por usuario)
↓ (si existe + si DB disponible)
4. Fallback a role defaults
Primero se evalúa rol; si hay grant temporal o override explícito, se usa. Si no, vuelve a los defaults del rol.
Parámetros
user— Usuario Django (tenga o norole,organization,module_permissions, etc.).scope— Cadena del dominio (racks,network,inventory,monitoring, etc.).level— Nivel de acceso:view,edit,admin. Default:view.
Retorno
True— Usuario tiene permisos.False— Usuario no tiene permisos.
Orden jerárquico de niveles
LEVEL_ORDER = {"view": 1, "edit": 2, "admin": 3}
Nivel edit incluye view. Nivel admin incluye edit y view.
Requisitos de seguridad (s104) — Fail-open fix
Problema histórico: Los bloques try/except de TemporaryAccess y ModulePermission tragaban toda excepción con except Exception: pass, incluyendo errores inesperados de BD. Esto causaba un fail-open silencioso: ante un error BD imprevisto, el usuario caía a los defaults del rol (potencialmente más permisivo que una denegación explícita).
Fix (s104, 2026-06-02):
- El
exceptse estrecha aProgrammingError/OperationalError(caso “tabla no migrada” en deployments iniciales). - Cualquier otra excepción se registra con
logger.exception(...), haciendo visible el fallo. - El usuario sigue cayendo a los defaults del rol, pero el error está documentado en logs.
Casos de uso
- Verificar acceso al endpoint
GET /api/credentials/{id}/decrypt→ requierenetwork/edit. - Verificar acceso al endpoint
PUT /api/settings/company→ requiereis_admin(). - Filtros en vistas (ej.
if has_permission(user, "racks", "edit"): ...). - Gate de mutadores HTMX de racks/papelera (
core/htmx_views.py) — antes solo@login_requireddejaba mutar a cualquier readonly; ahorahas_permission(request.user, "racks", level)+ fragmento 403 (racks:editen creación/edición,racks:adminen borrado permanente y vaciado de papelera). Tanda 1 Auditoría Suprema 2, v1.90.0.
Corrección 06-09-2026 (task #279, v1.118.0, commit b160abd9): core/htmx_device_groups.py (grupos de dispositivos) exigía has_permission(request.user, "racks", level) — dominio equivocado, copiado de los mutadores de racks de arriba. Un grupo de dispositivos es dominio “network”, no “racks”: ahora network:edit al crear y network:admin al borrar, alineado con sus gemelos de la API Ninja (network/api/device_groups.py::create_device_group/delete_device_group). Se añadió también log_action en ambos mutadores, que no lo tenían.
Tests
tests/test_permissions.py::test_unexpected_error_is_logged_not_swallowed— Fallo no-BD →logger.exception()invocado.tests/test_permissions.py::test_migration_error_stays_silent—ProgrammingError→ sin logging (esperado).tests/test_htmx_authz.py— tests del gate en mutadores HTMX (racks/papelera/grupos); +3 tests 06-09-2026 (task #279) cubriendo el nuevo scopenetworkdecore/htmx_device_groups.py(usuario connetwork:noneno crea,operatorno borra sinnetwork:admin,adminsí borra).
Véase también
- [[entity—core—model—temporary-access]]
- [[entity—core—model—module-permission]]
- [[entity—core—service—decrypt-credential]]
- [[entity—core—endpoint—update-company-settings]]
- [[feature—security—s104-auditoria-suprema-fixes-core]]
- [[concept—security—fail-open]]
- [[concept—security—role-based-access-control]]
- [[feature—security—auditoria-suprema-2-tanda-1-core]]
- [[entity—core—service—require-perm]]
Referenciado desde
- Auditoría Suprema 2 · Tanda 1 (core) — cerrar gates de permiso que faltaban
- Auditoría Suprema 2 · Tanda 1 (monitoring + racks): gates de permiso en Observatory, CNS y radar de integridad
- Auditoría Suprema 2 · Tanda 9: SSRF por IPv6 mapeada, XSS almacenado en stencils y borde anónimo de signage
- Decision · Auditoría Suprema: 4 hallazgos ALTA confirmados en core
- Feature s104 · Auditoría Suprema — 4 arreglos de seguridad en el núcleo
- Incident · Auditoría Suprema (s104): Mini-tanda de arreglos de seguridad core
- IP real del visitante a prueba de Cloudflare (v1.45.13)
- Mega-auditoría T02 (24-09-2026): la gestión de usuarios sin las reglas de la API, sin candado ante superiores y sin rastro
- Refactor R7 lote P2 · Autorización por scope módulo (is_admin → require_perm)
- Servicio decrypt_credential — Descifrado de credenciales
- Task #279 · gates de permisos que faltaban en 3 zonas + test de contrato universal