2023-08-14 02:08:08 +08:00
|
|
|
import logging
|
2023-11-22 21:52:18 +08:00
|
|
|
from typing import Annotated
|
2023-08-14 02:08:08 +08:00
|
|
|
|
2023-11-22 21:52:18 +08:00
|
|
|
from fastapi import Depends
|
2023-11-22 17:13:16 +08:00
|
|
|
from fastapi.security import OAuth2PasswordBearer
|
2023-09-12 18:45:22 +08:00
|
|
|
from graphql import GraphQLError
|
2024-09-25 00:12:10 +08:00
|
|
|
from jose import jwt, JWTError
|
2023-09-12 18:45:22 +08:00
|
|
|
from pydantic import ValidationError
|
2023-11-22 21:52:18 +08:00
|
|
|
from strawberry.fastapi import BaseContext
|
2024-02-16 23:48:19 +08:00
|
|
|
from strawberry.types.info import Info as StrawberryInfo
|
|
|
|
from strawberry.types.info import RootValueType
|
2023-08-14 02:08:08 +08:00
|
|
|
|
2024-01-27 01:08:02 +08:00
|
|
|
from felicity.apps.common import schemas as core_schemas # noqa
|
2024-07-24 04:30:01 +08:00
|
|
|
from felicity.apps.user.entities import User
|
2024-07-24 17:04:53 +08:00
|
|
|
from felicity.apps.user.services import UserService
|
2024-07-28 03:52:31 +08:00
|
|
|
from felicity.core import get_settings # noqa
|
2024-01-26 01:52:03 +08:00
|
|
|
|
2023-08-14 02:08:08 +08:00
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
2024-01-26 01:52:03 +08:00
|
|
|
settings = get_settings()
|
|
|
|
|
2023-11-24 06:22:22 +08:00
|
|
|
# oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
|
|
|
|
|
|
|
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="felicity-gql", scheme_name="JWT")
|
2023-11-22 17:13:16 +08:00
|
|
|
|
2023-08-14 02:08:08 +08:00
|
|
|
|
2023-11-22 21:52:18 +08:00
|
|
|
async def _get_user(token: str):
|
2024-07-24 17:04:53 +08:00
|
|
|
user_service = UserService()
|
2023-08-14 02:08:08 +08:00
|
|
|
if not token:
|
|
|
|
GraphQLError("No auth token")
|
|
|
|
try:
|
|
|
|
payload = jwt.decode(
|
2023-11-24 06:22:22 +08:00
|
|
|
token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]
|
2023-08-14 02:08:08 +08:00
|
|
|
)
|
|
|
|
token_data = core_schemas.TokenPayload(**payload)
|
2024-09-25 00:12:10 +08:00
|
|
|
except (JWTError, ValidationError):
|
2023-08-14 02:08:08 +08:00
|
|
|
return None
|
|
|
|
|
2024-07-24 17:04:53 +08:00
|
|
|
return await user_service.get(uid=token_data.sub)
|
2023-08-14 02:08:08 +08:00
|
|
|
|
|
|
|
|
2023-12-30 15:51:11 +08:00
|
|
|
async def get_current_user(
|
2024-09-22 23:15:27 +08:00
|
|
|
token: Annotated[str, Depends(oauth2_scheme)],
|
2024-07-24 04:30:01 +08:00
|
|
|
) -> User | None:
|
2023-11-22 21:52:18 +08:00
|
|
|
return await _get_user(token)
|
|
|
|
|
|
|
|
|
2023-12-30 15:51:11 +08:00
|
|
|
async def get_current_active_user(
|
2024-09-22 23:15:27 +08:00
|
|
|
token: Annotated[str, Depends(oauth2_scheme)],
|
2024-07-24 04:30:01 +08:00
|
|
|
) -> User | None:
|
2023-11-22 21:52:18 +08:00
|
|
|
current_user = await _get_user(token)
|
2023-08-14 02:08:08 +08:00
|
|
|
if not current_user or not current_user.is_active:
|
|
|
|
return None
|
|
|
|
return current_user
|
|
|
|
|
|
|
|
|
2023-11-22 21:52:18 +08:00
|
|
|
class InfoContext(BaseContext):
|
|
|
|
async def user(self) -> User | None:
|
|
|
|
if not self.request:
|
|
|
|
return None
|
2023-08-14 02:08:08 +08:00
|
|
|
|
2023-11-22 21:52:18 +08:00
|
|
|
authorization = self.request.headers.get("Authorization", None)
|
2023-08-14 02:08:08 +08:00
|
|
|
if not authorization:
|
2023-11-22 21:52:18 +08:00
|
|
|
return None
|
|
|
|
|
|
|
|
token = authorization.split(" ")[1]
|
|
|
|
return await _get_user(token)
|
2023-08-14 02:08:08 +08:00
|
|
|
|
|
|
|
|
2023-11-22 21:52:18 +08:00
|
|
|
Info = StrawberryInfo[InfoContext, RootValueType]
|
2023-09-12 18:45:22 +08:00
|
|
|
|
|
|
|
|
2023-11-22 21:52:18 +08:00
|
|
|
async def get_gql_context() -> InfoContext:
|
|
|
|
return InfoContext()
|