fix: replace passlib with bcrypt directly (passlib incompatible with bcrypt>=4)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8edf31edff
commit
ca40d251d6
2 changed files with 6 additions and 7 deletions
|
|
@ -6,6 +6,6 @@ alembic==1.14.0
|
|||
pydantic[email]==2.10.3
|
||||
pydantic-settings==2.6.1
|
||||
python-jose[cryptography]==3.3.0
|
||||
passlib[bcrypt]==1.7.4
|
||||
bcrypt==4.2.1
|
||||
python-multipart==0.0.20
|
||||
httpx==0.28.1
|
||||
|
|
|
|||
11
src/auth.py
11
src/auth.py
|
|
@ -2,10 +2,10 @@ import secrets
|
|||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Annotated
|
||||
|
||||
import bcrypt
|
||||
from fastapi import Depends, HTTPException, Security, status
|
||||
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||
from jose import JWTError, jwt
|
||||
from passlib.context import CryptContext
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
|
|
@ -13,7 +13,6 @@ from src.config import settings
|
|||
from src.database import get_db
|
||||
from src.models import ApiKey, User
|
||||
|
||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||
bearer_scheme = HTTPBearer(auto_error=False)
|
||||
|
||||
ALGORITHM = "HS256"
|
||||
|
|
@ -22,11 +21,11 @@ ALGORITHM = "HS256"
|
|||
# ── Password ──────────────────────────────────────────────────────────────────
|
||||
|
||||
def hash_password(password: str) -> str:
|
||||
return pwd_context.hash(password)
|
||||
return bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()
|
||||
|
||||
|
||||
def verify_password(plain: str, hashed: str) -> bool:
|
||||
return pwd_context.verify(plain, hashed)
|
||||
return bcrypt.checkpw(plain.encode(), hashed.encode())
|
||||
|
||||
|
||||
# ── JWT ───────────────────────────────────────────────────────────────────────
|
||||
|
|
@ -60,7 +59,7 @@ def generate_api_key() -> tuple[str, str, str]:
|
|||
"""Returns (raw_key, prefix, hash). raw_key shown once to user."""
|
||||
raw = "cc_" + secrets.token_urlsafe(32)
|
||||
prefix = raw[:11] # "cc_" + 8 chars
|
||||
return raw, prefix, pwd_context.hash(raw)
|
||||
return raw, prefix, hash_password(raw)
|
||||
|
||||
|
||||
async def verify_api_key(raw_key: str, db: AsyncSession) -> User | None:
|
||||
|
|
@ -75,7 +74,7 @@ async def verify_api_key(raw_key: str, db: AsyncSession) -> User | None:
|
|||
)
|
||||
keys = result.scalars().all()
|
||||
for key in keys:
|
||||
if pwd_context.verify(raw_key, key.key_hash):
|
||||
if verify_password(raw_key, key.key_hash):
|
||||
key.last_used_at = datetime.now(timezone.utc)
|
||||
await db.commit()
|
||||
return key.user
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue