updates
This commit is contained in:
@@ -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
68
backEnd/.gitignore
vendored
Normal 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/
|
||||
|
||||
@@ -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"]
|
||||
|
||||
101
backEnd/gnx/email_backend.py
Normal file
101
backEnd/gnx/email_backend.py
Normal 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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user