Implement MVP: Anonymous feedback submission (User Story 1)
Complete implementation of Phase 1-3 (64 tasks): - Phase 1: Project setup with Flask, pytest, configuration - Phase 2: Core infrastructure (auth, models, services, testing) - Phase 3: Anonymous feedback submission with file uploads Features: - Anonymous feedback submission (text and/or up to 3 file attachments) - Multi-language support (any language accepted) - File validation (type, size) and virus scanning (ClamAV) - Product management with active/archived status - File-based storage with YAML metadata - User authentication system (Flask-Login) - CSRF protection and rate limiting - Test coverage: 10 passing tests (contract + integration) Security: - No IP address logging (FR-055 compliance) - File type whitelist and size limits (10MB max) - Virus scanning with graceful degradation - Filename sanitization and secure storage Test Results: - 8 contract tests passed - 2 integration tests passed - End-to-end workflow verified 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
"""Production configuration"""
|
||||
import os
|
||||
|
||||
class ProductionConfig:
|
||||
"""Production environment configuration"""
|
||||
DEBUG = False
|
||||
TESTING = False
|
||||
|
||||
# Security
|
||||
SECRET_KEY = os.environ.get('SECRET_KEY') # Required in production
|
||||
if not SECRET_KEY:
|
||||
raise ValueError("SECRET_KEY environment variable must be set in production")
|
||||
|
||||
# Paths
|
||||
DATA_DIR = os.environ.get('DATA_DIR', '/var/lib/reklamator/data')
|
||||
|
||||
# Flask-WTF CSRF
|
||||
WTF_CSRF_ENABLED = True
|
||||
WTF_CSRF_TIME_LIMIT = None
|
||||
|
||||
# File Upload
|
||||
MAX_CONTENT_LENGTH = int(os.environ.get('MAX_CONTENT_LENGTH', 10 * 1024 * 1024)) # 10MB
|
||||
|
||||
# AI Integration
|
||||
ANTHROPIC_API_KEY = os.environ.get('ANTHROPIC_API_KEY') # Required
|
||||
if not ANTHROPIC_API_KEY:
|
||||
raise ValueError("ANTHROPIC_API_KEY environment variable must be set in production")
|
||||
|
||||
# ClamAV
|
||||
CLAMD_SOCKET = os.environ.get('CLAMD_SOCKET', '/var/run/clamav/clamd.ctl')
|
||||
|
||||
# Rate Limiting
|
||||
RATELIMIT_ENABLED = os.environ.get('RATE_LIMIT_ENABLED', 'true').lower() == 'true'
|
||||
RATELIMIT_STORAGE_URL = 'memory://'
|
||||
RATELIMIT_PER_HOUR = int(os.environ.get('RATE_LIMIT_PER_HOUR', 10))
|
||||
|
||||
# Session - HTTPS only
|
||||
SESSION_COOKIE_SECURE = True # HTTPS only
|
||||
SESSION_COOKIE_HTTPONLY = True
|
||||
SESSION_COOKIE_SAMESITE = 'Lax'
|
||||
PERMANENT_SESSION_LIFETIME = 86400 # 24 hours
|
||||
|
||||
# Security Headers
|
||||
SEND_FILE_MAX_AGE_DEFAULT = 31536000 # 1 year for static files
|
||||
Reference in New Issue
Block a user