Fix bcrypt incompatibility: replace passlib with direct bcrypt 5.x API

This commit is contained in:
Erik 2026-04-10 19:55:55 +02:00
parent b09169ade2
commit 6e090eb4dc
3 changed files with 7 additions and 7 deletions

View file

@ -17,7 +17,7 @@ RUN python -m pip install --upgrade pip && \
alembic \ alembic \
psycopg2-binary \ psycopg2-binary \
httpx \ httpx \
passlib[bcrypt] \ bcrypt \
itsdangerous itsdangerous
## Copy application source code and migration scripts into container ## Copy application source code and migration scripts into container

View file

@ -11,7 +11,7 @@ from databases import Database
from sqlalchemy import MetaData, Table, Column, Integer, String, Float, DateTime, text from sqlalchemy import MetaData, Table, Column, Integer, String, Float, DateTime, text
from sqlalchemy import Index, BigInteger, JSON, Boolean, UniqueConstraint from sqlalchemy import Index, BigInteger, JSON, Boolean, UniqueConstraint
from sqlalchemy.sql import func from sqlalchemy.sql import func
from passlib.hash import bcrypt import bcrypt as _bcrypt
# Environment: Postgres/TimescaleDB connection URL # Environment: Postgres/TimescaleDB connection URL
DATABASE_URL = os.getenv( DATABASE_URL = os.getenv(
@ -364,7 +364,7 @@ async def seed_users():
}, },
] ]
for u in default_users: for u in default_users:
pw_hash = bcrypt.hash(u["password"]) pw_hash = _bcrypt.hashpw(u["password"].encode(), _bcrypt.gensalt()).decode()
await database.execute( await database.execute(
"INSERT INTO users (username, password_hash, is_admin) VALUES (:username, :password_hash, :is_admin)", "INSERT INTO users (username, password_hash, is_admin) VALUES (:username, :password_hash, :is_admin)",
{ {

View file

@ -42,7 +42,7 @@ from pydantic import BaseModel
from typing import Optional from typing import Optional
from starlette.middleware.base import BaseHTTPMiddleware from starlette.middleware.base import BaseHTTPMiddleware
import httpx import httpx
from passlib.hash import bcrypt import bcrypt as _bcrypt
from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired
# Async database support # Async database support
@ -1314,7 +1314,7 @@ async def login(request: Request):
"SELECT id, username, password_hash, is_admin FROM users WHERE LOWER(username) = :username", "SELECT id, username, password_hash, is_admin FROM users WHERE LOWER(username) = :username",
{"username": username}, {"username": username},
) )
if not row or not bcrypt.verify(password, row["password_hash"]): if not row or not _bcrypt.checkpw(password.encode(), row["password_hash"].encode()):
raise HTTPException(status_code=401, detail="Invalid username or password") raise HTTPException(status_code=401, detail="Invalid username or password")
token = create_session_cookie(row["username"], row["is_admin"]) token = create_session_cookie(row["username"], row["is_admin"])
@ -1401,7 +1401,7 @@ async def create_user(request: Request):
if existing: if existing:
raise HTTPException(status_code=409, detail="Username already exists") raise HTTPException(status_code=409, detail="Username already exists")
pw_hash = bcrypt.hash(password) pw_hash = _bcrypt.hashpw(password.encode(), _bcrypt.gensalt()).decode()
await database.execute( await database.execute(
"INSERT INTO users (username, password_hash, is_admin) VALUES (:username, :password_hash, :is_admin)", "INSERT INTO users (username, password_hash, is_admin) VALUES (:username, :password_hash, :is_admin)",
{"username": username, "password_hash": pw_hash, "is_admin": is_admin}, {"username": username, "password_hash": pw_hash, "is_admin": is_admin},
@ -1442,7 +1442,7 @@ async def update_user(user_id: int, request: Request):
raise HTTPException( raise HTTPException(
status_code=400, detail="Password must be at least 4 characters" status_code=400, detail="Password must be at least 4 characters"
) )
pw_hash = bcrypt.hash(password) pw_hash = _bcrypt.hashpw(password.encode(), _bcrypt.gensalt()).decode()
await database.execute( await database.execute(
"UPDATE users SET password_hash = :pw WHERE id = :id", "UPDATE users SET password_hash = :pw WHERE id = :id",
{"pw": pw_hash, "id": user_id}, {"pw": pw_hash, "id": user_id},