Skip to content

Commit 7382217

Browse files
server-side password strength validation
1 parent 8775dd3 commit 7382217

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

routers/authentication.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from utils.db import User
99
from utils.auth import (
1010
get_session,
11+
validate_password_strength,
1112
get_user_from_reset_token,
1213
oauth2_scheme_cookie,
1314
get_password_hash,
@@ -60,6 +61,10 @@ async def register(
6061
if password != confirm_password:
6162
raise HTTPException(status_code=400, detail="Passwords do not match")
6263

64+
if not validate_password_strength(password):
65+
raise HTTPException(
66+
status_code=400, detail="Password does not satisfy the security policy")
67+
6368
user = UserCreate(name=name, email=email, password=password)
6469
db_user = session.exec(select(User).where(
6570
User.email == user.email)).first()
@@ -196,6 +201,10 @@ def reset_password(
196201
if new_password != confirm_new_password:
197202
raise HTTPException(status_code=400, detail="Passwords do not match")
198203

204+
if not validate_password_strength(new_password):
205+
raise HTTPException(
206+
status_code=400, detail="Password does not satisfy the security policy")
207+
199208
authorized_user, reset_token = get_user_from_reset_token(
200209
email, token, session)
201210

utils/auth.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# utils.py
22
import os
3+
import re
34
import jwt
45
import uuid
56
import logging
@@ -33,6 +34,19 @@ def oauth2_scheme_cookie(
3334
return access_token, refresh_token
3435

3536

37+
def validate_password_strength(password: str) -> bool:
38+
"""
39+
Validate the password to ensure it meets the required criteria:
40+
- At least one number
41+
- At least one uppercase and one lowercase letter
42+
- At least one special character
43+
- At least 8 characters long
44+
"""
45+
pattern = re.compile(
46+
r"(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}")
47+
return bool(pattern.match(password))
48+
49+
3650
def get_password_hash(password: str) -> str:
3751
return pwd_context.hash(password)
3852

0 commit comments

Comments
 (0)