diff --git a/pyproject.toml b/pyproject.toml index c9b93cc..239ff5e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ dependencies = [ "anyio>=4.4.0", "fastapi>=0.111.0", "uvicorn[standard]>=0.30.0", - "passlib[bcrypt]>=1.7.4", + "bcrypt>=4.0.0", "email-validator>=2.0.0", "cryptography>=42.0.0", ] diff --git a/src/mt_odoo_mcp/auth/crypto.py b/src/mt_odoo_mcp/auth/crypto.py index d2bbce0..5a70350 100644 --- a/src/mt_odoo_mcp/auth/crypto.py +++ b/src/mt_odoo_mcp/auth/crypto.py @@ -1,19 +1,17 @@ """Password hashing, API key generation, and Fernet encryption for credentials.""" from __future__ import annotations import secrets -from passlib.context import CryptContext +import bcrypt from cryptography.fernet import Fernet from ..config import settings -_pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") - def hash_password(plain: str) -> str: - return _pwd_context.hash(plain) + return bcrypt.hashpw(plain.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()) def generate_api_key() -> tuple[str, str, str]: @@ -21,17 +19,17 @@ def generate_api_key() -> tuple[str, str, str]: full_key is shown to the user exactly once. key_hash is stored in the DB. - key_prefix (first 8 chars) is stored for display. + key_prefix (first 12 chars) is stored for display/lookup. """ raw = secrets.token_hex(32) full_key = f"mtom_{raw}" - key_hash = _pwd_context.hash(full_key) + key_hash = bcrypt.hashpw(full_key.encode(), bcrypt.gensalt()).decode() key_prefix = full_key[:12] return full_key, key_hash, key_prefix def verify_api_key(plain: str, hashed: str) -> bool: - return _pwd_context.verify(plain, hashed) + return bcrypt.checkpw(plain.encode(), hashed.encode()) def _fernet() -> Fernet: