atriumchain-api / config.py
Jainish1808's picture
Upload folder using huggingface_hub
fe0192d verified
from pydantic_settings import BaseSettings
from typing import List, Optional
from pathlib import Path
class Settings(BaseSettings):
# SECURITY: Must be set via .env file. No default for production safety.
SECRET_KEY: str # Required - generate with: openssl rand -base64 32
ALGORITHM: str = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24
# MongoDB Atlas configuration
# Example: mongodb+srv://user:pass@cluster.mongodb.net/
# NOTE: Credentials present here only for legacy/dev; MUST be overridden in environment (.env)
# Recommendation: remove secrets before committing publicly.
# IMPORTANT: Provide via environment (.env). Default points to localhost for safety.
MONGODB_URI: str = "mongodb://localhost:27017" # Override in .env for Atlas or remote
MONGODB_DB_NAME: str = "atriumchain"
# SECURITY: Explicit allowed origins only - no wildcard "*" for production
# Add production domains here when deploying (e.g., "https://yourdomain.com")
CORS_ORIGINS: List[str] = [
"http://localhost:5173",
"http://127.0.0.1:5173",
"http://localhost:5174",
"http://127.0.0.1:5174",
"http://localhost:5175",
"http://127.0.0.1:5175",
# Production domains
"https://atriumchain.web.app",
"https://atriumchain.firebaseapp.com",
"https://jainish1808-atriumchain-api.hf.space",
"https://huggingface.co"
]
ALLOWED_ORIGINS: Optional[str] = None # comma-separated override list; if set replaces CORS_ORIGINS
XRPL_NETWORK: str = "testnet" # testnet only
ISSUER_SEED: str | None = None # DEPRECATED: Use admin wallet instead (kept for backward compatibility)
# TOKEN MODEL: IOU for fractional real estate ownership
# Uses XRPL issued currencies for fungible property tokens
XRPL_TOKEN_MODEL: str = "IOU" # Fixed to IOU - the correct model for fractional ownership
# Blockchain integration is mandatory for production
XRPL_LEDGER_PURCHASE_ENABLED: bool = True
# Configurable AED to XRP demo conversion rate (used only for displaying estimated costs
# and in IOU path cost calculation). Previously hard-coded to 1e-6.
# NOTE: This should be replaced with real-time oracle in production
XRPL_RATE_AED_TO_XRP: float = 0.000001
# Unified explorer base (avoid hard-coded duplicates elsewhere)
XRPL_EXPLORER_BASE: str = "https://testnet.xrpl.org/transactions/"
# Unified RPC URL (replace ad-hoc constants in services)
XRPL_RPC_URL: str = "https://s.altnet.rippletest.net:51234/"
# Optional encryption key (32 byte raw, hex, or Fernet base64). If absent seeds remain legacy/base64.
ENCRYPTION_KEY: str | None = None
# Security Configuration
RATE_LIMIT_ENABLED: bool = True
MAX_LOGIN_ATTEMPTS: int = 5
LOGIN_LOCKOUT_MINUTES: int = 15
REQUIRE_STRONG_PASSWORDS: bool = True
MIN_PASSWORD_LENGTH: int = 8
# Session Configuration
SESSION_TIMEOUT_MINUTES: int = 60
REFRESH_TOKEN_EXPIRE_DAYS: int = 7
# IPFS Configuration for Decentralized Document Storage
WEB3_STORAGE_API_TOKEN: str | None = None # Get free token from https://web3.storage
PINATA_API_KEY: str | None = None # Get free API key from https://pinata.cloud
PINATA_SECRET_KEY: str | None = None # Secret key from Pinata dashboard
IPFS_GATEWAY: str = "ipfs.io" # Default public IPFS gateway
IPFS_BACKUP_GATEWAY: str = "cloudflare-ipfs.com" # Backup gateway
IPFS_PROVIDER: str = "local_simulation" # Options: "pinata", "web3storage", "local_simulation"
# Monitoring and Logging Configuration
LOG_LEVEL: str = "INFO" # DEBUG, INFO, WARNING, ERROR, CRITICAL
LOG_FILE_ENABLED: bool = True
LOG_FILE_PATH: str = "logs/app.log"
LOG_FILE_MAX_SIZE: int = 10485760 # 10MB in bytes
LOG_FILE_BACKUP_COUNT: int = 5
# Performance Monitoring
ENABLE_PERFORMANCE_MONITORING: bool = True
SLOW_QUERY_THRESHOLD: float = 1.0 # Log queries taking longer than 1 second
# Transaction Monitoring
ENABLE_TRANSACTION_MONITORING: bool = True
BLOCKCHAIN_TIMEOUT_SECONDS: int = 30
# Environment-specific settings
ENVIRONMENT: str = "development" # development, staging, production
DEBUG_MODE: bool = True # Set to False in production
def encryption_enabled(self) -> bool:
return bool(self.ENCRYPTION_KEY)
def is_production(self) -> bool:
return self.ENVIRONMENT.lower() == "production"
def is_development(self) -> bool:
return self.ENVIRONMENT.lower() == "development"
def validate_configuration(self): # renamed from validate_issuer_seed for clarity
"""Validate configuration settings and log important information"""
# Validate IOU token configuration
if not self.ISSUER_SEED:
print("[CONFIG][INFO] ISSUER_SEED not set – using admin wallet for token issuance (recommended).")
# Configure CORS origins
if self.ALLOWED_ORIGINS:
self.CORS_ORIGINS = [o.strip() for o in self.ALLOWED_ORIGINS.split(',') if o.strip()]
# Validate environment-specific settings
if self.is_production():
# CRITICAL: Validate production security requirements
if self.DEBUG_MODE:
print("[CONFIG][ERROR] DEBUG_MODE is enabled in production environment!")
print("[CONFIG][ERROR] Set DEBUG_MODE=false in .env file immediately!")
raise ValueError("DEBUG_MODE must be disabled in production environment")
# H1/H3: Enforce encryption key in production for wallet seed security
if not self.ENCRYPTION_KEY:
print("[CONFIG][ERROR] ENCRYPTION_KEY not set in production environment!")
print("[CONFIG][ERROR] Wallet seeds will not be encrypted. This is a security risk.")
print("[CONFIG][INFO] Generate key: python -c \"from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())\"")
raise ValueError("ENCRYPTION_KEY is required in production environment")
else:
print("[CONFIG][INFO] ✅ Encryption enabled for wallet seeds.")
else:
# Development environment warnings
if not self.ENCRYPTION_KEY:
print("[CONFIG][WARNING] ENCRYPTION_KEY not set – wallet seeds stored with legacy obfuscation.")
print("[CONFIG][WARNING] For production, generate with: python -c \"from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())\"")
else:
print("[CONFIG][INFO] ✅ Encryption enabled for wallet seeds.")
# Log monitoring configuration
print(f"[CONFIG][INFO] Logging level: {self.LOG_LEVEL}")
print(f"[CONFIG][INFO] Environment: {self.ENVIRONMENT}")
print(f"[CONFIG][INFO] Performance monitoring: {'Enabled' if self.ENABLE_PERFORMANCE_MONITORING else 'Disabled'}")
print(f"[CONFIG][INFO] Transaction monitoring: {'Enabled' if self.ENABLE_TRANSACTION_MONITORING else 'Disabled'}")
class Config:
env_file = Path(__file__).parent / ".env"
settings = Settings()
settings.validate_configuration()