Skip to content

Commit 326c590

Browse files
Use bcrypt instead of passlib since passlib is unmaintained
1 parent 7382217 commit 326c590

File tree

3 files changed

+18
-28
lines changed

3 files changed

+18
-28
lines changed

poetry.lock

Lines changed: 2 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ python = "^3.12"
1111
sqlmodel = "^0.0.22"
1212
mypy = "^1.11.2"
1313
fastapi = "^0.114.1"
14-
passlib = {extras = ["bcrypt"], version = "^1.7.4"}
1514
pyjwt = "^2.9.0"
1615
jinja2 = "^3.1.4"
1716
uvicorn = "^0.30.6"
@@ -20,6 +19,7 @@ pydantic = {extras = ["email"], version = "^2.9.1"}
2019
python-multipart = "^0.0.9"
2120
python-dotenv = "^1.0.1"
2221
resend = "^2.4.0"
22+
bcrypt = "^4.2.0"
2323

2424

2525
[build-system]

utils/auth.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import resend
88
from dotenv import load_dotenv
99
from sqlmodel import Session, select
10-
from passlib.context import CryptContext
10+
from bcrypt import gensalt, hashpw, checkpw
1111
from datetime import UTC, datetime, timedelta
1212
from typing import Optional
1313
from fastapi import Depends, Cookie, HTTPException, status
@@ -19,7 +19,6 @@
1919

2020
# --- AUTH ---
2121

22-
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
2322
SECRET_KEY = os.getenv("SECRET_KEY")
2423
ALGORITHM = "HS256"
2524
ACCESS_TOKEN_EXPIRE_MINUTES = 30
@@ -43,16 +42,27 @@ def validate_password_strength(password: str) -> bool:
4342
- At least 8 characters long
4443
"""
4544
pattern = re.compile(
46-
r"(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}")
45+
r"(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@$!%*?&{}<>.,\\'#\-_=+\(\)\[\]:;|~])[A-Za-z\d@$!%*?&{}<>.,\\'#\-_=+\(\)\[\]:;|~]{8,}")
4746
return bool(pattern.match(password))
4847

4948

5049
def get_password_hash(password: str) -> str:
51-
return pwd_context.hash(password)
50+
"""
51+
Hash a password using bcrypt with a random salt
52+
"""
53+
# Convert the password to bytes and generate the hash
54+
password_bytes = password.encode('utf-8')
55+
salt = gensalt()
56+
return hashpw(password_bytes, salt).decode('utf-8')
5257

5358

5459
def verify_password(plain_password: str, hashed_password: str) -> bool:
55-
return pwd_context.verify(plain_password, hashed_password)
60+
"""
61+
Verify a password against a bcrypt hash
62+
"""
63+
password_bytes = plain_password.encode('utf-8')
64+
hashed_bytes = hashed_password.encode('utf-8')
65+
return checkpw(password_bytes, hashed_bytes)
5666

5767

5868
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:

0 commit comments

Comments
 (0)