bcrypt fix
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-09-26 07:07:48 +09:00
parent 31c1644ec2
commit e5aa933cf9
5 changed files with 69 additions and 11 deletions

0
-H Normal file
View File

1
-d Normal file
View File

@@ -0,0 +1 @@
{"detail":[{"type":"missing","loc":["body"],"msg":"Field required","input":null,"url":"https://errors.pydantic.dev/2.4/v/missing"}]}

43
deploy_bcrypt_fix.sh Executable file
View File

@@ -0,0 +1,43 @@
#!/bin/bash
# Deploy bcrypt compatibility fix to production server
# Server: 192.168.0.103
echo "Deploying bcrypt compatibility fix to production server..."
# Copy updated files to server
echo "Copying requirements.txt..."
scp requirements.txt trevor@192.168.0.103:/home/trevor/dev/chat/
echo "Copying shared/auth.py..."
scp shared/auth.py trevor@192.168.0.103:/home/trevor/dev/chat/shared/
echo "Copying user service schemas..."
scp services/user_service/schemas.py trevor@192.168.0.103:/home/trevor/dev/chat/services/user_service/
echo "Connecting to server to update dependencies..."
ssh trevor@192.168.0.103 << 'EOF'
cd /home/trevor/dev/chat
# Stop services
echo "Stopping services..."
./stop_services.sh
# Update Python packages
echo "Updating bcrypt to version 4.0.1..."
pip install --upgrade bcrypt==4.0.1
pip install --upgrade passlib[bcrypt]==1.7.4
# Verify bcrypt installation
echo "Verifying bcrypt installation..."
python3 -c "import bcrypt; print(f'bcrypt version: {bcrypt.__version__}')"
# Restart services
echo "Restarting services..."
./start_services_no_docker.sh
echo "Deployment complete. Services are starting..."
EOF
echo "Deployment script completed."
echo "Check server logs at 192.168.0.103 to verify bcrypt compatibility fix."

View File

@@ -12,6 +12,7 @@ pydantic-settings==2.0.3
python-jose[cryptography]==3.3.0 python-jose[cryptography]==3.3.0
PyJWT==2.8.0 PyJWT==2.8.0
passlib[bcrypt]==1.7.4 passlib[bcrypt]==1.7.4
bcrypt==4.0.1
python-multipart==0.0.6 python-multipart==0.0.6
httpx==0.25.1 httpx==0.25.1
aiofiles==23.2.1 aiofiles==23.2.1

View File

@@ -3,6 +3,7 @@ Authentication utilities for all services.
This module provides common authentication functionality to avoid circular imports. This module provides common authentication functionality to avoid circular imports.
""" """
import logging
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Optional from typing import Optional
@@ -14,6 +15,9 @@ from passlib.context import CryptContext
from shared.config import settings from shared.config import settings
# Suppress bcrypt version warnings
logging.getLogger("passlib").setLevel(logging.ERROR)
# Password hashing # Password hashing
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@@ -22,21 +26,30 @@ security = HTTPBearer()
def verify_password(plain_password: str, hashed_password: str) -> bool: def verify_password(plain_password: str, hashed_password: str) -> bool:
"""Verify password against hash. Apply same truncation as used during hashing.""" """Verify a password against its hash. Handle bcrypt compatibility issues."""
# Apply same truncation logic as during hashing try:
# Truncate password to 72 bytes for consistency
password_bytes = plain_password.encode('utf-8') password_bytes = plain_password.encode('utf-8')
if len(password_bytes) > 72: if len(password_bytes) > 72:
plain_password = password_bytes[:72].decode('utf-8', errors='ignore') plain_password = password_bytes[:72].decode('utf-8', errors='ignore')
return pwd_context.verify(plain_password, hashed_password) return pwd_context.verify(plain_password, hashed_password)
except Exception as e:
logging.error(f"Error verifying password: {e}")
return False
def get_password_hash(password: str) -> str: def get_password_hash(password: str) -> str:
"""Get password hash. Truncate password to 72 bytes if necessary for bcrypt compatibility.""" """Get password hash. Truncate password to 72 bytes if necessary for bcrypt compatibility."""
try:
# bcrypt has a 72-byte limit, so truncate if necessary # bcrypt has a 72-byte limit, so truncate if necessary
password_bytes = password.encode('utf-8') password_bytes = password.encode('utf-8')
if len(password_bytes) > 72: if len(password_bytes) > 72:
password = password_bytes[:72].decode('utf-8', errors='ignore') password = password_bytes[:72].decode('utf-8', errors='ignore')
return pwd_context.hash(password) return pwd_context.hash(password)
except Exception as e:
# Handle bcrypt compatibility issues
logging.error(f"Error hashing password: {e}")
raise ValueError("Password hashing failed. Please use a shorter password.")
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str: def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str: