diff --git a/Dockerfile b/Dockerfile index e8a80c27..5505f9e0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ RUN python -m pip install --upgrade pip && \ alembic \ psycopg2-binary \ httpx \ - passlib[bcrypt] \ + bcrypt \ itsdangerous ## Copy application source code and migration scripts into container diff --git a/db_async.py b/db_async.py index d265036b..d79c88ce 100644 --- a/db_async.py +++ b/db_async.py @@ -11,7 +11,7 @@ from databases import Database from sqlalchemy import MetaData, Table, Column, Integer, String, Float, DateTime, text from sqlalchemy import Index, BigInteger, JSON, Boolean, UniqueConstraint from sqlalchemy.sql import func -from passlib.hash import bcrypt +import bcrypt as _bcrypt # Environment: Postgres/TimescaleDB connection URL DATABASE_URL = os.getenv( @@ -364,7 +364,7 @@ async def seed_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( "INSERT INTO users (username, password_hash, is_admin) VALUES (:username, :password_hash, :is_admin)", { diff --git a/main.py b/main.py index 5f451015..b41d035f 100644 --- a/main.py +++ b/main.py @@ -42,7 +42,7 @@ from pydantic import BaseModel from typing import Optional from starlette.middleware.base import BaseHTTPMiddleware import httpx -from passlib.hash import bcrypt +import bcrypt as _bcrypt from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired # 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", {"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") token = create_session_cookie(row["username"], row["is_admin"]) @@ -1401,7 +1401,7 @@ async def create_user(request: Request): if existing: 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( "INSERT INTO users (username, password_hash, is_admin) VALUES (:username, :password_hash, :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( 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( "UPDATE users SET password_hash = :pw WHERE id = :id", {"pw": pw_hash, "id": user_id},