diff --git a/backend/app/api/v1/auth.py b/backend/app/api/v1/auth.py index c3523b4..8782989 100644 --- a/backend/app/api/v1/auth.py +++ b/backend/app/api/v1/auth.py @@ -159,17 +159,35 @@ async def login( ): """Login user and return access tokens""" + logger.info(f"Login attempt for email: {user_data.email}") + start_time = datetime.utcnow() + # Get user by email stmt = select(User).where(User.email == user_data.email) result = await db.execute(stmt) user = result.scalar_one_or_none() - if not user or not verify_password(user_data.password, user.hashed_password): + if not user: + logger.warning(f"User not found: {user_data.email}") raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect email or password" ) + logger.info(f"User found, starting password verification...") + verify_start = datetime.utcnow() + + if not verify_password(user_data.password, user.hashed_password): + verify_end = datetime.utcnow() + logger.warning(f"Password verification failed. Time taken: {(verify_end - verify_start).total_seconds()} seconds") + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Incorrect email or password" + ) + + verify_end = datetime.utcnow() + logger.info(f"Password verification successful. Time taken: {(verify_end - verify_start).total_seconds()} seconds") + if not user.is_active: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 15f832d..15cbbd9 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -34,6 +34,7 @@ class Settings(BaseSettings): REFRESH_TOKEN_EXPIRE_MINUTES: int = int(os.getenv("REFRESH_TOKEN_EXPIRE_MINUTES", "10080")) # 7 days SESSION_EXPIRE_MINUTES: int = int(os.getenv("SESSION_EXPIRE_MINUTES", "1440")) # 24 hours API_KEY_PREFIX: str = os.getenv("API_KEY_PREFIX", "en_") + BCRYPT_ROUNDS: int = int(os.getenv("BCRYPT_ROUNDS", "6")) # Bcrypt work factor - lower for production performance # Admin user provisioning (used only on first startup) ADMIN_EMAIL: str = os.getenv("ADMIN_EMAIL") diff --git a/backend/app/core/security.py b/backend/app/core/security.py index f9d7e6d..6611fe0 100644 --- a/backend/app/core/security.py +++ b/backend/app/core/security.py @@ -20,7 +20,12 @@ from app.utils.exceptions import AuthenticationError, AuthorizationError logger = logging.getLogger(__name__) # Password hashing -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +# Use a lower work factor for better performance in production +pwd_context = CryptContext( + schemes=["bcrypt"], + deprecated="auto", + bcrypt__rounds=settings.BCRYPT_ROUNDS +) # JWT token handling security = HTTPBearer() diff --git a/nginx/nginx.conf b/nginx/nginx.conf index 3d30567..0430ed7 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -13,6 +13,10 @@ http { proxy_read_timeout 600; send_timeout 600; + # FastAPI timeout handling + proxy_read_timeout 300s; + proxy_send_timeout 300s; + upstream backend { server enclava-backend:8000; }