Ali2206 commited on
Commit
99eba87
·
verified ·
1 Parent(s): bd65e6d

Update core/security.py

Browse files
Files changed (1) hide show
  1. core/security.py +31 -24
core/security.py CHANGED
@@ -1,61 +1,68 @@
1
  from datetime import datetime, timedelta
2
  from passlib.context import CryptContext
3
  from jose import jwt, JWTError
4
- from fastapi import Depends, HTTPException, status
5
  from fastapi.security import OAuth2PasswordBearer
6
  from core.config import SECRET_KEY, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES
7
  from db.mongo import users_collection
8
  import logging
9
- from fastapi import Request
10
 
11
  logger = logging.getLogger(__name__)
12
 
13
  # OAuth2 setup
14
  oauth2_scheme = OAuth2PasswordBearer(
15
- tokenUrl="/auth/login", # Correct path
16
  scheme_name="JWT"
17
  )
 
18
  # Password hashing context
19
  pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
20
 
21
- # Hash a plain password
22
  def hash_password(password: str) -> str:
23
  return pwd_context.hash(password)
24
 
25
- # Verify a plain password against the hash
26
  def verify_password(plain: str, hashed: str) -> bool:
27
  return pwd_context.verify(plain, hashed)
28
 
29
- # Create a JWT access token
30
- def create_access_token(data: dict, expires_delta: timedelta = None):
31
  to_encode = data.copy()
32
  expire = datetime.utcnow() + (expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
33
  to_encode.update({"exp": expire})
34
  return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
35
 
36
- # Get the current user from the JWT token
37
  async def get_current_user(request: Request, token: str = Depends(oauth2_scheme)):
38
- print("🧪 Request headers:", dict(request.headers))
39
- print("🔐 Raw token received:", token)
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- if not token:
42
- print(" No token received")
43
- raise HTTPException(status_code=401, detail="No token provided")
44
 
45
- try:
46
  payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
47
- print("🧠 Token payload:", payload)
 
 
 
48
 
49
- email = payload.get("sub")
50
- if not email:
51
- raise HTTPException(status_code=401, detail="Invalid token: missing subject")
52
  except JWTError as e:
53
- print("JWT decode error:", str(e))
54
- raise HTTPException(status_code=401, detail="Could not validate token")
55
 
56
  user = await users_collection.find_one({"email": email})
57
- if not user:
58
- raise HTTPException(status_code=404, detail="User not found")
 
59
 
60
- print("✅ Authenticated user:", user["email"])
61
- return user
 
1
  from datetime import datetime, timedelta
2
  from passlib.context import CryptContext
3
  from jose import jwt, JWTError
4
+ from fastapi import Depends, HTTPException, status, Request
5
  from fastapi.security import OAuth2PasswordBearer
6
  from core.config import SECRET_KEY, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES
7
  from db.mongo import users_collection
8
  import logging
 
9
 
10
  logger = logging.getLogger(__name__)
11
 
12
  # OAuth2 setup
13
  oauth2_scheme = OAuth2PasswordBearer(
14
+ tokenUrl="/auth/login",
15
  scheme_name="JWT"
16
  )
17
+
18
  # Password hashing context
19
  pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
20
 
 
21
  def hash_password(password: str) -> str:
22
  return pwd_context.hash(password)
23
 
 
24
  def verify_password(plain: str, hashed: str) -> bool:
25
  return pwd_context.verify(plain, hashed)
26
 
27
+ def create_access_token(data: dict, expires_delta: timedelta = None) -> str:
 
28
  to_encode = data.copy()
29
  expire = datetime.utcnow() + (expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
30
  to_encode.update({"exp": expire})
31
  return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
32
 
 
33
  async def get_current_user(request: Request, token: str = Depends(oauth2_scheme)):
34
+ credentials_exception = HTTPException(
35
+ status_code=status.HTTP_401_UNAUTHORIZED,
36
+ detail="Could not validate credentials",
37
+ headers={"WWW-Authenticate": "Bearer"},
38
+ )
39
+
40
+ try:
41
+ # First try to get token from Authorization header
42
+ if not token:
43
+ # Fallback to checking cookies if using session-based auth
44
+ token = request.cookies.get("access_token")
45
+ if not token:
46
+ logger.error("No token provided in headers or cookies")
47
+ raise credentials_exception
48
 
49
+ # Remove 'Bearer ' prefix if present
50
+ if token.startswith("Bearer "):
51
+ token = token[7:]
52
 
 
53
  payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
54
+ email: str = payload.get("sub")
55
+ if email is None:
56
+ logger.error("Token missing 'sub' claim")
57
+ raise credentials_exception
58
 
 
 
 
59
  except JWTError as e:
60
+ logger.error(f"JWT validation error: {str(e)}")
61
+ raise credentials_exception
62
 
63
  user = await users_collection.find_one({"email": email})
64
+ if user is None:
65
+ logger.error(f"User not found for email: {email}")
66
+ raise credentials_exception
67
 
68
+ return user