Niveles de permiso#
Sistema de permisos de seis niveles (NIVELES_ACCESO) para control de acceso.
Descripción general#
Seis niveles de permiso:
Auxiliar (1) - Ver solo
Coordinador (2) - Crear y editar
Director (3) - Operaciones CRUD completas
Corporativo (4) - Acceso entre empresas
Soporte (5) - Soporte/mantenimiento
Superusuario (6) - Acceso completo al sistema
Implementación: Clave externa en modelo de Usuario apuntando a NivelAcceso.
Modelo NivelAcceso#
Archivo: construbot/users/models.py
class NivelAcceso(models.Model):
"""Permission level definition"""
nombre = models.CharField(max_length=50) # Name
nivel = models.IntegerField(unique=True) # Level number (1-6)
descripcion = models.TextField(blank=True)
class Meta:
ordering = ['nivel']
verbose_name_plural = 'Niveles de Acceso'
def __str__(self):
return f"{self.nivel} - {self.nombre}"
Niveles predeterminados:
# Populated via migration or fixtures
1 - Auxiliar
2 - Coordinador
3 - Director
4 - Corporativo
5 - Soporte
6 - Superusuario
Asignación de usuarios#
class User(AbstractUser):
nivel_acceso = models.ForeignKey(
NivelAcceso,
on_delete=models.PROTECT,
related_name='users'
)
Nivel de configuración:
user = User.objects.get(email='user@example.com')
user.nivel_acceso = NivelAcceso.objects.get(nivel=3) # Director
user.save()
Verificaciones de permisos#
Ver decoradores#
def nivel_required(min_level):
"""Decorator to require minimum permission level"""
def decorator(view_func):
@wraps(view_func)
def wrapper(request, *args, **kwargs):
if not request.user.is_authenticated:
return redirect('login')
if request.user.nivel_acceso.nivel < min_level:
raise PermissionDenied(f"Requires level {min_level}")
return view_func(request, *args, **kwargs)
return wrapper
return decorator
# Usage
@nivel_required(3) # Director or higher
def delete_contract(request, contract_id):
...
Vistas basadas en clases#
class NivelRequiredMixin:
"""Mixin for permission level check"""
required_nivel = 1 # Override in subclass
def dispatch(self, request, *args, **kwargs):
if request.user.nivel_acceso.nivel < self.required_nivel:
raise PermissionDenied()
return super().dispatch(request, *args, **kwargs)
class ContractDeleteView(NivelRequiredMixin, DeleteView):
required_nivel = 3 # Director
model = Contrato
Verificaciones de plantilla#
{% if user.nivel_acceso.nivel >= 3 %}
<a href="{% url 'delete_contract' contract.id %}">Delete</a>
{% endif %}
{% if user.nivel_acceso.nivel == 6 %}
<div class="admin-panel">...</div>
{% endif %}
Capacidades específicas de nivel#
1. Auxiliar (solo ver)#
Permisos:
Ver contratos, estimaciones, informes.
No crear/editar/eliminar
Caso de uso: Trabajadores de campo, acceso de solo lectura
@nivel_required(1)
def view_contract(request, contract_id):
# Can view but not edit
2. Coordinador (Crear/Editar)#
Permisos:
Todos los permisos auxiliares
Crear nuevos registros
Editar registros existentes
No se puede eliminar
Caso de uso: Coordinadores de proyecto
@nivel_required(2)
def create_estimate(request):
# Can create estimates
3. Director (CRUD completo)#
Permisos:
Todos los permisos del Coordinador
Eliminar registros
Aprobar estimaciones
Generar informes
Caso de uso: Gerentes de proyecto, directores
@nivel_required(3)
def delete_contract(request, contract_id):
# Can delete contracts
4. Corporativo (Multiempresa)#
Permisos:
Todos los permisos del director
Accede a múltiples empresas
Informes entre empresas
Configuración a nivel de empresa
Caso de uso: Gestión a nivel corporativo
@nivel_required(4)
def corporate_report(request):
# Access all companies under customer
companies = Company.objects.filter(customer=request.user.customer)
5. Soporte (Acceso de soporte)#
Permisos:
Acceso al soporte técnico
Diagnóstico del sistema
Asistencia al usuario
Configuración limitada
Caso de uso: Personal de soporte técnico
@nivel_required(5)
def system_diagnostics(request):
# Support-only features
6. Superusuario (Acceso Completo)#
Permisos:
Todo el acceso al sistema.
Administrador de Django
Gestión de usuarios
Configuración del sistema
Caso de uso: Administradores del sistema
# Django superuser check
if request.user.is_superuser:
# Full access
Combinando con el alcance de la empresa#
Combine siempre la verificación de nivel con el alcance de la empresa:
@login_required
@nivel_required(2)
def create_contract(request):
# Level check passed
company = request.user.active_company
if request.method == 'POST':
contract = form.save(commit=False)
contract.company = company # Company scope
contract.save()
Permisos API#
from rest_framework.permissions import BasePermission
class HasNivelAcceso(BasePermission):
"""DRF permission for nivel check"""
def has_permission(self, request, view):
required_level = getattr(view, 'required_nivel', 1)
return request.user.nivel_acceso.nivel >= required_level
# Usage
class ContractViewSet(viewsets.ModelViewSet):
required_nivel = 3
permission_classes = [IsAuthenticated, HasNivelAcceso]
Mejores prácticas#
1. Utilice el nivel mínimo requerido:
# GOOD - requires minimum needed
@nivel_required(2)
def edit_view(request):
...
# BAD - unnecessarily restrictive
@nivel_required(6) # Unless truly needed
2. Verifique vistas, no plantillas:
# GOOD - security in view
@nivel_required(3)
def delete_view(request):
...
# BAD - relying only on template hiding
# <a href="delete">Delete</a> (no view protection)
3. Combinar cheques:
@login_required
@nivel_required(3)
def delete_contract(request, contract_id):
contract = get_object_or_404(Contrato, id=contract_id)
# Also verify company access
if contract.company != request.user.active_company:
raise PermissionDenied()
contract.delete()
4. Niveles de documentación requeridos:
@nivel_required(3)
def delete_contract(request, contract_id):
"""
Delete a contract.
Requires: Director level (3) or higher
"""
Solución de problemas#
Errores de permiso denegado:
Consultar nivel_acceso del usuario
Verifique que el nivel requerido sea correcto
Confirmar que el usuario está autenticado
El usuario no puede acceder a la función:
Consultar asignación nivel_acceso
Verificar que se haya aplicado el decorador de permisos
Confirmar que el umbral de nivel es apropiado
Ver también#
Autenticación - Authentication system
Multi-inquilino - Multi-company architecture
../models/users - User model reference