""" Configuration module for Domain Check API """ import os from datetime import timedelta from typing import Dict, Any class Config: """Base configuration""" # Flask SECRET_KEY = os.getenv('SECRET_KEY', 'dev-secret-key-change-in-production') DEBUG = False TESTING = False # Database SQLALCHEMY_DATABASE_URI = os.getenv( 'DATABASE_URL', 'postgresql://dns_admin:password@localhost:5432/domain_check' ) SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_ECHO = False SQLALCHEMY_POOL_SIZE = 10 SQLALCHEMY_POOL_TIMEOUT = 30 SQLALCHEMY_POOL_RECYCLE = 3600 SQLALCHEMY_MAX_OVERFLOW = 20 # Redis REDIS_URL = os.getenv('REDIS_URL', 'redis://localhost:6379/0') REDIS_TTL_HOT = int(os.getenv('REDIS_TTL_HOT', 21600)) # 6 hours REDIS_TTL_WARM = int(os.getenv('REDIS_TTL_WARM', 86400)) # 24 hours REDIS_TTL_COLD = int(os.getenv('REDIS_TTL_COLD', 604800)) # 7 days # Celery CELERY_BROKER_URL = os.getenv('CELERY_BROKER_URL', 'redis://localhost:6379/1') CELERY_RESULT_BACKEND = os.getenv('CELERY_RESULT_BACKEND', 'redis://localhost:6379/2') CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' CELERY_ACCEPT_CONTENT = ['json'] CELERY_TIMEZONE = 'UTC' CELERY_ENABLE_UTC = True CELERY_TASK_TRACK_STARTED = True CELERY_TASK_TIME_LIMIT = 300 # 5 minutes CELERY_TASK_SOFT_TIME_LIMIT = 240 # 4 minutes # API Keys WHOXY_API_KEY = os.getenv('WHOXY_API_KEY', '') VIRUSTOTAL_API_KEY = os.getenv('VIRUSTOTAL_API_KEY', '') # Risk Scoring Thresholds RISK_THRESHOLD_LOW = int(os.getenv('RISK_THRESHOLD_LOW', 30)) RISK_THRESHOLD_MEDIUM = int(os.getenv('RISK_THRESHOLD_MEDIUM', 60)) RISK_THRESHOLD_HIGH = int(os.getenv('RISK_THRESHOLD_HIGH', 85)) # Domain Age Thresholds (days) DOMAIN_AGE_CRITICAL = int(os.getenv('DOMAIN_AGE_CRITICAL', 90)) # 3 months DOMAIN_AGE_HIGH = int(os.getenv('DOMAIN_AGE_HIGH', 180)) # 6 months DOMAIN_AGE_MEDIUM = int(os.getenv('DOMAIN_AGE_MEDIUM', 365)) # 1 year # API Rate Limiting WHOXY_DAILY_LIMIT = int(os.getenv('WHOXY_DAILY_LIMIT', 8000)) VIRUSTOTAL_DAILY_LIMIT = int(os.getenv('VIRUSTOTAL_DAILY_LIMIT', 500)) # Batch Processing BATCH_CHUNK_SIZE = int(os.getenv('BATCH_CHUNK_SIZE', 50)) BATCH_TIMEOUT_SECONDS = int(os.getenv('BATCH_TIMEOUT_SECONDS', 300)) # API Settings API_VERSION = os.getenv('API_VERSION', 'v1') API_TITLE = 'Domain Check API - Anti-Fake News Tool' API_DESCRIPTION = ''' **Comprehensive Domain Verification & Risk Scoring API** This API provides powerful tools for detecting potentially malicious or newly-registered domains commonly used in disinformation campaigns and fake news distribution. ## 🎯 Key Features - **WHOIS Analysis**: Domain age, registrar information, privacy protection detection - **DNS Verification**: A, AAAA, MX, TXT, NS, CNAME, SOA records with email security (SPF, DKIM, DMARC) - **SSL Certificate Validation**: Certificate validity, issuer verification, expiration monitoring - **Risk Scoring**: Multi-factor algorithm (0-100) with detailed breakdown - **Comprehensive Database**: Full history tracking and audit trail ## 📊 Risk Levels - **LOW (0-30)**: Established, trustworthy domains - **MEDIUM (31-60)**: Moderate risk, requires attention - **HIGH (61-85)**: Suspicious activity detected - **CRITICAL (86-100)**: Newly registered or highly suspicious domains ## 🚀 Quick Start Use the `/check` endpoint to verify any domain: ```bash curl -X POST http://domain-check-api:11000/api/v1/check/check \\ -H "Content-Type: application/json" \\ -d '{"domain": "example.com", "check_options": {"whois": true, "dns": true}}' ``` ## 📖 Documentation - **Swagger UI**: Interactive API testing and documentation - **ReDoc**: Clean, responsive API reference - **Platformă**: modul T4 (evaluare credibilitate sursă) al platformei DIDI ''' API_CONTACT = { 'name': 'DIDI Domain Check', 'email': 'support@didi.local' } API_LICENSE = { 'name': 'MIT', 'url': 'https://opensource.org/licenses/MIT' } API_TERMS_OF_SERVICE = '' # CORS - use CORS_ORIGINS env var for production (comma-separated) # Example: CORS_ORIGINS=https://didi.example.ro,https://admin.didi.example.ro # Default '*' allows all origins (development only!) _cors_origins_env = os.getenv('CORS_ORIGINS', '*') CORS_ORIGINS = ['*'] if _cors_origins_env == '*' else [o.strip() for o in _cors_origins_env.split(',') if o.strip()] CORS_ALLOW_HEADERS = ['Content-Type', 'Authorization'] CORS_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'] # Security - Documentation endpoints # Set DISABLE_SWAGGER=true in production to hide /docs and /redoc DISABLE_SWAGGER = os.getenv('DISABLE_SWAGGER', 'false').lower() == 'true' # Health endpoint - set SIMPLE_HEALTH=true to return only {"status":"ok"} SIMPLE_HEALTH = os.getenv('SIMPLE_HEALTH', 'false').lower() == 'true' # Logging LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO') LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' LOG_FILE = os.path.join(os.path.dirname(__file__), '..', 'logs', 'api.log') # External Service URLs WHOXY_API_URL = 'https://api.whoxy.com/' VIRUSTOTAL_API_URL = 'https://www.virustotal.com/api/v3/' RDAP_BOOTSTRAP_URL = 'https://rdap.org/' # Risk Scoring Weights RISK_WEIGHT_DOMAIN_AGE = 0.30 RISK_WEIGHT_REPUTATION = 0.30 RISK_WEIGHT_SSL = 0.20 RISK_WEIGHT_DNS = 0.10 RISK_WEIGHT_WHOIS = 0.10 # Pagination DEFAULT_PAGE_SIZE = 50 MAX_PAGE_SIZE = 100 # Timeouts (seconds) HTTP_TIMEOUT = 30 DNS_TIMEOUT = 10 SSL_TIMEOUT = 10 @staticmethod def init_app(app): """Initialize application configuration""" # Create logs directory if it doesn't exist log_dir = os.path.dirname(Config.LOG_FILE) os.makedirs(log_dir, exist_ok=True) class DevelopmentConfig(Config): """Development configuration""" DEBUG = True SQLALCHEMY_ECHO = False LOG_LEVEL = 'DEBUG' class ProductionConfig(Config): """Production configuration""" DEBUG = False TESTING = False SQLALCHEMY_ECHO = False LOG_LEVEL = 'WARNING' # Production security defaults (can be overridden by env vars) # If CORS_ORIGINS not set, default to empty (blocks all cross-origin) _cors_origins_env = os.getenv('CORS_ORIGINS', '') CORS_ORIGINS = [o.strip() for o in _cors_origins_env.split(',') if o.strip()] if _cors_origins_env else [] # Disable swagger by default in production (override with DISABLE_SWAGGER=false) DISABLE_SWAGGER = os.getenv('DISABLE_SWAGGER', 'true').lower() != 'false' # Simple health by default in production SIMPLE_HEALTH = os.getenv('SIMPLE_HEALTH', 'true').lower() != 'false' @classmethod def init_app(cls, app): Config.init_app(app) # Production-specific initialization import logging from logging.handlers import RotatingFileHandler # Setup file handler with rotation file_handler = RotatingFileHandler( cls.LOG_FILE, maxBytes=10485760, # 10MB backupCount=10 ) file_handler.setLevel(logging.WARNING) file_handler.setFormatter(logging.Formatter(cls.LOG_FORMAT)) app.logger.addHandler(file_handler) class TestingConfig(Config): """Testing configuration""" TESTING = True DEBUG = True SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:' REDIS_URL = 'redis://localhost:6379/15' # Use separate Redis DB for testing WTF_CSRF_ENABLED = False # Configuration dictionary config: Dict[str, Any] = { 'development': DevelopmentConfig, 'production': ProductionConfig, 'testing': TestingConfig, 'default': DevelopmentConfig } def get_config(env: str = None) -> Config: """Get configuration based on environment""" if env is None: env = os.getenv('FLASK_ENV', 'development') return config.get(env, config['default'])