diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..7d895b6 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +DB_TYPE=sqlite +SQLITE_PATH=databases/chatbot.db +FLASK_DEBUG=true +FLASK_SECRET_KEY=change-this-in-productio \ No newline at end of file diff --git a/.gitignore b/.gitignore index d4e940c..e5616be 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ /.idea/ testing.py /databases/ +.venv .env \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3448bda --- /dev/null +++ b/Dockerfile @@ -0,0 +1,64 @@ +# Use Python 3.11 slim image for smaller size +FROM python:3.11-slim + +# Set maintainer +LABEL maintainer="fuh@fuhlig.de" +LABEL description="PY_ChatBot - Modern Flask-based Chatbot Application" + +# Set environment variables +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + FLASK_APP=main.py \ + FLASK_ENV=production \ + PIP_NO_CACHE_DIR=1 \ + PIP_DISABLE_PIP_VERSION_CHECK=1 + +# Set work directory +WORKDIR /app + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + gcc \ + sqlite3 \ + curl \ + && rm -rf /var/lib/apt/lists/* + +# Create non-root user for security +RUN addgroup --system --gid 1001 chatbot && \ + adduser --system --uid 1001 --gid 1001 --no-create-home --disabled-password chatbot + +# Create necessary directories with proper permissions +RUN mkdir -p /app/data /app/logs /app/static && \ + chown -R chatbot:chatbot /app + +# Copy requirements first for better Docker layer caching +COPY requirements.txt . +RUN chown chatbot:chatbot requirements.txt + +# Install Python dependencies +RUN pip install --no-cache-dir -r requirements.txt + +# Copy application code +COPY . . +RUN chown -R chatbot:chatbot . + +# Copy entrypoint script +COPY docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh && \ + chown chatbot:chatbot /usr/local/bin/docker-entrypoint.sh + +# Switch to non-root user +USER chatbot + +# Expose port +EXPOSE 8080 + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ + CMD curl -f http://localhost:8080/ || exit 1 + +# Set entrypoint +ENTRYPOINT ["docker-entrypoint.sh"] + +# Default command +CMD ["python", "main.py"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..32b6707 --- /dev/null +++ b/README.md @@ -0,0 +1,157 @@ +# 🤖 PY_ChatBot + +A modular, secure, and extensible web-based chatbot platform built with Flask. Features include user authentication, session management, multi-database support, and a modern responsive UI. + +--- + +## 📋 Table of Contents + +- [Features](#features) +- [Demo](#demo) +- [Installation](#installation) +- [Configuration](#configuration) +- [Usage](#usage) +- [Project Structure](#project-structure) +- [Docker Setup](#docker-setup) +- [Contributing](#contributing) +- [Troubleshooting](#troubleshooting) +- [License](#license) + +--- + +## ✨ Features + +- **User Authentication** + - Registration, login, logout, and password change + - Email validation and strong password requirements + - Secure session cookies with configurable lifetime + +- **Multi-Database Support** + - Abstracted database layer + - Thread-safe SQLite implementation + - Ready for PostgreSQL/MySQL integration + +- **Modern UI/UX** + - Responsive templates: login, register, dashboard, profile, change password, 404 + - Gradient backgrounds, animations, and hover effects + - Flash messages for real-time feedback + +- **Security** + - SHA-512 password hashing + - Decorators for route protection (`@login_required`, `@logout_required`) + - CSRF-ready and input validation utilities + +- **Developer-Friendly** + - Well-organized code: `config`, `database`, `frontend`, `models`, `services`, `utils` + - Comprehensive logging and error handlers + - Environment-based configuration + +--- + +## đŸ–Ĩ Demo + +Screenshots and live demo links can be added here. + +--- + +## 🛠 Installation + +### Prerequisites + +- Python 3.8+ +- Git + +### Local Setup + +1. **Clone the repo** + + ```bash + git clone https://github.com/florianuhlig/PY_ChatBot.git + cd PY_ChatBot + git checkout Development + ``` + +2. **Create virtual environment** + + ```bash + python -m venv .venv + source .venv/bin/activate # macOS/Linux + .venv\Scripts\activate # Windows + ``` + +3. **Install dependencies** + + ```bash + pip install -r requirements.txt + ``` + +4. **Configure environment** + + Copy `.env.example` to `.env` and adjust values: + + ```bash + cp .env.example .env + ``` + +5. **Run the app** + + ```bash + python main.py + ``` + + Open your browser to `http://localhost:8080`. + +--- + +## âš™ī¸ Configuration + +Edit `.env` for: + +- `DB_TYPE` (e.g., `sqlite`, `postgresql`, `mysql`) +- `SQLITE_PATH` (path to SQLite file) +- `FLASK_SECRET_KEY` +- `FLASK_DEBUG`, `FLASK_HOST`, `FLASK_PORT` +- Session and password policy variables + +--- + +## 🚀 Usage + +- **Register**: `/register` +- **Login**: `/login` +- **Dashboard**: `/dashboard` (protected) +- **Profile**: `/profile` (protected) +- **Change Password**: `/change-password` (protected) +- **Logout**: `/logout` + +--- + +## 📁 Project Structure + +``` +PY_ChatBot/ +├── config/ # App configuration loader +│ └── database.py +├── database/ # DB abstraction and implementations +│ ├── interface.py +│ ├── sqlite_db.py +│ └── flask_integration.py +├── frontend/ # Flask application and templates +│ ├── app.py +│ └── templates/ +│ ├── login.html +│ ├── register.html +│ ├── dashboard.html +│ ├── profile.html +│ ├── change_password.html +│ └── 404.html +├── models/ # Data models (if any) +├── services/ # Business logic: user and auth services +├── utils/ # Utility functions and decorators +├── .env.example # Environment variable template +├── Dockerfile # Container setup +├── docker-compose.yml # Orchestration +├── docker-entrypoint.sh # Init script +├── main.py # Entry point +└── requirements.txt # Python dependencies +``` \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..6c11a2b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,66 @@ +services: + chatbot: + build: + context: . + dockerfile: Dockerfile + container_name: py_chatbot + restart: unless-stopped + ports: + - "8080:8080" + environment: + # Database Configuration + - DB_TYPE=sqlite + - SQLITE_PATH=/app/data/chatbot.db + + # Flask Configuration + - FLASK_HOST=0.0.0.0 + - FLASK_PORT=8080 + - FLASK_DEBUG=false + - FLASK_SECRET_KEY=your-super-secret-key-change-this-in-production + + # Session Configuration + - SESSION_LIFETIME_HOURS=24 + - SESSION_COOKIE_SECURE=false + - SESSION_COOKIE_HTTPONLY=true + volumes: + # Persist database and logs + - chatbot_data:/app/data + - chatbot_logs:/app/logs + networks: + - chatbot_network + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + + postgres: + image: postgres:15-alpine + container_name: py_chatbot_postgres + restart: unless-stopped + environment: + - POSTGRES_DB=chatbot + - POSTGRES_USER=chatbot_user + - POSTGRES_PASSWORD=secure_password_change_this + volumes: + - postgres_data:/var/lib/postgresql/data + - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro + networks: + - chatbot_network + profiles: + - postgres + +# Named Volumes +volumes: + chatbot_data: + driver: local + chatbot_logs: + driver: local + postgres_data: + driver: local + +# Networks +networks: + chatbot_network: + driver: bridge diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..d695393 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,53 @@ +#!/bin/bash +set -e + +echo "🤖 Starting PY_ChatBot..." +# Create directory for database dynamically based on SQLITE_PATH + +DB_DIR=$(dirname "$SQLITE_PATH") +mkdir -p "$DB_DIR" /app/logs + +# Set default environment variables if not provided +export DB_TYPE=${DB_TYPE:-sqlite} +export SQLITE_PATH=${SQLITE_PATH:-databases/chatbot.db} +export FLASK_HOST=${FLASK_HOST:-0.0.0.0} +export FLASK_PORT=${FLASK_PORT:-8080} +export FLASK_DEBUG=${FLASK_DEBUG:-false} + +# Generate a random secret key if not provided +if [ -z "$FLASK_SECRET_KEY" ]; then + export FLASK_SECRET_KEY=$(python -c "import secrets; print(secrets.token_hex(32))") + echo "âš ī¸ Generated random secret key. Set FLASK_SECRET_KEY environment variable for production!" +fi + +# Initialize database if it doesn't exist +if [ "$DB_TYPE" = "sqlite" ] && [ ! -f "$SQLITE_PATH" ]; then + echo "đŸ“Ļ Initializing SQLite database at $SQLITE_PATH..." + python -c " +import sys +sys.path.append('/app') +from config.database import DatabaseConfig +from database import get_database + +try: + db_config = DatabaseConfig() + db_type, config = db_config.get_database_config() + database = get_database(db_type, config) + print('✅ Database initialized successfully!') + database.disconnect() +except Exception as e: + print(f'❌ Database initialization failed: {e}') + sys.exit(1) +" +fi + +# Print configuration info +echo "📋 Configuration:" +echo " - Database Type: $DB_TYPE" +echo " - Database Path: $SQLITE_PATH" +echo " - Flask Host: $FLASK_HOST" +echo " - Flask Port: $FLASK_PORT" +echo " - Debug Mode: $FLASK_DEBUG" + +# Execute the command +exec "$@" diff --git a/frontend/templates/404.html b/frontend/templates/404.html new file mode 100644 index 0000000..2d2c506 --- /dev/null +++ b/frontend/templates/404.html @@ -0,0 +1,471 @@ + + + + + + 404 - Page Not Found | ChatBot + + + + +
+
+
+
+
+
+ +
+
404
+ +

Oops! Page Not Found

+ +

+ The page you're looking for seems to have wandered off into the digital void. + Don't worry, even the best explorers sometimes take a wrong turn! +

+ +
+

🤔 What happened?

+

+ The requested URL was not found on this server. This could be due to a + mistyped URL, a moved page, or a link that's no longer valid. +

+
+ +
+

Here's what you can try:

+ +
+ +
+ + 🏠 Go Home + + + {% if current_user %} + + 📊 Dashboard + + {% else %} + + 🔐 Login + + {% endif %} + + + â†Šī¸ Go Back + +
+ +
+

🤖 ChatBot Application

+

+ You're currently using our ChatBot platform. If you were trying to access + a specific chat or feature, please navigate through the main menu or + contact our support team for assistance. +

+
+ + +
+ + + + \ No newline at end of file diff --git a/frontend/templates/change_password.html b/frontend/templates/change_password.html new file mode 100644 index 0000000..182a215 --- /dev/null +++ b/frontend/templates/change_password.html @@ -0,0 +1,358 @@ + + + + + + Change Password - ChatBot + + + +
+ + +
+

Change Password

+

Update your account password

+
+ + + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} +
+ {{ message }} +
+ {% endfor %} + {% endif %} + {% endwith %} + +
+

🔒 Security Notice

+

For your security, we require your current password to make changes. Your new password will be encrypted and stored securely.

+
+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+

Password Requirements:

+
    +
  • At least 8 characters long
  • +
  • Contains at least one uppercase letter (A-Z)
  • +
  • Contains at least one lowercase letter (a-z)
  • +
  • Contains at least one number (0-9)
  • +
  • Contains at least one special character (!@#$%^&*)
  • +
+
+ +
+ + + Cancel + +
+
+
+ + + + \ No newline at end of file diff --git a/frontend/templates/profile.html b/frontend/templates/profile.html index 9d1aa2b..9d45f36 100644 --- a/frontend/templates/profile.html +++ b/frontend/templates/profile.html @@ -140,8 +140,8 @@

Account Status

Status: Active

-

Created: {{ user.created_at[:19] if user.created_at else 'Unknown' }}

-

Last Updated: {{ user.updated_at[:19] if user.updated_at else 'Unknown' }}

+

Created: {{ user.created_at.strftime('%Y-%m-%d %H:%M:%S') if user.created_at else 'Unknown' }}

+

Last Updated: {{ user.updated_at.strftime('%Y-%m-%d %H:%M:%S') if user.updated_at else 'Unknown' }}

diff --git a/requirements.txt b/requirements.txt index 7e10602..2bc2985 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,36 @@ -flask +# Requirements for PY_ChatBot +# Core Framework +Flask>=2.3.0,<3.0.0 +Werkzeug>=2.3.0,<3.0.0 + +# Database & ORM (Optional for future expansion) +SQLAlchemy>=2.0.0,<3.0.0 + +# Environment & Configuration +python-dotenv>=1.0.0 + +# Security & Authentication +bcrypt>=4.0.0 + +# HTTP Client (for health checks and external APIs) +requests>=2.31.0 + +# Date/Time utilities +python-dateutil>=2.8.0 + +# Development Dependencies (commented out for production) +# pytest>=7.4.0 +# pytest-flask>=1.2.0 +# pytest-cov>=4.1.0 +# black>=23.7.0 +# flake8>=6.0.0 +# mypy>=1.5.0 + +# Production WSGI Server +gunicorn>=21.2.0 + +# Logging +colorlog>=6.7.0 + +# Utility +click>=8.1.0 \ No newline at end of file