|
1 | | -from datetime import datetime, timedelta |
2 | | - |
3 | 1 | from fastapi import Depends, HTTPException, status |
4 | | -from fastapi.security import OAuth2PasswordBearer |
| 2 | +from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer |
| 3 | +import httpx |
| 4 | +import json |
| 5 | +import os |
5 | 6 | from jose import JWTError, jwt |
6 | | -from passlib.context import CryptContext |
7 | | - |
8 | | -from api.core.config import settings |
9 | | - |
10 | | -# Password hashing context |
11 | | -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") |
12 | | - |
13 | | -# OAuth2 scheme for token authentication |
14 | | -oauth2_scheme = OAuth2PasswordBearer(tokenUrl="auth/login") |
15 | | - |
16 | | - |
17 | | -def verify_password(plain_password: str, hashed_password: str) -> bool: |
18 | | - """Verify a password against its hash.""" |
19 | | - return pwd_context.verify(plain_password, hashed_password) |
20 | 7 |
|
| 8 | +security = HTTPBearer() |
| 9 | +class UserInfo: |
| 10 | + scheme: str |
| 11 | + credentials: str |
| 12 | + projectGroups: list[str] |
21 | 13 |
|
22 | | -def get_password_hash(password: str) -> str: |
23 | | - """Generate password hash.""" |
24 | | - return pwd_context.hash(password) |
25 | | - |
26 | | - |
27 | | -def create_access_token(data: dict, expires_delta: timedelta | None = None) -> str: |
28 | | - """Create JWT access token.""" |
29 | | - to_encode = data.copy() |
30 | | - expire = datetime.utcnow() + ( |
31 | | - expires_delta or timedelta(minutes=settings.JWT_EXPIRATION) |
32 | | - ) |
33 | | - to_encode.update({"exp": expire}) |
34 | | - return jwt.encode(to_encode, settings.JWT_SECRET, algorithm=settings.JWT_ALGORITHM) |
35 | | - |
36 | | - |
37 | | -async def get_current_user(token: str = Depends(oauth2_scheme)): |
| 14 | +async def validate_token(credentials: HTTPAuthorizationCredentials = Depends(security)) -> UserInfo: |
38 | 15 | """Dependency to get current authenticated user.""" |
| 16 | + |
39 | 17 | credentials_exception = HTTPException( |
40 | 18 | status_code=status.HTTP_401_UNAUTHORIZED, |
41 | 19 | detail="Invalid authentication credentials", |
42 | 20 | headers={"WWW-Authenticate": "Bearer"}, |
43 | 21 | ) |
44 | 22 |
|
45 | 23 | try: |
46 | | - payload = jwt.decode( |
47 | | - token, settings.JWT_SECRET, algorithms=[settings.JWT_ALGORITHM] |
48 | | - ) |
49 | | - user_id: str = payload.get("sub") |
| 24 | + # FIXME: verify signature of JWT token |
| 25 | + payload = jwt.get_unverified_claims(credentials.credentials) |
| 26 | + user_id: str | None = payload.get("sub") |
50 | 27 | if user_id is None: |
51 | 28 | raise credentials_exception |
| 29 | + |
52 | 30 | except JWTError: |
53 | 31 | raise credentials_exception |
54 | 32 |
|
55 | | - # Import here to avoid circular imports |
56 | | - from api.core.database import get_session |
57 | | - from api.src.users.service import UserService |
| 33 | + async with httpx.AsyncClient() as client: |
| 34 | + headers = { |
| 35 | + 'Authorization': 'Bearer ' + credentials.credentials, |
| 36 | + 'Content-Type': 'application/json', |
| 37 | + } |
| 38 | + |
| 39 | + authorizationUrl = os.environ.get("TM_TDEI_BACKEND_URL", "https://portal-api-dev.tdei.us/api/v1/") + "/project-group-roles/" + user_id + "?page_no=1&page_size=50" |
| 40 | + response = await client.get(authorizationUrl, headers=headers) |
| 41 | + |
| 42 | + # token is not valid or server unavailable |
| 43 | + if response.status_code != 200: |
| 44 | + raise credentials_exception |
| 45 | + |
| 46 | + try: |
| 47 | + content = response.read() |
| 48 | + j = json.loads(content) |
| 49 | + except json.JSONDecodeError: |
| 50 | + raise credentials_exception |
| 51 | + |
| 52 | + pgs = [] |
| 53 | + for i in j: |
| 54 | + pgs.append(i["tdei_project_group_id"]) |
| 55 | + |
| 56 | + r = UserInfo() |
| 57 | + r.scheme = credentials.scheme |
| 58 | + r.credentials = credentials.credentials |
| 59 | + r.projectGroups = pgs |
| 60 | + |
| 61 | + return r |
| 62 | + |
| 63 | + |
| 64 | + |
58 | 65 |
|
59 | | - async for session in get_session(): |
60 | | - user = await UserService(session).get_user(int(user_id)) |
61 | | - if user is None: |
62 | | - raise credentials_exception |
63 | | - return user |
|
0 commit comments