aee0f09db8
- Datafabrik: Dockerfile fix, agentorkestrering fungerar - Vision: Identify-modell, FAISS, OCR alla testade - API: Alla 7 integrationstester passerade - Upplösare: Entitetsupplösning verifierad
82 lines
2.7 KiB
Python
82 lines
2.7 KiB
Python
"""Auth-endpoints: login, refresh, change password."""
|
|
from datetime import datetime
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.database import get_db
|
|
from app.dependencies import get_current_user
|
|
from app.models import User
|
|
from app.schemas import Token, LoginRequest, RefreshRequest, ChangePasswordRequest
|
|
from app.security import create_access_token, create_refresh_token, decode_token
|
|
from app.services.user_service import UserService
|
|
|
|
router = APIRouter(prefix="/auth", tags=["Authentication"])
|
|
|
|
|
|
@router.post("/login", response_model=Token)
|
|
async def login(data: LoginRequest, db: AsyncSession = Depends(get_db)):
|
|
service = UserService(db)
|
|
user = await service.authenticate(data.email, data.password)
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="Incorrect email or password",
|
|
headers={"WWW-Authenticate": "Bearer"},
|
|
)
|
|
user.last_login_at = datetime.utcnow()
|
|
await db.commit()
|
|
|
|
access_token = create_access_token(user.id)
|
|
refresh_token = create_refresh_token(user.id)
|
|
return Token(
|
|
access_token=access_token,
|
|
refresh_token=refresh_token,
|
|
expires_in=30 * 60,
|
|
)
|
|
|
|
|
|
@router.post("/refresh", response_model=Token)
|
|
async def refresh(data: RefreshRequest, db: AsyncSession = Depends(get_db)):
|
|
payload = decode_token(data.refresh_token)
|
|
if payload is None or payload.get("type") != "refresh":
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="Invalid refresh token",
|
|
)
|
|
|
|
from uuid import UUID
|
|
user_id = payload.get("sub")
|
|
service = UserService(db)
|
|
user = await service.get_by_id(UUID(user_id))
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="User not found",
|
|
)
|
|
|
|
access_token = create_access_token(user.id)
|
|
refresh_token = create_refresh_token(user.id)
|
|
return Token(
|
|
access_token=access_token,
|
|
refresh_token=refresh_token,
|
|
expires_in=30 * 60,
|
|
)
|
|
|
|
|
|
@router.post("/change-password")
|
|
async def change_password(
|
|
data: ChangePasswordRequest,
|
|
current_user: User = Depends(get_current_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
service = UserService(db)
|
|
await service.change_password(current_user, data.current_password, data.new_password)
|
|
return {"message": "Password changed successfully"}
|
|
|
|
|
|
@router.get("/me")
|
|
async def me(current_user: User = Depends(get_current_user)):
|
|
from app.schemas import UserDetailOut
|
|
return UserDetailOut.model_validate(current_user)
|