Cache System (Backend): - Implemented two-tier hybrid cache: L1 (in-memory) + L2 (SQLite) - L1 cache: Fast dictionary-based with 5-minute TTL for hot data - L2 cache: Persistent SQLite with 1-hour TTL for warm data - Cache decorator with automatic tier management and fallback - Cache key generation with per-user isolation - Event monitoring system for cache statistics - Cache benchmarking utilities for performance testing - Added cache management endpoints: /api/cache/stats, /api/cache/clear, /api/cache/benchmark - Cache configuration via environment variables (CACHE_ENABLED, CACHE_L1_TTL, etc.) Backend Services: - Updated dashboard_service to use @cached decorator with request context - Added cache support to invoice_service and treasury_service - Integrated cache manager into main.py with lifespan events - Added Request parameter to service methods for cache metadata Frontend Enhancements: - New CacheStatsView.vue for real-time cache monitoring dashboard - Cache store (cacheStore.js) for state management - Updated router to include /cache-stats route - Navigation updates in DashboardHeader and HamburgerMenu - Cache stats accessible from main navigation Telegram Bot Improvements: - Enhanced formatters with YTD comparison data - Improved menu navigation and button layout - Better error handling and user feedback - Bot startup improvements with graceful shutdown Auth & Middleware: - Enhanced middleware with cache metadata injection - Improved request state handling for cache source tracking Development: - Updated start-dev.sh with better error handling - Added TELEGRAM_EMAIL_AUTH_PLAN.md documentation - Updated requirements.txt with aiosqlite for async SQLite Performance: - L1 cache provides <1ms response for hot data - L2 cache provides ~5ms response for warm data - Database queries only for cold data or cache misses - Cache hit rates tracked and displayed in real-time 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
🔐 ROA2WEB Shared Authentication System
Sistem de autentificare JWT partajat între toate aplicațiile din ecosistemul ROA2WEB, integrat cu Oracle Database și optimizat pentru aplicații FastAPI.
📋 Table of Contents
- Features
- Architecture
- Quick Start
- Components
- Integration Guide
- Security Features
- API Reference
- Testing
- Deployment
- Troubleshooting
✨ Features
Core Features
- JWT Authentication: Secure token-based authentication cu access și refresh tokens
- Oracle Database Integration: Folosește
pack_drepturi.verificautilizatorpentru autentificare - Multi-Company Support: Acces controlat la multiple firme/schemas Oracle
- Permission System: Sistem granular de permisiuni (read, write, admin, reports)
- FastAPI Integration: Dependencies și middleware native pentru FastAPI
- Rate Limiting: Protecție împotriva brute force attacks
- Caching: Cache inteligent pentru performanță optimă
Security Features
- Token Expiration: Configurabil pentru access și refresh tokens
- SQL Injection Protection: Parametri legați în toate query-urile
- Rate Limiting: Configurabil per IP și endpoint
- CORS Protection: Configurare flexibilă pentru origins
- Header Security: Security headers automate
- Token Blacklisting: Suport pentru invalidarea token-urilor (în dezvoltare)
🏗️ Architecture
ROA2WEB Authentication Flow:
┌─────────────┐ ┌──────────────┐ ┌─────────────┐ ┌──────────────┐
│ Client │───▶│ FastAPI │───▶│ JWT │───▶│ Oracle │
│ (Frontend) │ │ Application │ │ Handler │ │ Database │
└─────────────┘ └──────────────┘ └─────────────┘ └──────────────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌─────────────┐ ┌──────────────┐
│ Auth Service │ │ Middleware │ │ User Cache │
└──────────────┘ └─────────────┘ └──────────────┘
Components Overview
shared/auth/
├── jwt_handler.py # JWT token creation și validation
├── auth_service.py # Oracle database integration
├── models.py # Pydantic models pentru data validation
├── middleware.py # FastAPI middleware pentru auto-authentication
├── dependencies.py # FastAPI dependencies pentru protected routes
├── routes.py # Pre-built authentication routes
├── test_auth.py # Comprehensive test suite
├── demo_app.py # Demo application cu examples
└── README.md # Această documentație
🚀 Quick Start
1. Environment Setup
# Copy și configurează environment variables
cp .env.example .env
# Edit .env cu configurările tale
JWT_SECRET_KEY=your-super-secret-jwt-key-change-in-production
ORACLE_USER=your_oracle_username
ORACLE_PASSWORD=your_oracle_password
ORACLE_DSN=your_oracle_connection_string
2. Basic Integration
from fastapi import FastAPI, Depends
from roa2web.shared.auth import (
AuthenticationMiddleware, create_auth_router,
get_current_user, CurrentUser
)
from roa2web.shared.database import oracle_pool
app = FastAPI(title="My ROA2WEB App")
# Add authentication middleware
app.add_middleware(
AuthenticationMiddleware,
excluded_paths=["/", "/docs", "/health", "/auth/login"]
)
# Include authentication routes
auth_router = create_auth_router()
app.include_router(auth_router)
@app.on_event("startup")
async def startup():
await oracle_pool.initialize()
@app.get("/protected")
async def protected_endpoint(
current_user: CurrentUser = Depends(get_current_user)
):
return {"message": f"Hello {current_user.username}!"}
3. Test Authentication
# Start demo application
cd roa2web/shared/auth
python demo_app.py
# Open browser
open http://localhost:8000/docs
# Login prin Swagger UI cu credențialele Oracle
🧩 Components
JWT Handler (jwt_handler.py)
Gestionează crearea, validarea și refresh-ul token-urilor JWT.
from roa2web.shared.auth import jwt_handler
# Create access token
token = jwt_handler.create_access_token(
username="admin",
companies=["COMP1", "COMP2"],
permissions=["read", "write", "reports"]
)
# Verify token
token_data = jwt_handler.verify_token(token)
if token_data:
print(f"Valid token for user: {token_data.username}")
Auth Service (auth_service.py)
Integrează cu Oracle Database pentru autentificare și management utilizatori.
from roa2web.shared.auth import auth_service
# Authenticate user
success, token_response, error = await auth_service.authenticate_and_create_tokens(
"username", "password"
)
if success:
print(f"Access token: {token_response.access_token}")
else:
print(f"Authentication failed: {error}")
FastAPI Dependencies (dependencies.py)
Oferă dependencies pentru protejarea endpoint-urilor.
from fastapi import Depends
from roa2web.shared.auth import (
get_current_user, require_company_access,
require_permissions, PermissionType
)
@app.get("/admin-only")
async def admin_endpoint(
user: CurrentUser = Depends(require_permissions([PermissionType.ADMIN]))
):
return {"message": "Admin access granted"}
@app.get("/company/{company_code}/data")
async def company_data(
company_code: str,
user: CurrentUser = Depends(require_company_access(company_code))
):
return {"company": company_code, "data": "..."}
Authentication Routes (routes.py)
Pre-built routes pentru operații de autentificare.
from roa2web.shared.auth import create_auth_router
# Basic auth router
auth_router = create_auth_router()
app.include_router(auth_router)
# Auth router cu admin routes
auth_router_admin = create_auth_router(include_admin_routes=True)
app.include_router(auth_router_admin)
Available routes:
POST /auth/login- User authenticationPOST /auth/refresh- Token refreshPOST /auth/logout- User logoutGET /auth/me- Current user infoGET /auth/companies- User companiesGET /auth/status- Authentication status
🔧 Integration Guide
Full FastAPI Application
from fastapi import FastAPI, Depends, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from contextlib import asynccontextmanager
from roa2web.shared.auth import (
AuthenticationMiddleware, create_auth_router,
get_current_user, require_company_access,
CurrentUser, PermissionType
)
from roa2web.shared.database import oracle_pool
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup
await oracle_pool.initialize()
yield
# Shutdown
await oracle_pool.close_pool()
app = FastAPI(
title="ROA2WEB Application",
lifespan=lifespan
)
# CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Authentication
app.add_middleware(
AuthenticationMiddleware,
excluded_paths=["/", "/docs", "/health"],
rate_limit_paths=["/auth/login"]
)
# Routes
auth_router = create_auth_router()
app.include_router(auth_router)
# Protected endpoints
@app.get("/")
async def public_endpoint():
return {"message": "Public endpoint"}
@app.get("/me")
async def my_info(current_user: CurrentUser = Depends(get_current_user)):
return current_user
@app.get("/company/{company_code}/invoices")
async def get_invoices(
company_code: str,
current_user: CurrentUser = Depends(require_company_access(company_code))
):
# Business logic here
return {"company": company_code, "invoices": []}
Custom Permissions
from roa2web.shared.auth import require_permissions, PermissionType
# Define custom permissions
class CustomPermissionType(str, Enum):
INVOICE_READ = "invoice_read"
INVOICE_WRITE = "invoice_write"
REPORT_EXPORT = "report_export"
# Use in endpoints
@app.get("/invoices")
async def get_invoices(
user: CurrentUser = Depends(require_permissions([CustomPermissionType.INVOICE_READ]))
):
return {"invoices": []}
Company-Specific Endpoints
from fastapi import Header
from roa2web.shared.auth import get_current_company_from_header
@app.get("/current-company-data")
async def get_current_company_data(
company_code: str = Depends(get_current_company_from_header),
current_user: CurrentUser = Depends(get_current_user)
):
# company_code is automatically extracted from X-Company-Code header
# and validated against user's accessible companies
return {"company": company_code, "data": "..."}
🔒 Security Features
JWT Configuration
# Environment variables
JWT_SECRET_KEY=your-super-secret-jwt-key-change-in-production
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7
Rate Limiting
from roa2web.shared.auth import RateLimiter, AuthenticationMiddleware
# Custom rate limiter
custom_rate_limiter = RateLimiter(
max_requests=10, # 10 requests
time_window=60 # per minute
)
app.add_middleware(
AuthenticationMiddleware,
rate_limit_paths=["/auth/login", "/auth/register"],
rate_limiter=custom_rate_limiter
)
Security Headers
Middleware-ul adaugă automat header-e de securitate:
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
📚 API Reference
JWT Handler Methods
class JWTHandler:
def create_access_token(username, companies, user_id=None, permissions=None) -> str
def create_refresh_token(username, user_id=None) -> str
def verify_token(token) -> Optional[TokenData]
def refresh_access_token(refresh_token, companies, permissions=None) -> Optional[str]
def create_token_response(username, companies, ...) -> TokenResponse
Auth Service Methods
class UserAuthService:
async def verify_user_credentials(username, password) -> bool
async def get_user_companies(username) -> List[str]
async def get_user_permissions(username, company) -> List[str]
async def authenticate_and_create_tokens(username, password) -> Tuple[bool, TokenResponse, str]
async def validate_user_company_access(username, company) -> bool
FastAPI Dependencies
# User dependencies
get_current_user() -> CurrentUser
get_optional_user() -> Optional[CurrentUser]
# Permission dependencies
require_permissions(permissions: List[PermissionType])
require_company_access(company_code: str)
require_company_and_permissions(company_code: str, permissions: List[PermissionType])
# Utility dependencies
get_current_company_from_header() -> str
🧪 Testing
Running Tests
# Install test dependencies
pip install pytest pytest-asyncio httpx
# Run all tests
cd roa2web/shared/auth
python -m pytest test_auth.py -v
# Run specific test categories
python -m pytest test_auth.py::TestJWTHandler -v
python -m pytest test_auth.py::TestUserAuthService -v
python -m pytest test_auth.py::TestSecurityFeatures -v
# Run with coverage
python -m pytest test_auth.py --cov=. --cov-report=html
Test Categories
- Unit Tests: JWT operations, auth service methods
- Integration Tests: Database integration, full auth flow
- Security Tests: Token tampering, SQL injection, rate limiting
- Performance Tests: Token creation/verification speed
Demo Application
# Start demo app for manual testing
cd roa2web/shared/auth
python demo_app.py
# Available demo endpoints:
# http://localhost:8000/ - Home page cu documentație
# http://localhost:8000/docs - Swagger UI pentru testare
# http://localhost:8000/demo/* - Various demo endpoints
🚀 Deployment
Production Configuration
# Strong JWT secret key
JWT_SECRET_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
# Shorter token expiration
ACCESS_TOKEN_EXPIRE_MINUTES=15
REFRESH_TOKEN_EXPIRE_DAYS=1
# Strict rate limiting
RATE_LIMIT_MAX_REQUESTS=3
RATE_LIMIT_TIME_WINDOW=300
# Secure headers
SECURE_SSL_REDIRECT=true
SESSION_COOKIE_SECURE=true
Docker Integration
# În Dockerfile-ul aplicației
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
# Environment pentru container
ENV JWT_SECRET_KEY=${JWT_SECRET_KEY}
ENV ORACLE_USER=${ORACLE_USER}
ENV ORACLE_PASSWORD=${ORACLE_PASSWORD}
ENV ORACLE_DSN=${ORACLE_DSN}
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Health Checks
@app.get("/health")
async def health_check():
# Test database connection
try:
async with oracle_pool.get_connection() as conn:
with conn.cursor() as cursor:
cursor.execute("SELECT 1 FROM DUAL")
db_status = "healthy"
except Exception as e:
db_status = f"error: {str(e)}"
return {
"status": "healthy" if db_status == "healthy" else "degraded",
"database": db_status,
"jwt": "functional",
"timestamp": datetime.now().isoformat()
}
🔧 Troubleshooting
Common Issues
1. "Invalid token" errors
# Check JWT secret key consistency
print(f"JWT Secret: {os.getenv('JWT_SECRET_KEY')}")
# Verify token creation and validation
token = jwt_handler.create_access_token("test", ["COMP1"])
token_data = jwt_handler.verify_token(token)
print(f"Token valid: {token_data is not None}")
2. Database connection errors
# Test Oracle connection
try:
async with oracle_pool.get_connection() as conn:
with conn.cursor() as cursor:
cursor.execute("SELECT 1 FROM DUAL")
result = cursor.fetchone()
print("Database connection: OK")
except Exception as e:
print(f"Database error: {e}")
3. Rate limiting issues
# Check rate limiter stats
from roa2web.shared.auth import default_rate_limiter
client_ip = "192.168.1.1"
allowed = default_rate_limiter.is_allowed(client_ip)
reset_time = default_rate_limiter.get_reset_time(client_ip)
print(f"IP {client_ip} allowed: {allowed}, resets at: {reset_time}")
4. Permission denied errors
# Check user companies and permissions
companies = await auth_service.get_user_companies("username")
permissions = await auth_service.get_user_permissions("username", "COMP1")
print(f"User companies: {companies}")
print(f"User permissions: {permissions}")
Debug Mode
import logging
# Enable debug logging
logging.basicConfig(level=logging.DEBUG)
# Specific loggers
logging.getLogger("roa2web.shared.auth").setLevel(logging.DEBUG)
Environment Validation
from roa2web.shared.utils.config import shared_config
# Validate configuration
print(f"Oracle User: {shared_config.oracle_user}")
print(f"JWT Secret set: {'***' if shared_config.jwt_secret_key else 'NOT SET'}")
print(f"Token expiry: {shared_config.access_token_expire_minutes} minutes")
📈 Performance Optimization
Caching
# Cache configuration
AUTH_CACHE_TTL_MINUTES=15 # User data cache TTL
# Monitor cache performance
stats = auth_service.get_cache_stats()
print(f"Cache hit ratio: {stats['cache_hit_ratio']:.2%}")
Connection Pooling
# Oracle pool configuration
DB_MIN_CONNECTIONS=2
DB_MAX_CONNECTIONS=10
DB_CONNECTION_INCREMENT=1
Token Optimization
# Optimize token size by limiting payload
token = jwt_handler.create_access_token(
username="user",
companies=["COMP1"], # Limit companies in token
permissions=["read"] # Essential permissions only
)
🤝 Contributing
Pentru contribuții la sistemul de autentificare:
- Fork repository-ul și creează o ramură pentru feature
- Implementează schimbările cu tests comprehensive
- Rulează toate testele pentru a verifica compatibilitatea
- Actualizează documentația dacă este necesar
- Creează Pull Request cu descriere detaliată
Development Setup
# Clone repository
git clone [repository-url]
cd roa-flask
# Setup environment
python -m venv venv
source venv/bin/activate # Linux/Mac
# or
venv\Scripts\activate # Windows
pip install -r requirements.txt
# Run tests
cd roa2web/shared/auth
python -m pytest test_auth.py -v
📜 License
Acest sistem de autentificare face parte din proiectul ROA2WEB și este disponibil sub aceleași condiții de licențiere ca și proiectul principal.
ROA2WEB Authentication System v1.0.0
Secure, scalable, Oracle-integrated authentication pentru aplicații moderne