Skip to main content

Freedec: Secure Document & Password Recovery Service

Python Django DRF Security OWASP License: GPL v3

🇪🇸 Leer en Español (Guía Completa para Principiantes)   |   🇬🇧 Read in English (Complete Beginner-Friendly Guide)


🇪🇸 Español: Guía Completa de la Aplicación Freedec

Bienvenido a la documentación oficial de Freedec.


📑 Índice de Contenidos (Español)

  1. ¿Qué es Freedec y qué problema resuelve?
  2. Requisitos Previos del Sistema
  3. Entorno de Pruebas Rápido (Staging Sandbox sin tocar tu proyecto)
  4. Las 4 Opciones de Instalación en un Proyecto Existente
  5. Guía Paso a Paso de Integración (Línea por Línea)
  6. Cómo Funciona y Cómo se Usa la Web GUI (Navegador)
  7. Endpoints de la API REST (para Desarrolladores y cURL)
  8. Configuración de MEDIA en Producción (Nginx y Apache)
  9. Resolución de Problemas Frecuentes (FAQ / Troubleshooting)

1. ¿Qué es Freedec y qué problema resuelve?

Imagina que necesitas compartir un documento altamente confidencial (un contrato, una auditoría, unas credenciales maestras) con una lista específica de personas. Si envías el archivo y la contraseña por el mismo canal (por ejemplo, en el mismo correo o chat), cualquier persona que intercepte la comunicación tendrá acceso total.

Freedec resuelve esto mediante una arquitectura descentralizada de conocimiento cero (Zero-Knowledge) y verificación multi-factor:

  1. El Administrador sube el documento:
    • El sistema calcula la huella digital exacta del archivo (hash SHA-256). No se usan IDs secuenciales (como documento/1), lo que impide que atacantes adivinen URLs (anti-IDOR).
    • El archivo se cifra inmediatamente con AES-128-CBC + HMAC-SHA256 (Fernet) y se guarda protegido en disco.
    • Se genera un Código Secreto de Acceso (access_code) de 256 bits. El administrador recibe este código una sola vez para entregarlo en mano o por chat seguro (Signal/SMS). En la base de datos se guarda hasheado con PBKDF2 (incluso si roban la base de datos, nadie puede ver el código).
  2. El Destinatario recupera la clave:
    • El usuario sube su copia del documento a la web de Freedec.
    • Introduce el access_code y su correo electrónico.
    • El sistema calcula el hash en tiempo real, verifica que posea el archivo original, comprueba el código y confirma que su correo esté en la lista blanca autorizada.
    • La clave NUNCA se muestra en pantalla: se envía de forma automatizada y exclusiva al buzón del correo verificado.

2. Requisitos Previos del Sistema

Antes de empezar, comprueba que tienes instaladas estas herramientas en tu ordenador o servidor:

  • Python 3.11 o 3.12: Comprueba con:
    python3 --version
    
  • Poetry (Gestor moderno de dependencias en Python): Comprueba con:
    poetry --version
    
    Si no tienes Poetry instalado, instálalo en Linux/macOS con:
    curl -sSL https://install.python-poetry.org | python3 -
    

3. Entorno de Pruebas Rápido (Staging Sandbox)

El repositorio incluye un servidor de prueba autónomo preconfigurado. No necesitas tener ningún proyecto Django previo para probarlo.

Paso 1: Clonar e Instalar Dependencias

git clone https://github.com/jrubioh1/Freedec.git
cd Freedec
poetry install

Paso 2: Inicializar la Base de Datos de Prueba

Ejecuta el comando automatizado:

poetry run python manage.py setup_staging

Creará una base de datos SQLite local (db_staging.sqlite3), creará el usuario administrador admin con contraseña admin123 y generará un archivo de prueba legítimo sample_document.pdf.

Paso 3: Arrancar el Servidor

poetry run python manage.py runserver 8000

Paso 4: Probar la Interfaz Gráfica en tu Navegador

Paso 5: Probar el Flujo Automatizado por CLI (Opcional)

En otra terminal distinta, ejecuta:

poetry run python scripts/demo_flow.py

4. Las 4 Opciones de Instalación en un Proyecto Existente

Si ya tienes un proyecto Django funcionando, puedes incorporar freedec de cualquiera de estas 4 maneras:

Opción 1: Copiar la carpeta freedec/ a tu proyecto (La más sencilla y directa)

  • ¿Qué se copia?: ÚNICAMENTE la carpeta freedec/.
  • ¿Qué NO se copia?: NO copies config/ ni manage.py (tu proyecto ya tiene los suyos propios).
  • Comando para instalar dependencias: En la carpeta de tu proyecto existente:
    poetry add cryptography djangorestframework
    

Comparativa visual de directorios:

Tu Proyecto ANTES de copiar:             Tu Proyecto DESPUÉS de copiar:
----------------------------             ------------------------------
mi_proyecto/                             mi_proyecto/
├── manage.py                            ├── manage.py
├── mi_config/                           ├── mi_config/
│   ├── settings.py                      │   ├── settings.py  <-- Añadir 4 líneas
│   ├── urls.py                          │   ├── urls.py      <-- Añadir 1 línea
│   └── wsgi.py                          │   └── wsgi.py
                                         └── freedec/         <-- ¡Solo pegas esto!
                                             ├── models.py
                                             ├── views.py
                                             ├── templates/
                                             └── ...

Opción 2: Como dependencia Git con Poetry (Ideal para repositorios en equipo)

Si Freedec está en un repositorio Git remoto (GitHub, GitLab):

poetry add git+https://github.com/jrubioh1/Freedec.git

Poetry clonará y gestionará las actualizaciones de Freedec como cualquier paquete estándar.


Opción 3: Enlace local editable con Poetry (Monorepos o Desarrollo Activo)

Si tienes el repositorio de Freedec descargado en tu misma máquina:

poetry add --editable /ruta/absoluta/a/Freedec

Cualquier cambio que hagas en el código de Freedec se reflejará al instante en tu proyecto principal.


Opción 4: Como paquete de PyPI o Registro Privado

Si compilas y publicas Freedec:

# En el repositorio Freedec:
poetry build
poetry publish

# En tu proyecto principal:
poetry add freedec

5. Guía Paso a Paso de Integración (Línea por Línea)

Sigue estos 6 pasos numerados en tu proyecto Django existente:

Paso 1: Generar la Clave Criptográfica Maestra

Abre tu terminal y ejecuta:

python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Obtendrás una cadena de 44 caracteres base64 similar a: 2bXoO5W3uK_mZ6k9wE2qR7vA1yT8pI0uL4mN6jH3gD1=


Paso 2: Editar tu archivo settings.py

Abre el archivo settings.py de tu proyecto y añade lo siguiente:

import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

# 1. Añadir 'rest_framework' y 'freedec.apps.FreedecConfig' a INSTALLED_APPS
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Aplicaciones requeridas:
    'rest_framework',
    'freedec.apps.FreedecConfig',
]

# 2. Configurar la clave maestra que generaste en el Paso 1
# (En producción se recomienda inyectarla desde os.environ)
FREEDEC_FERNET_KEY = os.environ.get(
    "FREEDEC_FERNET_KEY",
    "Pega_Aqui_La_Clave_Generada_En_El_Paso_1=="
)

# 3. Tamaño máximo de archivo permitido (50 MB por defecto)
FREEDEC_MAX_FILE_SIZE = 50 * 1024 * 1024

# 4. Configurar las rutas de archivos MEDIA (si no las tenías)
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

# 5. Configurar el correo (Usa tu SMTP habitual en producción)
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
DEFAULT_FROM_EMAIL = 'no-reply@tudominio.com'

# 6. Throttling de seguridad en DRF (protege el endpoint público)
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle'],
    'DEFAULT_THROTTLE_RATES': {'anon': '5/minute'},
}

Paso 3: Editar tu archivo urls.py principal

Abre el archivo urls.py de la carpeta de configuración de tu proyecto y añade el include:

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    
    # Acoplar las rutas de Freedec (GUI y API REST)
    path('freedec/', include('freedec.urls', namespace='freedec')),
]

# Servir archivos multimedia únicamente durante desarrollo local:
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Paso 4: Ejecutar las Migraciones

Ejecuta en tu terminal para crear las tablas en tu base de datos:

poetry run python manage.py makemigrations freedec
poetry run python manage.py migrate

Paso 5: Crear un Superusuario Administrador (si no tienes uno)

poetry run python manage.py createsuperuser

Introduce un nombre de usuario, correo y contraseña.


Paso 6: Iniciar tu Servidor

poetry run python manage.py runserver

¡Listo! Ya tienes tanto la interfaz web como la API REST plenamente operativas en tu proyecto.


6. Cómo Funciona y Cómo se Usa la Web GUI

Una vez acoplado, tendrás los portales web accesibles desde cualquier navegador:

A. Panel de Administración (Django Admin - http://localhost:8000/admin/)

  1. Inicia sesión con tu cuenta de administrador en /admin/ (o la ruta de admin de tu proyecto).
  2. Entra al menú Documentos Cifrados -> Añadir Documento Cifrado.
  3. Selecciona tu documento en formato permitido (PDF, LibreOffice .odt/.ods o Microsoft Office .docx/.xlsx).
  4. Opcionalmente escribe una contraseña personalizada o déjalo vacío para que el sistema genere una automáticamente con alta entropía criptográfica (24 caracteres).
  5. Escribe las direcciones de correo autorizadas (usa el botón ➕ Añadir otro correo para agregar destinatarios de forma interactiva).
  6. Pulsa Guardar.
  7. Resultado:
    • Descarga Automática de Recibo de Credenciales: El navegador descargará al instante un archivo de texto <nombre_original>_credenciales.txt con el hash SHA-256, código secreto de acceso, contraseña y enlaces directos, para que el administrador pueda guardarlo de forma local sin que quede expuesto en claro en el servidor.
    • La pantalla mostrará el Código Secreto de Acceso (access_code) con botón de copiado rápido y la Contraseña Asignada.
    • Un botón para descargar el archivo cifrado <nombre_original>.enc.

B. Portal Público de Solicitud de Contraseña (http://localhost:8000/freedec/)

  1. El usuario final o destinatario entra a http://localhost:8000/freedec/.
  2. Sube su copia del documento (bien el archivo original o el archivo .enc que le facilitaron).
  3. Pega el código de acceso facilitado por el emisor.
  4. Escribe su correo electrónico registrado en la lista de autorización.
  5. Pulsa Solicitar Contraseña.
  6. Resultado: La web mostrará un mensaje de confirmación neutro (anti-enumeración de usuarios). Si los datos son legítimos y el correo está autorizado:
    • El sistema enviará de inmediato la contraseña al correo del destinatario, especificando explícitamente el nombre del documento al que corresponde la clave y un enlace directo a la pestaña de descifrado.
    • El sistema registra el acceso en la tabla de auditoría (DocumentAccessLog), actualizando el contador access_count, la fecha de último acceso y la IP del solicitante.

C. Portal Público de Descifrado de Archivos .enc (http://localhost:8000/freedec/descifrar/)

¿Cómo se pasa del archivo .enc al documento original descifrado?

  1. El usuario abre http://localhost:8000/freedec/descifrar/ (o pulsa 🔓 Descifrar Archivo (.enc) en la barra de navegación).
  2. Sube el archivo .enc.
  3. Pega la contraseña que acaba de recibir en su correo electrónico.
  4. Pulsa Descifrar y Descargar Archivo Original.
  5. Resultado: El sistema valida la contraseña en memoria, descifra el contenedor con AES-128/Fernet y descarga inmediatamente el archivo original con su nombre y extensión correcta (documento.pdf, contrato.docx, etc.).

D. Eliminación de Documentos y Borrado Físico en Disco (Derecho al Olvido / GDPR)

Al eliminar un documento registrado:

  • Señal post_delete automática: Al borrar un documento desde el panel de Django Admin o el ORM, se elimina automáticamente su archivo físico .enc asociado en disco para evitar archivos confidenciales huérfanos.
  • Botón directo en Django Admin: La tabla de documentos en /admin/freedec/encrypteddocument/ dispone de un botón directo 🗑️ Eliminar por cada fila.
  • Comando CLI de borrado:
    # Listar documentos existentes
    poetry run python manage.py delete_document --list
    
    # Eliminar un documento específico por nombre o hash
    poetry run python manage.py delete_document balance_anual.pdf
    
    # Eliminar todos los registros y archivos físicos (.enc)
    poetry run python manage.py delete_document --all
    

E. Compatibilidad con Despliegues en Apache (Múltiples Apps en el Mismo Dominio)

Freedec está diseñado específicamente para convivir con otras aplicaciones en el mismo servidor Apache:

  • Espacio de nombres aislado: Todas las rutas cuelgan de /freedec/ (ej. http://dominio.com/freedec/), sin invadir la raíz / ni rutas genéricas.
  • Resolución dinámica con SCRIPT_NAME: En las plantillas HTML se usa {% url 'freedec:gui-public-request' %} y {% url 'freedec:gui-public-decrypt' %}, adaptándose automáticamente a subcarpetas como WSGIScriptAlias /freedec o ProxyPass.
  • Admin Desacoplado: Los recibos y enlaces al panel de administración se resuelven dinámicamente mediante reverse('admin:index'), respetando la URL exacta que tu proyecto tenga configurada para Django Admin.

F. Descifrado por Terminal (Línea de Comandos CLI)

Para administradores, scripts o usuarios avanzados:

poetry run python manage.py decrypt_document ruta/al/archivo.enc --password "TuContraseña" --output documento_recuperado.pdf

7. Endpoints de la API REST

Si deseas integrar Freedec con un frontend en React, Vue, Angular o una app móvil, utiliza los endpoints REST:

1. Subida Administrativa (POST /freedec/api/admin/upload/)

  • Headers: Authorization: Bearer <TOKEN> o sesión activa.
  • Form-Data:
    • original_file: Archivo binario.
    • plain_password: Contraseña.
    • allowed_emails: ["auditor@empresa.com"].
curl -X POST http://127.0.0.1:8000/freedec/api/admin/upload/ \
  -u admin:admin123 \
  -F "original_file=@documento.pdf" \
  -F "plain_password=ClaveSecreta#2026!" \
  -F 'allowed_emails=["auditor@empresa.com"]'

2. Recuperación Pública (POST /freedec/api/public/request-password/)

  • Headers: Sin autenticación previa requerida (Público).
  • Form-Data:
    • file: Archivo binario en posesión del usuario.
    • access_code: Código secreto.
    • email: Correo del usuario.
curl -X POST http://127.0.0.1:8000/freedec/api/public/request-password/ \
  -F "file=@documento.pdf" \
  -F "access_code=CODIGO_DE_ACCESO" \
  -F "email=auditor@empresa.com"

8. Configuración de MEDIA en Producción (Nginx y Apache)

Opción A: Configuración en Nginx

Añade este bloque en tu archivo /etc/nginx/sites-available/tudominio:

server {
    listen 443 ssl http2;
    server_name tudominio.com;

    # Servir la carpeta MEDIA directamente desde el disco:
    location /media/ {
        alias /var/www/tu_proyecto/media/;
        autoindex off;                          # Desactiva listado de archivos
        add_header X-Content-Type-Options "nosniff";
        default_type application/octet-stream;  # Fuerza descarga segura
        location ~* \.(php|py|sh|pl|cgi|exe)$ { deny all; } # Bloquea scripts
    }

    # Resto de la aplicación Django (Gunicorn):
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Opción B: Configuración en Apache (httpd con mod_wsgi)

Añade estas líneas dentro de tu VirtualHost (/etc/apache2/sites-available/default-ssl.conf):

<VirtualHost *:443>
    ServerName tudominio.com

    # 1. Alias para servir la carpeta /media/ desde el disco
    Alias /media/ /var/www/tu_proyecto/media/

    <Directory /var/www/tu_proyecto/media>
        Options -Indexes -FollowSymLinks
        AllowOverride None
        Require all granted
        <IfModule mod_headers.c>
            Header always set X-Content-Type-Options "nosniff"
        </IfModule>
        <FilesMatch "\.(php|py|sh|pl|cgi|exe)$">
            Require all denied
        </FilesMatch>
        ForceType application/octet-stream
    </Directory>

    # 2. Conexión con Django vía mod_wsgi
    WSGIDaemonProcess tu_proyecto python-home=/var/www/tu_proyecto/.venv python-path=/var/www/tu_proyecto
    WSGIProcessGroup tu_proyecto
    WSGIScriptAlias / /var/www/tu_proyecto/config/wsgi.py
</VirtualHost>

9. Resolución de Problemas Frecuentes (FAQ)

¿Error: ImproperlyConfigured: Falta la configuración FREEDEC_FERNET_KEY?

  • Causa: No has definido la clave maestra en tu settings.py.
  • Solución: Genera una con python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" y colócala en settings.py.

¿Error 404 al intentar descargar el archivo cifrado .enc?

  • Causa en desarrollo: Falta la línea urlpatterns += static(settings.MEDIA_URL, ...) en tu urls.py.
  • Causa en producción: No has configurado el alias /media/ en tu servidor Nginx o Apache.

¿No llega el correo con la contraseña al destinatario?

  • Causa en desarrollo / sandbox por defecto: Tienes EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'. La contraseña se imprime en la terminal donde corre Django, no se envía por internet.
  • Solución: Configura tu servidor SMTP en un archivo .env en la raíz (copiando .env.example). Dispones de plantillas para Gmail, Brevo, Outlook, etc. Puedes comprobar tu conexión SMTP al instante ejecutando:
    poetry run python manage.py test_smtp tu-correo@gmail.com
    

¿Qué sucede cuando elimino un registro de documento cifrado?

  • Eliminación física garantizada: Gracias al receptor de señales post_delete, cuando se elimina un registro (sea individualmente desde el Admin, por lotes o mediante QuerySet.delete()), el archivo físico .enc asociado en disco (media_staging/encrypted_docs/) se destruye automáticamente del sistema de archivos, garantizando el cumplimiento de borrado seguro y GDPR.

¿Error: Tipo de archivo no permitido?

  • Causa: Solo se admiten archivos PDF, LibreOffice (.odt, .ods, .odp, .odg) y MS Office (.docx, .xlsx, .pptx, .doc, .xls, .ppt). No se permiten archivos de texto plano .txt, ejecutables .exe ni scripts .sh.


🇬🇧 English: Complete Guide for Freedec Application

Welcome to the official documentation for Freedec.


📑 Table of Contents (English)

  1. What is Freedec and what problem does it solve?
  2. System Prerequisites
  3. Quick Test Sandbox (Staging mode without touching your project)
  4. The 4 Installation Options into an Existing Project
  5. Step-by-Step Integration Checklist (Line by Line)
  6. How the Web GUI Works and How to Use It
  7. REST API Endpoints (for Developers and cURL)
  8. Production MEDIA Configuration (Nginx & Apache)
  9. Frequently Asked Questions (FAQ / Troubleshooting)

1. What is Freedec and what problem does it solve?

Imagine you need to share a highly confidential document (a contract, an audit, master database credentials) with a specific list of recipients. If you send both the file and the password over the same channel (e.g. in the same email or chat), any attacker who intercepts the communication gains full access.

Freedec solves this through a decentralized Zero-Knowledge architecture and multi-factor verification:

  1. The Administrator uploads the document:
    • The system computes the exact digital fingerprint of the file (SHA-256 hash). No sequential IDs (like document/1) are used, completely preventing Insecure Direct Object References (anti-IDOR).
    • The file is encrypted immediately using AES-128-CBC + HMAC-SHA256 (Fernet) and securely saved to disk.
    • A 256-bit Secret Access Code (access_code) is generated. The administrator receives this code once to hand over in person or via secure channel (Signal/SMS). In the database, it is stored hashed with PBKDF2 (even if attackers dump the database, they cannot view the code).
  2. The Recipient retrieves the password:
    • The user uploads their copy of the document to the Freedec web portal.
    • Enters the access_code and their email address.
    • The system calculates the SHA-256 hash in real time, verifies possession of the exact file, checks the access code, and confirms their email is whitelisted.
    • The password is NEVER shown on the screen: it is dispatched automatically and exclusively to the inbox of the verified email address.

2. System Prerequisites

Verify that your system has the following tools installed:

  • Python 3.11 or 3.12: Check with:
    python3 --version
    
  • Poetry (Modern Python dependency manager): Check with:
    poetry --version
    
    If not installed, install it on Linux/macOS using:
    curl -sSL https://install.python-poetry.org | python3 -
    

3. Quick Test Sandbox (Staging Mode)

The repository provides a standalone preconfigured test server. You do not need an existing Django project to evaluate it.

Step 1: Clone and Install Dependencies

git clone https://github.com/jrubioh1/Freedec.git
cd Freedec
poetry install

Step 2: Initialize Test Database

Run the automated command:

poetry run python manage.py setup_staging

Creates a local SQLite database (db_staging.sqlite3), creates the superuser admin with password admin123, and generates a valid sample file sample_document.pdf.

Step 3: Start the Server

poetry run python manage.py runserver 8000

Step 4: Open the Web GUI in Your Browser

Step 5: Run Automated CLI Demo (Optional)

In another terminal:

poetry run python scripts/demo_flow.py

4. The 4 Installation Options into an Existing Project

If you already have an existing Django project, you can integrate freedec in any of these 4 ways:

Option 1: Copy the freedec/ Folder (Simplest & Most Direct)

  • What to copy?: ONLY the freedec/ folder.
  • What NOT to copy?: DO NOT copy config/ or root manage.py (your project already has its own).
  • Command to install requirements: In your host project directory:
    poetry add cryptography djangorestframework
    

Visual Directory Comparison:

Your Project BEFORE copying:             Your Project AFTER copying:
----------------------------             ---------------------------
my_project/                              my_project/
├── manage.py                            ├── manage.py
├── my_config/                           ├── my_config/
│   ├── settings.py                      │   ├── settings.py  <-- Add 4 lines
│   ├── urls.py                          │   ├── urls.py      <-- Add 1 line
│   └── wsgi.py                          │   └── wsgi.py
                                         └── freedec/         <-- Only copy this!
                                             ├── models.py
                                             ├── views.py
                                             ├── templates/
                                             └── ...

Option 2: As a Direct Git Dependency via Poetry (Best for Teams)

poetry add git+https://github.com/jrubioh1/Freedec.git

Option 3: Local Editable Path via Poetry (Monorepos & Active Development)

poetry add --editable /absolute/path/to/Freedec

Option 4: Via PyPI or Private Package Registry

# In Freedec repository:
poetry build
poetry publish

# In your host project:
poetry add freedec

5. Step-by-Step Integration Checklist (Line by Line)

Follow these 6 numbered steps in your existing Django project:

Step 1: Generate Master Fernet Key

In your terminal:

python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Step 2: Edit Your settings.py File

import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

# 1. Add 'rest_framework' and 'freedec.apps.FreedecConfig'
INSTALLED_APPS = [
    # Existing apps...
    'rest_framework',
    'freedec.apps.FreedecConfig',
]

# 2. Configure master key generated in Step 1
FREEDEC_FERNET_KEY = os.environ.get("FREEDEC_FERNET_KEY", "YOUR_KEY_HERE==")

# 3. Maximum file size (default: 50 MB)
FREEDEC_MAX_FILE_SIZE = 50 * 1024 * 1024

# 4. MEDIA settings
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

# 5. Email settings
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
DEFAULT_FROM_EMAIL = 'no-reply@yourdomain.com'

# 6. DRF Rate Limiting
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle'],
    'DEFAULT_THROTTLE_RATES': {'anon': '5/minute'},
}

Step 3: Edit Your Main urls.py File

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('freedec/', include('freedec.urls', namespace='freedec')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Step 4: Run Database Migrations

poetry run python manage.py makemigrations freedec
poetry run python manage.py migrate

Step 5: Create Superuser (if needed)

poetry run python manage.py createsuperuser

Step 6: Start Your Server

poetry run python manage.py runserver

6. How the Web GUI Works and How to Use It

A. Admin Panel (Django Admin - http://localhost:8000/admin/)

  1. Log in at /admin/ (or your project's configured Django admin URL) with an administrator account.
  2. Navigate to Encrypted Documents -> Add Encrypted Document.
  3. Select your document in an authorized format (PDF, LibreOffice .odt/.ods, or MS Office .docx/.xlsx).
  4. Optionally enter a custom decryption password, or leave it blank to automatically generate a cryptographically strong 24-character password.
  5. Enter authorized recipient emails (interactive ➕ Add another email button available).
  6. Click Save.
  7. Result:
    • Automatic Credentials Receipt Download: The browser immediately downloads <original_filename>_credenciales.txt containing the SHA-256 hash, secret access code, assigned password, authorized emails, and direct access links, allowing local storage without server plaintext persistence.
    • The screen displays the secret Access Code (access_code) with quick-copy button and the Assigned Password.
    • A direct download button for the encrypted file <original_filename>.enc.

B. Public Password Request Portal (http://localhost:8000/freedec/)

  1. The user navigates to http://localhost:8000/freedec/.
  2. Uploads their file copy (either the original file or the .enc encrypted container).
  3. Pastes the secret access code provided by the issuer.
  4. Enters their authorized email address.
  5. Clicks Request Password.
  6. Result: A uniform, neutral confirmation message is displayed (preventing user or document enumeration). If the data matches and the email is authorized:
    • The system immediately emails the password to the recipient, explicitly citing the document name and a direct link to the decryption portal.
    • The access event is recorded in the DocumentAccessLog audit table, incrementing access_count and recording the last access timestamp and client IP.

C. Public Document Decryption Portal (http://localhost:8000/freedec/descifrar/)

How to turn the .enc file back into the original document?

  1. The user navigates to http://localhost:8000/freedec/descifrar/ (or clicks 🔓 Descifrar Archivo (.enc) in the navbar).
  2. Uploads the .enc file.
  3. Pastes the password received in their email.
  4. Clicks Descifrar y Descargar Archivo Original.
  5. Result: The system decrypts the container in memory with Fernet and triggers an instant download of the original file with its exact name and extension (document.pdf, contract.docx, etc.).

D. Document Deletion & Physical Disk Erasure (Right to Erasure / GDPR)

When deleting a registered document:

  • Automated post_delete Signal: Deleting a record via Django Admin or ORM triggers automatic unlinking and physical deletion of the .enc file in MEDIA_ROOT.
  • Direct Admin Button: The document table at /admin/freedec/encrypteddocument/ provides an inline 🗑️ Eliminar button on each row.
  • CLI Management Command:
    # List existing documents
    poetry run python manage.py delete_document --list
    
    # Delete a specific document by name or hash
    poetry run python manage.py delete_document balance_anual.pdf
    
    # Delete all database records and physical (.enc) files
    poetry run python manage.py delete_document --all
    

E. Apache Deployment & Multi-App Compatibility (Same Domain)

Freedec is engineered to run seamlessly alongside other applications on the same Apache server:

  • Isolated Namespace: All routes reside under /freedec/ (e.g. http://domain.com/freedec/), avoiding conflicts with the root domain / or other apps.
  • Dynamic Resolution with SCRIPT_NAME: HTML templates use {% url 'freedec:gui-public-request' %} and {% url 'freedec:gui-public-decrypt' %}, adapting dynamically to subfolders (WSGIScriptAlias /freedec or ProxyPass).
  • Decoupled Admin Integration: Receipts and links to Django admin dynamically use reverse('admin:index'), respecting whatever admin URL the host project defines.

F. Command Line Decryption (CLI)

For system administrators, automated pipelines, or offline recovery:

poetry run python manage.py decrypt_document path/to/file.enc --password "YourPassword" --output recovered_document.pdf

7. REST API Endpoints

1. Admin Upload (POST /freedec/api/admin/upload/)

curl -X POST http://127.0.0.1:8000/freedec/api/admin/upload/ \
  -u admin:admin123 \
  -F "original_file=@document.pdf" \
  -F "plain_password=SecretPassword#2026!" \
  -F 'allowed_emails=["auditor@corp.com"]'

2. Public Password Request (POST /freedec/api/public/request-password/)

curl -X POST http://127.0.0.1:8000/freedec/api/public/request-password/ \
  -F "file=@document.pdf" \
  -F "access_code=SECRET_ACCESS_CODE" \
  -F "email=auditor@corp.com"

8. Production MEDIA Configuration (Nginx & Apache)

Option A: Nginx Configuration

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    location /media/ {
        alias /var/www/your_project/media/;
        autoindex off;
        add_header X-Content-Type-Options "nosniff";
        default_type application/octet-stream;
        location ~* \.(php|py|sh|pl|cgi|exe)$ { deny all; }
    }

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Option B: Apache Configuration (httpd / mod_wsgi)

<VirtualHost *:443>
    ServerName yourdomain.com

    Alias /media/ /var/www/your_project/media/

    <Directory /var/www/your_project/media>
        Options -Indexes -FollowSymLinks
        AllowOverride None
        Require all granted
        <IfModule mod_headers.c>
            Header always set X-Content-Type-Options "nosniff"
        </IfModule>
        <FilesMatch "\.(php|py|sh|pl|cgi|exe)$">
            Require all denied
        </FilesMatch>
        ForceType application/octet-stream
    </Directory>

    WSGIDaemonProcess your_project python-home=/var/www/your_project/.venv python-path=/var/www/your_project
    WSGIProcessGroup your_project
    WSGIScriptAlias / /var/www/your_project/config/wsgi.py
</VirtualHost>

9. Frequently Asked Questions (FAQ / Troubleshooting)

Error: ImproperlyConfigured: Falta la configuración FREEDEC_FERNET_KEY?

  • Cause: Master key is missing in settings.py.
  • Fix: Generate one via python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" and set it in settings.py.

404 Error downloading encrypted .enc file?

  • In development: Missing urlpatterns += static(settings.MEDIA_URL, ...) in urls.py.
  • In production: Missing /media/ alias in your Nginx or Apache configuration.

Password email not received?

  • In default development / staging: You have EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'. Passwords print to the console terminal running Django.
  • Fix: Configure real SMTP credentials in a .env file (copying .env.example). You can test your SMTP delivery immediately with:
    poetry run python manage.py test_smtp your-email@gmail.com
    

What happens when an encrypted document record is deleted?

  • Guaranteed Physical File Deletion: A post_delete signal listener guarantees that whenever an EncryptedDocument record is deleted (from Django Admin single view, bulk actions, or ORM QuerySet.delete()), the underlying physical .enc file in media_staging/encrypted_docs/ is immediately removed from disk for strict GDPR and privacy compliance.

Error: Tipo de archivo no permitido?

  • Cause: Only PDF, LibreOffice (.odt, .ods, .odp, .odg), and MS Office (.docx, .xlsx, .pptx, .doc, .xls, .ppt) documents are allowed. Plain .txt, executables .exe, and scripts .sh are rejected.

Release files for freedec 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for freedec 1.0.0
File Size Uploaded
freedec-1.0.0.tar.gz 88.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for freedec 1.0.0
File Interpreter ABI Platform
freedec-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 186.5 kB

Release files / freedec-1.0.0.tar.gz

Download URL freedec-1.0.0.tar.gz
Size 88.2 kB
Tags Source
SHA-256 checksum
How to use checksums
bb4994f66f6ec29ef97c1e4d4f43d6a3aef514c55462fc0c771e010527794eca
BLAKE2b-256 checksum
How to use checksums
feccc50af92af5701b14a344ae3044749f95226ba11e45540f2e016e45038199
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.3 CPython/3.14.7 Linux/7.2.6-gentoo-dist-hardened

Release files / freedec-1.0.0-py3-none-any.whl

Download URL freedec-1.0.0-py3-none-any.whl
Size 98.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
60deb91c42284e9e0f613dacd77875812c0a6e45cb2ca11c1a0c027d6365062a
BLAKE2b-256 checksum
How to use checksums
b49d2c9151dec3d2018ae138bf7650d60687628047bcf32d868ba8e9ac5149a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.3 CPython/3.14.7 Linux/7.2.6-gentoo-dist-hardened

Release history Release notifications | RSS feed

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page