unify config
This commit is contained in:
		
							parent
							
								
									3511f18f9a
								
							
						
					
					
						commit
						689e8c00d4
					
				
							
								
								
									
										34
									
								
								.env.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								.env.example
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					# ===============================================
 | 
				
			||||||
 | 
					# DNSRecon Environment Variables
 | 
				
			||||||
 | 
					# ===============================================
 | 
				
			||||||
 | 
					# Copy this file to .env and fill in your values.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# --- API Keys ---
 | 
				
			||||||
 | 
					# Add your Shodan API key for the Shodan provider to be enabled.
 | 
				
			||||||
 | 
					SHODAN_API_KEY=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# --- Flask & Session Settings ---
 | 
				
			||||||
 | 
					# A strong, random secret key is crucial for session security.
 | 
				
			||||||
 | 
					FLASK_SECRET_KEY=your-very-secret-and-random-key-here
 | 
				
			||||||
 | 
					FLASK_HOST=127.0.0.1
 | 
				
			||||||
 | 
					FLASK_PORT=5000
 | 
				
			||||||
 | 
					FLASK_DEBUG=True
 | 
				
			||||||
 | 
					# How long a user's session in the browser lasts (in hours).
 | 
				
			||||||
 | 
					FLASK_PERMANENT_SESSION_LIFETIME_HOURS=2
 | 
				
			||||||
 | 
					# How long inactive scanner data is stored in Redis (in minutes).
 | 
				
			||||||
 | 
					SESSION_TIMEOUT_MINUTES=60
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# --- Application Core Settings ---
 | 
				
			||||||
 | 
					# The default number of levels to recurse when scanning.
 | 
				
			||||||
 | 
					DEFAULT_RECURSION_DEPTH=2
 | 
				
			||||||
 | 
					# Default timeout for provider API requests in seconds.
 | 
				
			||||||
 | 
					DEFAULT_TIMEOUT=30
 | 
				
			||||||
 | 
					# The number of concurrent provider requests to make.
 | 
				
			||||||
 | 
					MAX_CONCURRENT_REQUESTS=5
 | 
				
			||||||
 | 
					# The number of results from a provider that triggers the "large entity" grouping.
 | 
				
			||||||
 | 
					LARGE_ENTITY_THRESHOLD=100
 | 
				
			||||||
 | 
					# The number of times to retry a target if a provider fails.
 | 
				
			||||||
 | 
					MAX_RETRIES_PER_TARGET=3
 | 
				
			||||||
 | 
					# How long cached provider responses are stored (in hours).
 | 
				
			||||||
 | 
					CACHE_EXPIRY_HOURS=12
 | 
				
			||||||
							
								
								
									
										5
									
								
								app.py
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								app.py
									
									
									
									
									
								
							@ -16,8 +16,9 @@ from config import config
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app = Flask(__name__)
 | 
					app = Flask(__name__)
 | 
				
			||||||
app.config['SECRET_KEY'] = 'dnsrecon-dev-key-change-in-production'
 | 
					# Use centralized configuration for Flask settings
 | 
				
			||||||
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=2)  # 2 hour session lifetime
 | 
					app.config['SECRET_KEY'] = config.flask_secret_key
 | 
				
			||||||
 | 
					app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=config.flask_permanent_session_lifetime_hours)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_user_scanner():
 | 
					def get_user_scanner():
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										118
									
								
								config.py
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								config.py
									
									
									
									
									
								
							@ -5,111 +5,93 @@ Handles API key storage, rate limiting, and default settings.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
from typing import Dict, Optional
 | 
					from typing import Dict, Optional
 | 
				
			||||||
 | 
					from dotenv import load_dotenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Load environment variables from .env file
 | 
				
			||||||
 | 
					load_dotenv()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Config:
 | 
					class Config:
 | 
				
			||||||
    """Configuration manager for DNSRecon application."""
 | 
					    """Configuration manager for DNSRecon application."""
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        """Initialize configuration with default values."""
 | 
					        """Initialize configuration with default values."""
 | 
				
			||||||
        self.api_keys: Dict[str, Optional[str]] = {
 | 
					        self.api_keys: Dict[str, Optional[str]] = {}
 | 
				
			||||||
            'shodan': None
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        # Default settings
 | 
					        # --- General Settings ---
 | 
				
			||||||
        self.default_recursion_depth = 2
 | 
					        self.default_recursion_depth = 2
 | 
				
			||||||
        self.default_timeout = 10
 | 
					        self.default_timeout = 10
 | 
				
			||||||
        self.max_concurrent_requests = 5
 | 
					        self.max_concurrent_requests = 5
 | 
				
			||||||
        self.large_entity_threshold = 100
 | 
					        self.large_entity_threshold = 100
 | 
				
			||||||
        self.max_retries_per_target = 3
 | 
					        self.max_retries_per_target = 3
 | 
				
			||||||
 | 
					        self.cache_expiry_hours = 12
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        # Rate limiting settings (requests per minute)
 | 
					        # --- Rate Limiting (requests per minute) ---
 | 
				
			||||||
        self.rate_limits = {
 | 
					        self.rate_limits = {
 | 
				
			||||||
            'crtsh': 60,          # Free service, be respectful
 | 
					            'crtsh': 60,
 | 
				
			||||||
            'shodan': 60,         # API dependent
 | 
					            'shodan': 60,
 | 
				
			||||||
            'dns': 100            # Local DNS queries
 | 
					            'dns': 100
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        # Provider settings
 | 
					        # --- Provider Settings ---
 | 
				
			||||||
        self.enabled_providers = {
 | 
					        self.enabled_providers = {
 | 
				
			||||||
            'crtsh': True,        # Always enabled (free)
 | 
					            'crtsh': True,
 | 
				
			||||||
            'dns': True,          # Always enabled (free)
 | 
					            'dns': True,
 | 
				
			||||||
            'shodan': False       # Requires API key
 | 
					            'shodan': False
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        # Logging configuration
 | 
					        # --- Logging ---
 | 
				
			||||||
        self.log_level = 'INFO'
 | 
					        self.log_level = 'INFO'
 | 
				
			||||||
        self.log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
 | 
					        self.log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        # Flask configuration
 | 
					        # --- Flask & Session Settings ---
 | 
				
			||||||
        self.flask_host = '127.0.0.1'
 | 
					        self.flask_host = '127.0.0.1'
 | 
				
			||||||
        self.flask_port = 5000
 | 
					        self.flask_port = 5000
 | 
				
			||||||
        self.flask_debug = True
 | 
					        self.flask_debug = True
 | 
				
			||||||
 | 
					        self.flask_secret_key = 'default-secret-key-change-me'
 | 
				
			||||||
 | 
					        self.flask_permanent_session_lifetime_hours = 2
 | 
				
			||||||
 | 
					        self.session_timeout_minutes = 60
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    def set_api_key(self, provider: str, api_key: str) -> bool:
 | 
					        # Load environment variables to override defaults
 | 
				
			||||||
        """
 | 
					        self.load_from_env()
 | 
				
			||||||
        Set API key for a provider.
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        Args:
 | 
					    def load_from_env(self):
 | 
				
			||||||
            provider: Provider name (shodan, etc)
 | 
					        """Load configuration from environment variables."""
 | 
				
			||||||
            api_key: API key string
 | 
					        self.set_api_key('shodan', os.getenv('SHODAN_API_KEY'))
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
        Returns:
 | 
					        # Override settings from environment
 | 
				
			||||||
            bool: True if key was set successfully
 | 
					        self.default_recursion_depth = int(os.getenv('DEFAULT_RECURSION_DEPTH', self.default_recursion_depth))
 | 
				
			||||||
        """
 | 
					        self.default_timeout = int(os.getenv('DEFAULT_TIMEOUT', self.default_timeout))
 | 
				
			||||||
        if provider in self.api_keys:
 | 
					        self.max_concurrent_requests = int(os.getenv('MAX_CONCURRENT_REQUESTS', self.max_concurrent_requests))
 | 
				
			||||||
            self.api_keys[provider] = api_key
 | 
					        self.large_entity_threshold = int(os.getenv('LARGE_ENTITY_THRESHOLD', self.large_entity_threshold))
 | 
				
			||||||
            self.enabled_providers[provider] = True if api_key else False
 | 
					        self.max_retries_per_target = int(os.getenv('MAX_RETRIES_PER_TARGET', self.max_retries_per_target))
 | 
				
			||||||
            return True
 | 
					        self.cache_expiry_hours = int(os.getenv('CACHE_EXPIRY_HOURS', self.cache_expiry_hours))
 | 
				
			||||||
        return False
 | 
					        
 | 
				
			||||||
 | 
					        # Override Flask and session settings
 | 
				
			||||||
 | 
					        self.flask_host = os.getenv('FLASK_HOST', self.flask_host)
 | 
				
			||||||
 | 
					        self.flask_port = int(os.getenv('FLASK_PORT', self.flask_port))
 | 
				
			||||||
 | 
					        self.flask_debug = os.getenv('FLASK_DEBUG', str(self.flask_debug)).lower() == 'true'
 | 
				
			||||||
 | 
					        self.flask_secret_key = os.getenv('FLASK_SECRET_KEY', self.flask_secret_key)
 | 
				
			||||||
 | 
					        self.flask_permanent_session_lifetime_hours = int(os.getenv('FLASK_PERMANENT_SESSION_LIFETIME_HOURS', self.flask_permanent_session_lifetime_hours))
 | 
				
			||||||
 | 
					        self.session_timeout_minutes = int(os.getenv('SESSION_TIMEOUT_MINUTES', self.session_timeout_minutes))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_api_key(self, provider: str, api_key: Optional[str]) -> bool:
 | 
				
			||||||
 | 
					        """Set API key for a provider."""
 | 
				
			||||||
 | 
					        self.api_keys[provider] = api_key
 | 
				
			||||||
 | 
					        if api_key:
 | 
				
			||||||
 | 
					            self.enabled_providers[provider] = True
 | 
				
			||||||
 | 
					        return True
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def get_api_key(self, provider: str) -> Optional[str]:
 | 
					    def get_api_key(self, provider: str) -> Optional[str]:
 | 
				
			||||||
        """
 | 
					        """Get API key for a provider."""
 | 
				
			||||||
        Get API key for a provider.
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        Args:
 | 
					 | 
				
			||||||
            provider: Provider name
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        Returns:
 | 
					 | 
				
			||||||
            API key or None if not set
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.api_keys.get(provider)
 | 
					        return self.api_keys.get(provider)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def is_provider_enabled(self, provider: str) -> bool:
 | 
					    def is_provider_enabled(self, provider: str) -> bool:
 | 
				
			||||||
        """
 | 
					        """Check if a provider is enabled."""
 | 
				
			||||||
        Check if a provider is enabled.
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        Args:
 | 
					 | 
				
			||||||
            provider: Provider name
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        Returns:
 | 
					 | 
				
			||||||
            bool: True if provider is enabled
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.enabled_providers.get(provider, False)
 | 
					        return self.enabled_providers.get(provider, False)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def get_rate_limit(self, provider: str) -> int:
 | 
					    def get_rate_limit(self, provider: str) -> int:
 | 
				
			||||||
        """
 | 
					        """Get rate limit for a provider."""
 | 
				
			||||||
        Get rate limit for a provider.
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        Args:
 | 
					 | 
				
			||||||
            provider: Provider name
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        Returns:
 | 
					 | 
				
			||||||
            Rate limit in requests per minute
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.rate_limits.get(provider, 60)
 | 
					        return self.rate_limits.get(provider, 60)
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    def load_from_env(self):
 | 
					 | 
				
			||||||
        """Load configuration from environment variables."""
 | 
					 | 
				
			||||||
        if os.getenv('SHODAN_API_KEY'):
 | 
					 | 
				
			||||||
            self.set_api_key('shodan', os.getenv('SHODAN_API_KEY'))
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        # Override default settings from environment
 | 
					 | 
				
			||||||
        self.default_recursion_depth = int(os.getenv('DEFAULT_RECURSION_DEPTH', '2'))
 | 
					 | 
				
			||||||
        self.flask_debug = os.getenv('FLASK_DEBUG', 'True').lower() == 'true'
 | 
					 | 
				
			||||||
        self.default_timeout = 30
 | 
					 | 
				
			||||||
        self.max_concurrent_requests = 5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Global configuration instance
 | 
					# Global configuration instance
 | 
				
			||||||
config = Config()
 | 
					config = Config()
 | 
				
			||||||
@ -3,11 +3,9 @@ Per-session configuration management for DNSRecon.
 | 
				
			|||||||
Provides isolated configuration instances for each user session.
 | 
					Provides isolated configuration instances for each user session.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import os
 | 
					from config import Config
 | 
				
			||||||
from typing import Dict, Optional
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SessionConfig(Config):
 | 
				
			||||||
class SessionConfig:
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Session-specific configuration that inherits from global config
 | 
					    Session-specific configuration that inherits from global config
 | 
				
			||||||
    but maintains isolated API keys and provider settings.
 | 
					    but maintains isolated API keys and provider settings.
 | 
				
			||||||
@ -15,106 +13,8 @@ class SessionConfig:
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        """Initialize session config with global defaults."""
 | 
					        """Initialize session config with global defaults."""
 | 
				
			||||||
        # Copy all attributes from global config
 | 
					        super().__init__()
 | 
				
			||||||
        self.api_keys: Dict[str, Optional[str]] = {
 | 
					 | 
				
			||||||
            'shodan': None
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        # Default settings (copied from global config)
 | 
					 | 
				
			||||||
        self.default_recursion_depth = 2
 | 
					 | 
				
			||||||
        self.default_timeout = 30
 | 
					 | 
				
			||||||
        self.max_concurrent_requests = 5
 | 
					 | 
				
			||||||
        self.large_entity_threshold = 100
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        # Rate limiting settings (per session)
 | 
					 | 
				
			||||||
        self.rate_limits = {
 | 
					 | 
				
			||||||
            'crtsh': 60,
 | 
					 | 
				
			||||||
            'shodan': 60,
 | 
					 | 
				
			||||||
            'dns': 100
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        # Provider settings (per session)
 | 
					 | 
				
			||||||
        self.enabled_providers = {
 | 
					 | 
				
			||||||
            'crtsh': True,
 | 
					 | 
				
			||||||
            'dns': True,
 | 
					 | 
				
			||||||
            'shodan': False
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        # Logging configuration
 | 
					 | 
				
			||||||
        self.log_level = 'INFO'
 | 
					 | 
				
			||||||
        self.log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        # Flask configuration (shared)
 | 
					 | 
				
			||||||
        self.flask_host = '127.0.0.1'
 | 
					 | 
				
			||||||
        self.flask_port = 5000
 | 
					 | 
				
			||||||
        self.flask_debug = True
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    def set_api_key(self, provider: str, api_key: str) -> bool:
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        Set API key for a provider in this session.
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        Args:
 | 
					 | 
				
			||||||
            provider: Provider name (shodan, etc)
 | 
					 | 
				
			||||||
            api_key: API key string
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        Returns:
 | 
					 | 
				
			||||||
            bool: True if key was set successfully
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        if provider in self.api_keys:
 | 
					 | 
				
			||||||
            self.api_keys[provider] = api_key
 | 
					 | 
				
			||||||
            self.enabled_providers[provider] = True if api_key else False
 | 
					 | 
				
			||||||
            return True
 | 
					 | 
				
			||||||
        return False
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    def get_api_key(self, provider: str) -> Optional[str]:
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        Get API key for a provider in this session.
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        Args:
 | 
					 | 
				
			||||||
            provider: Provider name
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        Returns:
 | 
					 | 
				
			||||||
            API key or None if not set
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.api_keys.get(provider)
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    def is_provider_enabled(self, provider: str) -> bool:
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        Check if a provider is enabled in this session.
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        Args:
 | 
					 | 
				
			||||||
            provider: Provider name
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        Returns:
 | 
					 | 
				
			||||||
            bool: True if provider is enabled
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.enabled_providers.get(provider, False)
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    def get_rate_limit(self, provider: str) -> int:
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        Get rate limit for a provider in this session.
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        Args:
 | 
					 | 
				
			||||||
            provider: Provider name
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        Returns:
 | 
					 | 
				
			||||||
            Rate limit in requests per minute
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.rate_limits.get(provider, 60)
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    def load_from_env(self):
 | 
					 | 
				
			||||||
        """Load configuration from environment variables (only if not already set)."""
 | 
					 | 
				
			||||||
        if os.getenv('SHODAN_API_KEY') and not self.api_keys['shodan']:
 | 
					 | 
				
			||||||
            self.set_api_key('shodan', os.getenv('SHODAN_API_KEY'))
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        # Override default settings from environment
 | 
					 | 
				
			||||||
        self.default_recursion_depth = int(os.getenv('DEFAULT_RECURSION_DEPTH', '2'))
 | 
					 | 
				
			||||||
        self.default_timeout = 30
 | 
					 | 
				
			||||||
        self.max_concurrent_requests = 5
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def create_session_config() -> 'SessionConfig':
 | 
				
			||||||
def create_session_config() -> SessionConfig:
 | 
					 | 
				
			||||||
    """Create a new session configuration instance."""
 | 
					    """Create a new session configuration instance."""
 | 
				
			||||||
    session_config = SessionConfig()
 | 
					    return SessionConfig()
 | 
				
			||||||
    session_config.load_from_env()
 | 
					 | 
				
			||||||
    return session_config
 | 
					 | 
				
			||||||
@ -8,6 +8,7 @@ import pickle
 | 
				
			|||||||
from typing import Dict, Optional, Any, List
 | 
					from typing import Dict, Optional, Any, List
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from core.scanner import Scanner
 | 
					from core.scanner import Scanner
 | 
				
			||||||
 | 
					from config import config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# WARNING: Using pickle can be a security risk if the data source is not trusted.
 | 
					# WARNING: Using pickle can be a security risk if the data source is not trusted.
 | 
				
			||||||
# In this case, we are only serializing/deserializing our own trusted Scanner objects,
 | 
					# In this case, we are only serializing/deserializing our own trusted Scanner objects,
 | 
				
			||||||
@ -18,10 +19,13 @@ class SessionManager:
 | 
				
			|||||||
    Manages multiple scanner instances for concurrent user sessions using Redis.
 | 
					    Manages multiple scanner instances for concurrent user sessions using Redis.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def __init__(self, session_timeout_minutes: int = 60):
 | 
					    def __init__(self, session_timeout_minutes: int = 0):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Initialize session manager with a Redis backend.
 | 
					        Initialize session manager with a Redis backend.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        if session_timeout_minutes is None:
 | 
				
			||||||
 | 
					            session_timeout_minutes = config.session_timeout_minutes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.redis_client = redis.StrictRedis(db=0, decode_responses=False)
 | 
					        self.redis_client = redis.StrictRedis(db=0, decode_responses=False)
 | 
				
			||||||
        self.session_timeout = session_timeout_minutes * 60  # Convert to seconds
 | 
					        self.session_timeout = session_timeout_minutes * 60  # Convert to seconds
 | 
				
			||||||
        self.lock = threading.Lock() # Lock for local operations, Redis handles atomic ops
 | 
					        self.lock = threading.Lock() # Lock for local operations, Redis handles atomic ops
 | 
				
			||||||
 | 
				
			|||||||
@ -82,7 +82,7 @@ class BaseProvider(ABC):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # Caching configuration (per session)
 | 
					        # Caching configuration (per session)
 | 
				
			||||||
        self.cache_dir = f'.cache/{id(self.config)}'  # Unique cache per session config
 | 
					        self.cache_dir = f'.cache/{id(self.config)}'  # Unique cache per session config
 | 
				
			||||||
        self.cache_expiry = 12 * 3600  # 12 hours in seconds
 | 
					        self.cache_expiry = self.config.cache_expiry_hours * 3600
 | 
				
			||||||
        if not os.path.exists(self.cache_dir):
 | 
					        if not os.path.exists(self.cache_dir):
 | 
				
			||||||
            os.makedirs(self.cache_dir)
 | 
					            os.makedirs(self.cache_dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -6,4 +6,5 @@ Werkzeug>=2.3.7
 | 
				
			|||||||
urllib3>=2.0.0
 | 
					urllib3>=2.0.0
 | 
				
			||||||
dnspython>=2.4.2
 | 
					dnspython>=2.4.2
 | 
				
			||||||
gunicorn
 | 
					gunicorn
 | 
				
			||||||
redis
 | 
					redis
 | 
				
			||||||
 | 
					python-dotenv
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user