Tahasaif3 commited on
Commit
ae84dd9
·
verified ·
1 Parent(s): 1aa61fd

Update src/utils/security.py

Browse files
Files changed (1) hide show
  1. src/utils/security.py +23 -38
src/utils/security.py CHANGED
@@ -1,72 +1,57 @@
1
  from passlib.context import CryptContext
2
  from datetime import datetime, timedelta
3
- from typing import Optional
4
  import uuid
5
  from jose import JWTError, jwt
6
  from ..config import settings
7
 
 
8
  pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
9
 
10
 
11
- # 🔐 Normalize password to avoid bcrypt 72-byte crash
12
- def _normalize_password(password: str) -> str:
13
- return password.encode("utf-8")[:72].decode("utf-8", errors="ignore")
14
-
15
-
16
  def hash_password(password: str) -> str:
17
- """Hash a password using bcrypt (HF-safe)."""
18
- return pwd_context.hash(_normalize_password(password))
19
 
20
 
21
  def verify_password(plain_password: str, hashed_password: str) -> bool:
22
- """Verify a plain password against its hash (HF-safe)."""
23
- return pwd_context.verify(
24
- _normalize_password(plain_password),
25
- hashed_password
26
- )
27
 
28
 
29
  def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
 
30
  to_encode = data.copy()
31
 
32
  if expires_delta:
33
  expire = datetime.utcnow() + expires_delta
34
  else:
 
35
  expire = datetime.utcnow() + timedelta(days=settings.ACCESS_TOKEN_EXPIRE_DAYS)
36
 
37
- to_encode.update({
38
- "exp": expire,
39
- "iat": datetime.utcnow()
40
- })
41
 
42
- return jwt.encode(
43
- to_encode,
44
- settings.JWT_SECRET_KEY,
45
- algorithm=settings.JWT_ALGORITHM
46
- )
47
 
48
 
49
  def verify_token(token: str) -> Optional[dict]:
 
50
  try:
51
- return jwt.decode(
52
- token,
53
- settings.JWT_SECRET_KEY,
54
- algorithms=[settings.JWT_ALGORITHM]
55
- )
56
  except JWTError:
57
  return None
58
 
59
 
60
  def verify_user_id_from_token(token: str) -> Optional[uuid.UUID]:
 
61
  payload = verify_token(token)
62
- if not payload:
63
- return None
64
-
65
- user_id = payload.get("sub")
66
- if not user_id:
67
- return None
68
-
69
- try:
70
- return uuid.UUID(user_id)
71
- except ValueError:
72
- return None
 
1
  from passlib.context import CryptContext
2
  from datetime import datetime, timedelta
3
+ from typing import Optional, Union
4
  import uuid
5
  from jose import JWTError, jwt
6
  from ..config import settings
7
 
8
+ # Password hashing context
9
  pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
10
 
11
 
 
 
 
 
 
12
  def hash_password(password: str) -> str:
13
+ """Hash a password using bcrypt."""
14
+ return pwd_context.hash(password)
15
 
16
 
17
  def verify_password(plain_password: str, hashed_password: str) -> bool:
18
+ """Verify a plain password against its hash."""
19
+ return pwd_context.verify(plain_password, hashed_password)
 
 
 
20
 
21
 
22
  def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
23
+ """Create a JWT access token."""
24
  to_encode = data.copy()
25
 
26
  if expires_delta:
27
  expire = datetime.utcnow() + expires_delta
28
  else:
29
+ # Default to 7 days if no expiration is provided
30
  expire = datetime.utcnow() + timedelta(days=settings.ACCESS_TOKEN_EXPIRE_DAYS)
31
 
32
+ to_encode.update({"exp": expire, "iat": datetime.utcnow()})
 
 
 
33
 
34
+ encoded_jwt = jwt.encode(to_encode, settings.JWT_SECRET_KEY, algorithm=settings.JWT_ALGORITHM)
35
+ return encoded_jwt
 
 
 
36
 
37
 
38
  def verify_token(token: str) -> Optional[dict]:
39
+ """Verify a JWT token and return the payload if valid."""
40
  try:
41
+ payload = jwt.decode(token, settings.JWT_SECRET_KEY, algorithms=[settings.JWT_ALGORITHM])
42
+ return payload
 
 
 
43
  except JWTError:
44
  return None
45
 
46
 
47
  def verify_user_id_from_token(token: str) -> Optional[uuid.UUID]:
48
+ """Extract user_id from JWT token."""
49
  payload = verify_token(token)
50
+ if payload:
51
+ user_id_str = payload.get("sub")
52
+ if user_id_str:
53
+ try:
54
+ return uuid.UUID(user_id_str)
55
+ except ValueError:
56
+ return None
57
+ return None