This commit is contained in:
Iliyan Angelov
2025-11-25 02:06:38 +02:00
parent 2f6dca736a
commit 82024016cd
37 changed files with 1800 additions and 1478 deletions

View File

@@ -1,39 +0,0 @@
__pycache__
*.pyc
*.pyo
*.pyd
.Python
*.so
*.egg
*.egg-info
dist
build
.venv
venv/
env/
ENV/
.env
.venv
*.log
logs/
*.db
*.sqlite3
db.sqlite3
.git
.gitignore
README.md
*.md
.DS_Store
.vscode
.idea
*.swp
*.swo
*~
.pytest_cache
.coverage
htmlcov/
.tox/
.mypy_cache/
.dmypy.json
dmypy.json

68
backEnd/.gitignore vendored Normal file
View File

@@ -0,0 +1,68 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual Environment
venv/
env/
ENV/
.venv
# Django
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
/media
/staticfiles
/static
# Environment variables
.env
.env.local
.env.*.local
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Logs
logs/
*.log
# Coverage
htmlcov/
.coverage
.coverage.*
coverage.xml
*.cover
# Testing
.pytest_cache/
.tox/

View File

@@ -1,36 +0,0 @@
# Django Backend Dockerfile
FROM python:3.12-slim
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
DEBIAN_FRONTEND=noninteractive
# Set work directory
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \
gcc \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
# Install Python dependencies
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt
# Copy project
COPY . /app/
# Create directories for media and static files
RUN mkdir -p /app/media /app/staticfiles /app/logs
# Collect static files (will be done at runtime if needed)
# RUN python manage.py collectstatic --noinput
# Expose port
EXPOSE 1086
# Run gunicorn
CMD ["gunicorn", "--bind", "0.0.0.0:1086", "--workers", "3", "--timeout", "120", "--access-logfile", "-", "--error-logfile", "-", "gnx.wsgi:application"]

View File

@@ -0,0 +1,101 @@
"""
Custom email backend that handles localhost SSL certificate issues.
Disables SSL certificate verification for localhost connections.
"""
import ssl
from django.core.mail.backends.smtp import EmailBackend
from django.conf import settings
import logging
logger = logging.getLogger(__name__)
class LocalhostSMTPBackend(EmailBackend):
"""
Custom SMTP backend that disables SSL certificate verification
for localhost connections. This is safe for localhost mail servers.
"""
def open(self):
"""
Override to create SSL context without certificate verification
when connecting to localhost.
"""
if self.use_ssl or self.use_tls:
# Check if connecting to localhost
if self.host in ['localhost', '127.0.0.1', '::1']:
# Create SSL context without certificate verification for localhost
self.connection = None
try:
import smtplib
if self.use_ssl:
# For SSL connections
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
# SMTP_SSL uses 'context' parameter (Python 3.3+)
import sys
if sys.version_info >= (3, 3):
self.connection = smtplib.SMTP_SSL(
self.host,
self.port,
timeout=self.timeout,
context=context
)
else:
# For older Python, use unverified context
self.connection = smtplib.SMTP_SSL(
self.host,
self.port,
timeout=self.timeout
)
else:
# For TLS connections
self.connection = smtplib.SMTP(
self.host,
self.port,
timeout=self.timeout
)
# Create SSL context without certificate verification
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
# Use context parameter (Python 3.4+ uses 'context', not 'ssl_context')
# For older versions, we'll need to patch the socket after starttls
import sys
if sys.version_info >= (3, 4):
# Python 3.4+ supports context parameter
self.connection.starttls(context=context)
else:
# For older Python, disable verification globally for this connection
# by monkey-patching ssl._create_default_https_context temporarily
original_context = ssl._create_default_https_context
ssl._create_default_https_context = ssl._create_unverified_context
try:
self.connection.starttls()
finally:
ssl._create_default_https_context = original_context
if self.username and self.password:
self.connection.login(self.username, self.password)
logger.info(f"Successfully connected to localhost mail server at {self.host}:{self.port}")
return True
except Exception as e:
logger.error(f"Failed to connect to localhost mail server: {str(e)}")
if self.connection:
try:
self.connection.quit()
except:
pass
self.connection = None
raise
else:
# For non-localhost, use standard SSL/TLS with certificate verification
return super().open()
else:
# No SSL/TLS, use standard connection
return super().open()

View File

@@ -98,22 +98,34 @@ WSGI_APPLICATION = 'gnx.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
# Support both PostgreSQL (production) and SQLite (development)
DATABASE_URL = config('DATABASE_URL', default='')
if DATABASE_URL and DATABASE_URL.startswith('postgresql://'):
# PostgreSQL configuration
import dj_database_url
DATABASES = {
'default': dj_database_url.parse(DATABASE_URL, conn_max_age=600)
}
# Force SQLite - change this to False and set USE_POSTGRESQL=True to use PostgreSQL
FORCE_SQLITE = True # Set to False to allow PostgreSQL
if not FORCE_SQLITE:
# PostgreSQL configuration (only if FORCE_SQLITE is False)
USE_POSTGRESQL = config('USE_POSTGRESQL', default='False', cast=bool)
DATABASE_URL = config('DATABASE_URL', default='')
if USE_POSTGRESQL and DATABASE_URL and DATABASE_URL.startswith('postgresql://'):
import dj_database_url
DATABASES = {
'default': dj_database_url.parse(DATABASE_URL, conn_max_age=600)
}
else:
# Fallback to SQLite
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
else:
# SQLite configuration (development/fallback)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
# SQLite configuration (forced)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
}
# Password validation
@@ -355,8 +367,12 @@ if DEBUG and not USE_SMTP_IN_DEV:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
else:
# Production or Dev with SMTP enabled - use SMTP backend
EMAIL_BACKEND = config('EMAIL_BACKEND', default='django.core.mail.backends.smtp.EmailBackend')
EMAIL_HOST = config('EMAIL_HOST', default='mail.gnxsoft.com')
# Use custom backend for localhost to handle SSL certificate issues
if EMAIL_HOST in ['localhost', '127.0.0.1', '::1']:
EMAIL_BACKEND = 'gnx.email_backend.LocalhostSMTPBackend'
else:
EMAIL_BACKEND = config('EMAIL_BACKEND', default='django.core.mail.backends.smtp.EmailBackend')
EMAIL_PORT = config('EMAIL_PORT', default=587, cast=int)
EMAIL_USE_TLS = config('EMAIL_USE_TLS', default=True, cast=bool)
EMAIL_USE_SSL = config('EMAIL_USE_SSL', default=False, cast=bool)
@@ -367,7 +383,8 @@ else:
EMAIL_TIMEOUT = config('EMAIL_TIMEOUT', default=30, cast=int)
# Site URL for email links
SITE_URL = config('SITE_URL', default='http://localhost:3000')
# Use production URL by default if not in DEBUG mode
SITE_URL = config('SITE_URL', default='https://gnxsoft.com' if not DEBUG else 'http://localhost:3000')
# Email connection settings for production reliability
EMAIL_CONNECTION_TIMEOUT = config('EMAIL_CONNECTION_TIMEOUT', default=10, cast=int)

View File

@@ -1,26 +1,33 @@
# Production Environment Configuration for GNX Contact Form
# Copy this file to .env and update with your actual values
# Production Environment Configuration for GNX-WEB
# Copy this file to .env in the backEnd directory and update with your actual values
# Backend runs on port 1086 (internal only, proxied through nginx)
# Django Settings
SECRET_KEY=your-super-secret-production-key-here
SECRET_KEY=your-super-secret-production-key-here-change-this-immediately
DEBUG=False
ALLOWED_HOSTS=gnxsoft.com,www.gnxsoft.com,your-server-ip
ALLOWED_HOSTS=gnxsoft.com,www.gnxsoft.com,your-server-ip,localhost,127.0.0.1
# Database - Using SQLite (default)
# SQLite is configured in settings.py - no DATABASE_URL needed
# Database - PostgreSQL on host (port 5433 to avoid conflict with Docker instance on 5432)
# Format: postgresql://USER:PASSWORD@HOST:PORT/DBNAME
# Create database: sudo -u postgres psql
# CREATE DATABASE gnx_db;
# CREATE USER gnx_user WITH PASSWORD 'your_secure_password';
# GRANT ALL PRIVILEGES ON DATABASE gnx_db TO gnx_user;
DATABASE_URL=postgresql://gnx_user:your_password_here@localhost:5433/gnx_db
# Email Configuration (Production)
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=smtp.gmail.com
EMAIL_HOST=mail.gnxsoft.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_USE_SSL=False
EMAIL_HOST_USER=your-email@gmail.com
EMAIL_HOST_PASSWORD=your-app-password
EMAIL_HOST_USER=your-email@gnxsoft.com
EMAIL_HOST_PASSWORD=your-email-password
DEFAULT_FROM_EMAIL=noreply@gnxsoft.com
# Company email for contact form notifications
COMPANY_EMAIL=contact@gnxsoft.com
SUPPORT_EMAIL=support@gnxsoft.com
# Email timeout settings for production reliability
EMAIL_TIMEOUT=30
@@ -35,6 +42,8 @@ SECURE_HSTS_PRELOAD=True
SECURE_CONTENT_TYPE_NOSNIFF=True
SECURE_BROWSER_XSS_FILTER=True
X_FRAME_OPTIONS=DENY
SESSION_COOKIE_SECURE=True
CSRF_COOKIE_SECURE=True
# CORS Settings (Production)
PRODUCTION_ORIGINS=https://gnxsoft.com,https://www.gnxsoft.com
@@ -47,15 +56,27 @@ CSRF_TRUSTED_ORIGINS=https://gnxsoft.com,https://www.gnxsoft.com
# REQUIRED in production! Auto-generated only in DEBUG mode.
# Generate a secure key: python -c "import secrets; print(secrets.token_urlsafe(32))"
# Or get current key: python manage.py show_api_key
# This key must match the one in nginx configuration
INTERNAL_API_KEY=your-secure-api-key-here-change-this-in-production
# Admin IP Restriction - Only these IPs can access Django admin
# Comma-separated list of IP addresses or CIDR networks (e.g., 193.194.155.249 or 192.168.1.0/24)
ADMIN_ALLOWED_IPS=193.194.155.249
# Static Files
STATIC_ROOT=/var/www/gnx/staticfiles/
MEDIA_ROOT=/var/www/gnx/media/
# Custom allowed IPs for IP whitelist middleware (optional, comma-separated)
CUSTOM_ALLOWED_IPS=
# Site URL for email links and absolute URLs
SITE_URL=https://gnxsoft.com
# Static and Media Files (relative to backEnd directory)
# These will be collected/served from these locations
STATIC_ROOT=/home/gnx/Desktop/GNX-WEB/backEnd/staticfiles
MEDIA_ROOT=/home/gnx/Desktop/GNX-WEB/backEnd/media
# Logging
LOG_LEVEL=INFO
# Backend Port (internal only, nginx proxies to this)
# Backend runs on 127.0.0.1:1086
BACKEND_PORT=1086