mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-25 14:25:02 +00:00
Complete implementation of enterprise-grade authentication middleware for email service: Features: - JWT token creation/validation with configurable expiration - Bearer token extraction and validation - Multi-tenant isolation enforced at middleware level - Role-based access control (RBAC) with user/admin roles - Row-level security (RLS) for resource access - Automatic request logging with user context and audit trail - CORS configuration for email client frontend - Rate limiting (50 req/min per user with Redis backend) - Comprehensive error handling with proper HTTP status codes Implementation: - Enhanced src/middleware/auth.py (415 lines) - JWTConfig class for token management - create_jwt_token() for token generation - decode_jwt_token() for token validation - @verify_tenant_context decorator for auth middleware - @verify_role decorator for RBAC - verify_resource_access() for row-level security - log_request_context() for audit logging Testing: - 52 comprehensive test cases covering all features - 100% pass rate with fast execution (0.15s) - Test categories: JWT, multi-tenant, RBAC, RLS, logging, integration - Full coverage of error scenarios and edge cases Documentation: - AUTH_MIDDLEWARE.md: Complete API reference and configuration guide - AUTH_INTEGRATION_EXAMPLE.py: Real-world usage examples for 5+ scenarios - PHASE_7_SUMMARY.md: Implementation summary with checklist - Inline code documentation with type hints Security: - Multi-tenant data isolation at all levels - Constant-time password comparison - JWT signature validation - CORS protection - Rate limiting against abuse - Comprehensive audit logging Dependencies Added: - PyJWT==2.8.1 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
123 lines
3.8 KiB
Bash
Executable File
123 lines
3.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# Phase 8: Email Client System Backup Script
|
|
# Full backup of database, attachments, and critical data
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
BACKUP_DIR="${1:-.}/backups"
|
|
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
|
BACKUP_NAME="emailclient-backup-$TIMESTAMP"
|
|
|
|
echo "Email Client Backup - $TIMESTAMP"
|
|
echo "=================================="
|
|
echo "Backup directory: $BACKUP_DIR"
|
|
echo ""
|
|
|
|
# Create backup directory
|
|
mkdir -p "$BACKUP_DIR"
|
|
|
|
# 1. Database Backup
|
|
echo "[1/4] Backing up PostgreSQL database..."
|
|
DB_FILE="$BACKUP_DIR/$BACKUP_NAME-database.sql"
|
|
docker compose -f "$SCRIPT_DIR/docker-compose.yml" exec -T postgres \
|
|
pg_dump -U emailclient emailclient > "$DB_FILE"
|
|
echo "✓ Database backup: $DB_FILE ($(du -h "$DB_FILE" | cut -f1))"
|
|
|
|
# 2. Redis Backup
|
|
echo "[2/4] Backing up Redis cache..."
|
|
REDIS_FILE="$BACKUP_DIR/$BACKUP_NAME-redis.rdb"
|
|
docker compose -f "$SCRIPT_DIR/docker-compose.yml" exec -T redis \
|
|
redis-cli BGSAVE >/dev/null 2>&1
|
|
docker cp emailclient-redis:/data/dump.rdb "$REDIS_FILE" 2>/dev/null || echo " (Redis backup skipped or empty)"
|
|
if [ -f "$REDIS_FILE" ]; then
|
|
echo "✓ Redis backup: $REDIS_FILE ($(du -h "$REDIS_FILE" | cut -f1))"
|
|
else
|
|
echo "✓ Redis backup skipped (no data)"
|
|
fi
|
|
|
|
# 3. Attachment Files Backup
|
|
echo "[3/4] Backing up email attachments..."
|
|
ATTACH_FILE="$BACKUP_DIR/$BACKUP_NAME-attachments.tar.gz"
|
|
docker cp emailclient-email-service:/data/attachments "$BACKUP_DIR/attachments-temp" 2>/dev/null || true
|
|
if [ -d "$BACKUP_DIR/attachments-temp" ]; then
|
|
tar -czf "$ATTACH_FILE" -C "$BACKUP_DIR" attachments-temp 2>/dev/null || true
|
|
rm -rf "$BACKUP_DIR/attachments-temp"
|
|
if [ -f "$ATTACH_FILE" ]; then
|
|
echo "✓ Attachments backup: $ATTACH_FILE ($(du -h "$ATTACH_FILE" | cut -f1))"
|
|
fi
|
|
else
|
|
echo "✓ Attachments backup skipped (empty)"
|
|
fi
|
|
|
|
# 4. Dovecot Mailbox Backup
|
|
echo "[4/4] Backing up Dovecot mailboxes..."
|
|
MAIL_FILE="$BACKUP_DIR/$BACKUP_NAME-mailboxes.tar.gz"
|
|
docker cp emailclient-dovecot:/var/mail "$BACKUP_DIR/mail-temp" 2>/dev/null || true
|
|
if [ -d "$BACKUP_DIR/mail-temp" ] && [ -n "$(ls -A "$BACKUP_DIR/mail-temp")" ]; then
|
|
tar -czf "$MAIL_FILE" -C "$BACKUP_DIR" mail-temp 2>/dev/null || true
|
|
rm -rf "$BACKUP_DIR/mail-temp"
|
|
if [ -f "$MAIL_FILE" ]; then
|
|
echo "✓ Mailboxes backup: $MAIL_FILE ($(du -h "$MAIL_FILE" | cut -f1))"
|
|
fi
|
|
else
|
|
echo "✓ Mailboxes backup skipped (empty)"
|
|
fi
|
|
|
|
# Create manifest
|
|
echo ""
|
|
echo "[5/5] Creating backup manifest..."
|
|
MANIFEST="$BACKUP_DIR/$BACKUP_NAME-manifest.txt"
|
|
cat > "$MANIFEST" << EOF
|
|
Email Client Backup Manifest
|
|
=============================
|
|
Timestamp: $TIMESTAMP
|
|
Hostname: $(hostname)
|
|
Docker Compose: $SCRIPT_DIR/docker-compose.yml
|
|
|
|
Files:
|
|
------
|
|
EOF
|
|
|
|
for file in "$BACKUP_DIR/$BACKUP_NAME"*; do
|
|
if [ -f "$file" ]; then
|
|
SIZE=$(du -h "$file" | cut -f1)
|
|
NAME=$(basename "$file")
|
|
echo "$NAME ($SIZE)" >> "$MANIFEST"
|
|
fi
|
|
done
|
|
|
|
TOTAL_SIZE=$(du -sh "$BACKUP_DIR" | grep "backups" | cut -f1)
|
|
echo "
|
|
Total backup size: $TOTAL_SIZE
|
|
|
|
Restore Instructions:
|
|
---------------------
|
|
# Restore database
|
|
docker compose exec -T postgres psql -U emailclient emailclient < $BACKUP_NAME-database.sql
|
|
|
|
# Restore redis
|
|
docker cp $BACKUP_NAME-redis.rdb emailclient-redis:/data/dump.rdb
|
|
docker compose restart redis
|
|
|
|
# Restore attachments
|
|
tar -xzf $BACKUP_NAME-attachments.tar.gz
|
|
docker cp attachments-temp/attachments emailclient-email-service:/data/
|
|
|
|
# Restore mailboxes
|
|
tar -xzf $BACKUP_NAME-mailboxes.tar.gz
|
|
docker cp mail-temp/mail emailclient-dovecot:/var/
|
|
" >> "$MANIFEST"
|
|
|
|
echo "✓ Manifest created: $MANIFEST"
|
|
|
|
echo ""
|
|
echo "Backup Complete!"
|
|
echo "================"
|
|
echo "Total size: $TOTAL_SIZE"
|
|
echo "Location: $BACKUP_DIR"
|
|
echo ""
|
|
echo "Retention policy: Keep latest 7 backups"
|
|
echo "Cleanup old backups:"
|
|
echo " ls -t $BACKUP_DIR/*-manifest.txt | tail -n +8 | xargs -I {} rm {}.."
|