auth.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. from fastapi import APIRouter, Depends, HTTPException, Query
  2. from fastapi.security import OAuth2PasswordRequestForm
  3. from sqlalchemy.orm import Session
  4. from sqlalchemy.exc import SQLAlchemyError
  5. from typing import List
  6. from flowsint_core.core.services import (
  7. create_auth_service,
  8. AuthenticationError,
  9. ConflictError,
  10. DatabaseError,
  11. )
  12. from flowsint_core.core.models import Profile
  13. from flowsint_core.core.postgre_db import get_db
  14. from app.api.schemas.profile import ProfileCreate, ProfileRead, ProfileUpdate
  15. from app.api.deps import get_current_user
  16. router = APIRouter()
  17. @router.post("/token")
  18. def login_for_access_token(
  19. form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)
  20. ):
  21. service = create_auth_service(db)
  22. try:
  23. return service.authenticate(form_data.username, form_data.password)
  24. except AuthenticationError:
  25. raise HTTPException(status_code=400, detail="Incorrect email or password")
  26. except (DatabaseError, SQLAlchemyError) as e:
  27. print(f"[ERROR] DB error during login: {e}")
  28. raise HTTPException(status_code=500, detail="Internal server error")
  29. @router.post("/register", status_code=201)
  30. def register(user: ProfileCreate, db: Session = Depends(get_db)):
  31. service = create_auth_service(db)
  32. try:
  33. return service.register(user.email, user.password)
  34. except ConflictError:
  35. raise HTTPException(status_code=400, detail="Email already registered")
  36. except (DatabaseError, SQLAlchemyError) as e:
  37. print(f"[ERROR] DB error during registration: {e}")
  38. raise HTTPException(status_code=500, detail="Internal server error")
  39. @router.get("/me", response_model=ProfileRead)
  40. def get_me(current_user: Profile = Depends(get_current_user)):
  41. return current_user
  42. @router.put("/me", response_model=ProfileRead)
  43. def update_me(
  44. payload: ProfileUpdate,
  45. db: Session = Depends(get_db),
  46. current_user: Profile = Depends(get_current_user),
  47. ):
  48. for key, value in payload.model_dump(exclude_unset=True).items():
  49. setattr(current_user, key, value)
  50. db.commit()
  51. db.refresh(current_user)
  52. return current_user
  53. @router.get("/users/search", response_model=List[ProfileRead])
  54. def search_users(
  55. q: str = Query(..., min_length=1),
  56. db: Session = Depends(get_db),
  57. current_user: Profile = Depends(get_current_user),
  58. ):
  59. """Search users by email prefix for the share dialog autocomplete."""
  60. results = (
  61. db.query(Profile)
  62. .filter(
  63. Profile.email.ilike(f"{q}%"),
  64. Profile.id != current_user.id,
  65. )
  66. .limit(5)
  67. .all()
  68. )
  69. return results