1+ from typing import Annotated
2+
3+ import jwt
14from fastapi import APIRouter , Depends , HTTPException , Request , status
25from fastapi .security import OAuth2PasswordBearer , OAuth2PasswordRequestForm
3- from services . database . orm . community import get_community_by_username
6+ from jwt . exceptions import InvalidTokenError
47from sqlmodel .ext .asyncio .session import AsyncSession
58
6- from app .schemas import Token , TokenPayload
9+ from app .schemas import Community , Token , TokenPayload
710from app .services import auth
811from app .services .database .models import Community as DBCommunity
912from app .services .database .orm .community import get_community_by_username
1215
1316
1417def setup ():
15- router = APIRouter (prefix = '/authentication' , tags = ['authentication' ])
16- async def authenticate_community ( request : Request , username : str , password : str ):
17- # Valida se o usuário existe e se a senha está correta
18- session : AsyncSession = request .app .db_session_factory
19- found_community = await get_community_by_username (
20- username = username ,
21- session = session
22- )
23- if not found_community or not auth .verify_password (password , found_community .password ):
18+ router = APIRouter (prefix = "/authentication" , tags = ["authentication" ])
19+
20+ async def authenticate_community (
21+ request : Request , username : str , password : str
22+ ):
23+ # Valida se o usuário existe e se a senha está correta
24+ session : AsyncSession = request .app .db_session_factory
25+ found_community = await get_community_by_username (
26+ username = username , session = session
27+ )
28+ if not found_community or not auth .verify_password (
29+ password , found_community .password
30+ ):
2431 return None
25- return found_community
32+ return found_community
33+
34+ # Teste
35+ async def get_current_community (
36+ request : Request ,
37+ token : Annotated [str , Depends (oauth2_scheme )],
38+ ) -> DBCommunity :
39+ credentials_exception = HTTPException (
40+ status_code = status .HTTP_401_UNAUTHORIZED ,
41+ detail = "Could not validate credentials" ,
42+ headers = {"WWW-Authenticate" : "Bearer" },
43+ )
44+
45+ try :
46+ payload = jwt .decode (
47+ token , auth .SECRET_KEY , algorithms = [auth .ALGORITHM ]
48+ )
49+ username = payload .get ("sub" )
50+ if username is None :
51+ raise credentials_exception
52+ token_data = TokenPayload (username = username )
53+ except InvalidTokenError :
54+ raise credentials_exception
55+ session : AsyncSession = request .app .db_session_factory
56+ community = await get_community_by_username (
57+ session = session , username = token_data .username
58+ )
59+ if community is None :
60+ raise credentials_exception
61+
62+ return community
63+
64+ async def get_current_active_community (
65+ current_user : Annotated [DBCommunity , Depends (get_current_community )],
66+ ) -> DBCommunity :
67+ # A função simplesmente retorna o usuário.
68+ # Pode ser estendido futuramente para verificar um status "ativo".
69+ return current_user
2670
2771 # Teste
2872
@@ -48,7 +92,9 @@ async def login_for_access_token(
4892 request : Request , form_data : OAuth2PasswordRequestForm = Depends ()
4993 ):
5094 # Rota de login: valida credenciais e retorna token JWT
51- community = await authenticate_community ( request , form_data .username , form_data .password )
95+ community = await authenticate_community (
96+ request , form_data .username , form_data .password
97+ )
5298 if not community :
5399 raise HTTPException (
54100 status_code = status .HTTP_401_UNAUTHORIZED ,
@@ -62,4 +108,13 @@ async def login_for_access_token(
62108 "expires_in" : expires_in ,
63109 }
64110
111+ @router .get ("/me" , response_model = Community )
112+ async def read_community_me (
113+ current_community : Annotated [
114+ DBCommunity , Depends (get_current_active_community )
115+ ],
116+ ):
117+ # Rota para obter informações do usuário autenticado
118+ return current_community
119+
65120 return router # Retorna o router configurado com as rotas de autenticação
0 commit comments