From d6feeee8935b09f68955400d7c8a084e4672c565 Mon Sep 17 00:00:00 2001 From: daniel Date: Fri, 20 Mar 2026 09:17:01 +0100 Subject: [PATCH] Add Nginx configuration, update MEDIA_ROOT path, and enhance email confirmation task --- nginx.conf | 68 ++++++++++++++++++++++++++++++++++++++++++++ proyecto/settings.py | 15 +++++++++- tienda/tasks.py | 20 +++++++++++-- tienda/views.py | 15 ++-------- 4 files changed, 101 insertions(+), 17 deletions(-) create mode 100644 nginx.conf diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..a2a3e58 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,68 @@ +worker_processes auto; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + client_max_body_size 25M; + + upstream django_gunicorn { + # Usa el nombre del servicio del contenedor Django/Gunicorn en tu red Docker. + # Si en docker-compose el servicio se llama distinto, cámbialo aquí. + server django:8000; + } + + server { + listen 80; + server_name _; + + # Archivos estáticos generados por collectstatic. + location /static/ { + alias /static/; + expires 30d; + add_header Cache-Control "public, max-age=2592000, immutable"; + access_log off; + } + + # Archivos subidos por usuarios. + location /media/ { + alias /media/; + expires 7d; + add_header Cache-Control "public, max-age=604800"; + access_log off; + } + + location / { + proxy_pass http://django_gunicorn; + proxy_http_version 1.1; + + 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; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + + proxy_redirect off; + proxy_read_timeout 300; + } + } +} diff --git a/proyecto/settings.py b/proyecto/settings.py index fd4b544..ad41d73 100644 --- a/proyecto/settings.py +++ b/proyecto/settings.py @@ -212,7 +212,7 @@ if SASS_BINARY: # Media files (User uploads) MEDIA_URL = 'media/' -MEDIA_ROOT = BASE_DIR / 'tienda' / 'static' / 'media' +MEDIA_ROOT = Path(os.getenv('MEDIA_ROOT', '/app/media')) # Redis Configuration CACHES = { @@ -271,6 +271,19 @@ AUTH_USER_MODEL = 'tienda.User' DOMAIN = os.getenv("DOMAIN", "localhost") PROTOCOL = os.getenv("PROTOCOL", "http") +default_csrf_trusted_origins = [] +if DOMAIN: + default_csrf_trusted_origins.append(f"{PROTOCOL}://{DOMAIN}") + +for host in ALLOWED_HOSTS: + if host and host != '*': + default_csrf_trusted_origins.append(f"{PROTOCOL}://{host}") + +CSRF_TRUSTED_ORIGINS = env_list( + 'CSRF_TRUSTED_ORIGINS', + list(dict.fromkeys(default_csrf_trusted_origins)), +) + LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO').upper() LOG_DIR = Path(os.getenv('LOG_DIR', BASE_DIR / 'logs')) diff --git a/tienda/tasks.py b/tienda/tasks.py index 5a7de53..5e32e71 100644 --- a/tienda/tasks.py +++ b/tienda/tasks.py @@ -1,7 +1,21 @@ from celery import shared_task +from django.conf import settings from .utilities import send_email -from .vars import login_message +from .vars import login_message, verify_message +import random, string + +from .models import User, VerificationCode +@shared_task +def enviar_correo_bienvenida(email_usuario: str, nombre_usuario: str): + send_email(email_usuario, "Inicio de Sesión correcto", login_message.format(name = nombre_usuario)) @shared_task -def enviar_correo_bienvenida(email_usuario, nombre_usuario): - send_email(email_usuario, "Inicio de Sesión correcto", login_message.format(name = nombre_usuario)) \ No newline at end of file +def enviar_correo_confirmacion(usuario: User): + code = VerificationCode.objects.create( + user = usuario, + code_mode = VerificationCode.VerificationModes.VERIFY_ACCOUNT, + code = ''.join(random.choices(string.digits, k=12)) + ) + + message = verify_message.format(name = usuario.get_full_name(), protocol = settings.PROTOCOL, domain = settings.DOMAIN, code = code.code) + email_result = send_email(usuario.email, "Verificación de cuenta", message) \ No newline at end of file diff --git a/tienda/views.py b/tienda/views.py index ba257d4..877511a 100644 --- a/tienda/views.py +++ b/tienda/views.py @@ -5,16 +5,13 @@ from django.contrib.auth import authenticate, login as auth_login, logout as aut from django.contrib.auth.decorators import login_required from django.contrib import messages from .models import User, Product, Category, Cart, CartItem, Image, Order, OrderItem, OrderMessage, ShippingAddress, VerificationCode -from .utilities import send_email from . import tasks from .vars import ( PAGE_SIZE, VAT_RATE, SHIPPING_COUNTRY, ALMERIA_POSTAL_CODE_PREFIX, - ALMERIA_MUNICIPALITIES_DISPLAY, - verify_message, - login_message + ALMERIA_MUNICIPALITIES_DISPLAY ) from django.conf import settings from django.views.decorators.csrf import csrf_exempt @@ -239,16 +236,8 @@ def register(request: HttpRequest): client_ip, ) - ver_code = ''.join(random.choices(string.digits, k=12)) - codigo = VerificationCode.objects.create( - user = user, - code = ver_code, - code_mode = VerificationCode.VerificationModes.VERIFY_ACCOUNT - ) - message = verify_message.format(name = name, protocol = settings.PROTOCOL, domain = settings.DOMAIN, code = ver_code) - email_result = send_email(email, "Verificación de cuenta", message) - + tasks.enviar_correo_confirmacion.delay(user) messages.success(request, f"¡Cuenta creada exitosamente! Por favor, verifica tu correo entrando al Link enviado.") return redirect("index")