# Sistema de Control de Acceso Basado en Roles (RBAC)

## 📋 Resumen Ejecutivo

El campamento cuenta con un sistema de 6 roles con permisos diferenciados:

| Rol | Acceso Principal | Permisos Especiales |
|-----|------------------|-------------------|
| **admin** | TODO | Acceso total a todas las vistas, menú administrativo |
| **inscripcion** | Gestión de registro e inventario | Puede ver y editar inscritos, grupos, iglesias, uniones, inventario |
| **lider** | Crear contenido | Puede crear actividades y noticias |
| **director** | Gestionar competencia | Puede crear actividades/noticias, gestionar puntos, ver ranking |
| **pastor** | Crear devocionales | Puede crear/ver devocionales, publicar en muro |
| **campamentista** | Acceso solo lectura | Puede ver muro, ranking, actividades, noticias, devocionales (sin editar) |

---

## 🔐 Decoradores de Permisos

### Decorador `@require_role(*roles)`

Protege una vista Django requiriendo que el usuario tenga uno de los roles especificados.

**Ubicación:** `principal/permisos.py`

**Uso:**
```python
@require_role('director', 'admin')
def agregar_puntos(request):
    # Solo directores y administradores pueden acceder
    pass

@require_role('inscripcion', 'admin')
def listar_inventario(request):
    # Solo personal de inscripción y administradores
    pass
```

**Características:**
- ✅ Los administradores siempre tienen acceso (bypass automático)
- ✅ Redirige a `/muro` si el usuario no tiene permiso
- ✅ Muestra mensaje de error: "No tienes permiso para acceder a esta página"
- ✅ Requiere autenticación (redirige a login si no autenticado)

---

## 📍 Vistas Protegidas por Rol

### 🔵 Admin Only
- `listar_usuarios` - Ver/editar todos los usuarios del campamento

### 🟣 Inscripción & Admin
- `lista_inscritos` - Registrar participantes y entregar kits
- `listar_inventario` - Gestionar inventario de poleras, credenciales, etc.
- `listar_grupos` - Crear y editar grupos
- `gestionar_iglesias_uniones` - Gestionar iglesias y uniones

### 🟡 Director & Admin
- `agregar_puntos` - Agregar puntos a grupos (competencia)
- `crear_actividad` - Crear nuevas actividades/cronograma
- `crear_noticia` - Publicar noticias

### 🟢 Lider & Director & Admin
- `crear_actividad` - Crear actividades en el cronograma
- `crear_noticia` - Crear y publicar noticias

### 🟣 Pastor & Admin
- `crear_devocional` - Crear devocionales/reflexiones

### 👥 Todos (Campamentista, Inscripción, Director, Admin, Lider, Pastor)
- `muro_social` - Ver/comentar en el muro social
- `listar_actividades` - Ver cronograma de actividades
- `listar_noticias` - Ver noticias del campamento
- `listar_devocionales` - Ver devocionales publicados
- `ranking_grupos` - Ver ranking de competencia

---

## 🎨 Menu Dinámico por Rol

El archivo `base.html` contiene un menú que se adapta automáticamente al rol del usuario:

### Visible para Todos
```html
<a href="{% url 'muro' %}">🎭 Muro</a>
<a href="{% url 'ranking' %}">🏆 Ranking</a>
<a href="{% url 'listar_actividades' %}">📅 Actividades</a>
<a href="{% url 'listar_noticias' %}">📰 Noticias</a>
<a href="{% url 'listar_devocionales' %}">📖 Devocionales</a>
```

### Visible para Lider, Director & Admin
```html
<a href="{% url 'crear_actividad' %}">➕ Crear Actividad</a>
<a href="{% url 'crear_noticia' %}">➕ Crear Noticia</a>
```

### Visible para Pastor & Admin
```html
<a href="{% url 'crear_devocional' %}">➕ Crear Devocional</a>
```

### Visible para Inscripción & Admin (Gestión - Emerald)
```html
<a href="{% url 'lista_inscritos' %}">👥 Inscritos</a>
<a href="{% url 'listar_grupos' %}">👫 Grupos</a>
<a href="{% url 'gestionar_iglesias_uniones' %}">🏘️ Iglesias/Uniones</a>
<a href="{% url 'listar_inventario' %}">📦 Inventario</a>
```

### Visible para Director & Admin (Competencia - Yellow)
```html
<a href="{% url 'agregar_puntos' %}">⭐ Puntos</a>
```

### Visible para Admin Only (Administración - Red)
```html
<a href="{% url 'listar_usuarios' %}">⚙️ Usuarios</a>
```

---

## 🔄 Flujo de Login

1. Usuario inicia sesión con su credencial
2. Sistema verifica credenciales en la base de datos
3. **Si es Admin:** Redirige a `/dashboard`
4. **Si NO es Admin:** Redirige a `/muro` (muro social)

**Archivo:** `principal/views.py` - `login_view()`

---

## 💾 Archivo de Permisos

**Ubicación:** `principal/permisos.py`

**Contiene:**
- `@require_role(*roles)` - Decorador principal
- `@admin_only` - Solo administradores
- `@director_or_admin` - Directores y administradores
- `@inscripcion_or_admin` - Personal de inscripción y administradores
- `@lider_or_higher` - Líderes, directores y administradores
- `@pastor_or_admin` - Pastores y administradores
- Funciones auxiliares para uso en plantillas (ej: `user_can_edit_actividades()`)
- `get_context_permisos(user)` - Diccionario de permisos para plantillas

---

## 🛡️ Protección de Vistas - Checklist

### ✅ Ya Protegidas

| Vista | Decorador | URL |
|-------|-----------|-----|
| `lista_inscritos` | `@require_role('inscripcion', 'admin')` | `/inscripcion/lista/` |
| `muro_social` | `@require_role(..., 'pastor')` | `/muro/` |
| `agregar_puntos` | `@require_role('director', 'admin')` | `/puntos/agregar/` |
| `listar_usuarios` | `@require_role('admin')` | `/usuarios/` |
| `listar_inventario` | `@require_role('inscripcion', 'admin')` | `/inventario/` |
| `listar_grupos` | `@require_role('inscripcion', 'admin')` | `/grupos/` |
| `listar_actividades` | `@require_role(..., 'pastor')` | `/actividades/` |
| `crear_actividad` | `@require_role('lider', 'director', 'admin')` | `/actividades/crear/` |
| `listar_noticias` | `@require_role(..., 'pastor')` | `/noticias/` |
| `crear_noticia` | `@require_role('lider', 'director', 'admin')` | `/noticias/crear/` |
| `gestionar_iglesias_uniones` | `@require_role('inscripcion', 'admin')` | `/gestion_iglesias_uniones/` |
| `listar_devocionales` | `@require_role(..., 'pastor')` | `/devocionales/` |
| `crear_devocional` | `@require_role('pastor', 'admin')` | `/devocionales/crear/` |

---

## 🧪 Pruebas de Acceso

Para probar los permisos, crea usuarios con cada rol y verifica:

```python
# En el shell de Django:
from principal.models import Usuario

# Crear usuarios de prueba
admin = Usuario.objects.create_user(
    username='admin_test',
    password='test123',
    rol='admin'
)

inscripcion = Usuario.objects.create_user(
    username='inscripcion_test',
    password='test123',
    rol='inscripcion'
)

lider = Usuario.objects.create_user(
    username='lider_test',
    password='test123',
    rol='lider'
)

director = Usuario.objects.create_user(
    username='director_test',
    password='test123',
    rol='director'
)

pastor = Usuario.objects.create_user(
    username='pastor_test',
    password='test123',
    rol='pastor'
)

campamentista = Usuario.objects.create_user(
    username='campamentista_test',
    password='test123',
    rol='campamentista'
)
```

Luego inicia sesión con cada usuario y verifica que:
1. El menú muestra solo las opciones correspondientes a su rol
2. Si intenta acceder directamente a una URL restringida, recibe el error

---

## 📝 Notas Importantes

1. **El decorador `@require_role` cubre ambas cosas:**
   - Protección en la lógica de negocio (backend)
   - El menú en `base.html` es solo una comodidad visual

2. **Los administradores siempre tienen acceso:**
   - El rol 'admin' es especial y puede acceder a todo
   - No necesita estar listado en cada `@require_role`

3. **Redirección inteligente:**
   - Admins van a `/dashboard` en login
   - Otros roles van a `/muro` en login

4. **Mensajes de error:**
   - Se muestra automáticamente si el usuario no tiene permiso
   - Estilo rojo con `messages.error()`

---

## 🔄 Modificar Permisos

Para cambiar los permisos de una vista:

1. Localiza la vista en `principal/views.py`
2. Modifica el decorador `@require_role` con los roles deseados
3. Ejemplos:
   ```python
   # Permitir solo directores
   @require_role('director', 'admin')
   def mi_vista(request):
       pass
   
   # Permitir múltiples roles
   @require_role('lider', 'director', 'admin')
   def otra_vista(request):
       pass
   
   # Permitir a todos los autenticados
   @require_role('campamentista', 'inscripcion', 'director', 'admin', 'lider', 'pastor')
   def vista_publica(request):
       pass
   ```

4. Guarda y reinicia el servidor Django

---

## 📞 Soporte

Para agregar nuevas restricciones de permisos:

1. **Usa el decorador existente:** `@require_role('rol1', 'rol2')`
2. **No crees nuevos decoradores** a menos que sea absolutamente necesario
3. **Documentación:** Actualiza este archivo si cambias permisos

---

**Última actualización:** {% now "d/m/Y H:i" %}
**Mantenido por:** Sistema RBAC Campamento 026
