80 lines
3.0 KiB
Python
80 lines
3.0 KiB
Python
from fastapi import Depends, FastAPI, HTTPException, status
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from sqlalchemy.orm import Session
|
|
|
|
from .auth import create_access_token
|
|
from .core.config import settings
|
|
from .crud import authenticate_user, create_address, create_user, get_user_by_email
|
|
from .db.session import Base, engine, get_db
|
|
from .dependencies import get_current_user
|
|
from .models import Address, User
|
|
from .schemas import AddressCreate, AddressRead, TokenResponse, UserCreate, UserLogin, UserRead
|
|
|
|
app = FastAPI(title='Flutter Auth API', version='1.0.0')
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=settings.cors_origin_list,
|
|
allow_credentials=True,
|
|
allow_methods=['*'],
|
|
allow_headers=['*'],
|
|
)
|
|
|
|
|
|
@app.on_event('startup')
|
|
def on_startup() -> None:
|
|
Base.metadata.create_all(bind=engine)
|
|
|
|
|
|
@app.get('/health')
|
|
def health_check() -> dict[str, str]:
|
|
return {'status': 'ok'}
|
|
|
|
|
|
@app.post('/auth/register', response_model=TokenResponse, status_code=status.HTTP_201_CREATED)
|
|
def register(payload: UserCreate, db: Session = Depends(get_db)) -> TokenResponse:
|
|
existing_user = get_user_by_email(db, payload.email)
|
|
if existing_user is not None:
|
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Ya existe un usuario con ese correo')
|
|
|
|
user = create_user(db, payload)
|
|
token = create_access_token(user_id=user.id, email=user.email)
|
|
return TokenResponse(token=token, user=UserRead.model_validate(user))
|
|
|
|
|
|
@app.post('/auth/login', response_model=TokenResponse)
|
|
def login(payload: UserLogin, db: Session = Depends(get_db)) -> TokenResponse:
|
|
user = authenticate_user(db, payload.email, payload.password)
|
|
if user is None:
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Correo o contraseña inválidos')
|
|
|
|
token = create_access_token(user_id=user.id, email=user.email)
|
|
return TokenResponse(token=token, user=UserRead.model_validate(user))
|
|
|
|
|
|
@app.get('/me', response_model=UserRead)
|
|
def read_me(current_user: User = Depends(get_current_user)) -> UserRead:
|
|
return UserRead.model_validate(current_user)
|
|
|
|
|
|
@app.post('/addresses', response_model=AddressRead, status_code=status.HTTP_201_CREATED)
|
|
def save_address(
|
|
payload: AddressCreate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
) -> AddressRead:
|
|
if payload.email is not None and payload.email != current_user.email:
|
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='El correo no coincide con el usuario autenticado')
|
|
|
|
address = create_address(db, current_user, payload)
|
|
return AddressRead.model_validate(address)
|
|
|
|
|
|
@app.get('/addresses/me', response_model=list[AddressRead])
|
|
def read_my_addresses(
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
) -> list[AddressRead]:
|
|
addresses = sorted(current_user.addresses, key=lambda address: address.created_at, reverse=True)
|
|
return [AddressRead.model_validate(address) for address in addresses]
|