routes.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. from typing import Annotated
  2. from core_domain import ServiceHealth
  3. from fastapi import APIRouter, Depends, HTTPException, Query, Request
  4. from sqlalchemy import text
  5. from sqlalchemy.orm import Session
  6. from app.application.services import AuthApplicationService
  7. from app.db.session import get_db
  8. from app.domain.repositories import RoleAssignmentRepository, RoleRepository, UserRepository
  9. from app.schemas.auth import (
  10. LoginRequest,
  11. LoginResponse,
  12. PermissionCheckRequest,
  13. PermissionCheckResponse,
  14. RoleAssignmentCreateRequest,
  15. RoleAssignmentResponse,
  16. RoleAssignmentStatusUpdateRequest,
  17. RoleCreateRequest,
  18. RoleResponse,
  19. RoleStatusUpdateRequest,
  20. TokenVerifyRequest,
  21. TokenVerifyResponse,
  22. UserCreateRequest,
  23. UserResponse,
  24. UserStatusUpdateRequest,
  25. )
  26. router = APIRouter()
  27. DbSession = Annotated[Session, Depends(get_db)]
  28. UserIdQuery = Annotated[str, Query(...)]
  29. def get_auth_application_service(request: Request, db: DbSession) -> AuthApplicationService:
  30. settings = request.app.state.settings
  31. return AuthApplicationService(
  32. user_repository=UserRepository(db),
  33. role_repository=RoleRepository(db),
  34. assignment_repository=RoleAssignmentRepository(db),
  35. token_secret=settings.credential_encryption_key)
  36. AuthServiceDep = Annotated[AuthApplicationService, Depends(get_auth_application_service)]
  37. @router.get("/health", response_model=ServiceHealth)
  38. def health_check(db: DbSession) -> ServiceHealth:
  39. db.execute(text("SELECT 1"))
  40. return ServiceHealth(service="auth-service", status="ok", database="ok")
  41. @router.post("/login", response_model=LoginResponse)
  42. def login(
  43. payload: LoginRequest,
  44. service: AuthServiceDep) -> LoginResponse:
  45. result = service.login(payload)
  46. if result is None:
  47. raise HTTPException(status_code=401, detail="invalid username or password")
  48. return result
  49. @router.post("/tokens/verify", response_model=TokenVerifyResponse)
  50. def verify_token(
  51. payload: TokenVerifyRequest,
  52. service: AuthServiceDep) -> TokenVerifyResponse:
  53. return service.verify_token(payload)
  54. @router.post("/users", response_model=UserResponse)
  55. def create_user(
  56. payload: UserCreateRequest,
  57. service: AuthServiceDep) -> UserResponse:
  58. return UserResponse.from_entity(service.create_user(payload))
  59. @router.get("/users", response_model=list[UserResponse])
  60. def list_users(
  61. service: AuthServiceDep) -> list[UserResponse]:
  62. return [UserResponse.from_entity(item) for item in service.list_users()]
  63. @router.patch("/users/{user_id}/status", response_model=UserResponse)
  64. def update_user_status(
  65. user_id: str,
  66. payload: UserStatusUpdateRequest,
  67. service: AuthServiceDep) -> UserResponse:
  68. entity = service.update_user_status(user_id=user_id, payload=payload)
  69. if entity is None:
  70. raise HTTPException(status_code=404, detail=f"user not found: {user_id}")
  71. return UserResponse.from_entity(entity)
  72. @router.post("/roles", response_model=RoleResponse)
  73. def create_role(
  74. payload: RoleCreateRequest,
  75. service: AuthServiceDep) -> RoleResponse:
  76. return RoleResponse.from_entity(service.create_role(payload))
  77. @router.get("/roles", response_model=list[RoleResponse])
  78. def list_roles(
  79. service: AuthServiceDep) -> list[RoleResponse]:
  80. return [RoleResponse.from_entity(item) for item in service.list_roles()]
  81. @router.patch("/roles/{role_id}/status", response_model=RoleResponse)
  82. def update_role_status(
  83. role_id: str,
  84. payload: RoleStatusUpdateRequest,
  85. service: AuthServiceDep) -> RoleResponse:
  86. entity = service.update_role_status(role_id=role_id, payload=payload)
  87. if entity is None:
  88. raise HTTPException(status_code=404, detail=f"role not found: {role_id}")
  89. return RoleResponse.from_entity(entity)
  90. @router.post("/assignments", response_model=RoleAssignmentResponse)
  91. def create_assignment(
  92. payload: RoleAssignmentCreateRequest,
  93. service: AuthServiceDep) -> RoleAssignmentResponse:
  94. return RoleAssignmentResponse.from_entity(service.create_assignment(payload))
  95. @router.get("/assignments", response_model=list[RoleAssignmentResponse])
  96. def list_assignments(
  97. user_id: UserIdQuery,
  98. service: AuthServiceDep) -> list[RoleAssignmentResponse]:
  99. return [
  100. RoleAssignmentResponse.from_entity(item)
  101. for item in service.list_assignments(user_id=user_id)
  102. ]
  103. @router.patch("/assignments/{assignment_id}/status", response_model=RoleAssignmentResponse)
  104. def update_assignment_status(
  105. assignment_id: str,
  106. payload: RoleAssignmentStatusUpdateRequest,
  107. service: AuthServiceDep) -> RoleAssignmentResponse:
  108. entity = service.update_assignment_status(assignment_id=assignment_id, payload=payload)
  109. if entity is None:
  110. raise HTTPException(status_code=404, detail=f"assignment not found: {assignment_id}")
  111. return RoleAssignmentResponse.from_entity(entity)
  112. @router.post("/permissions/check", response_model=PermissionCheckResponse)
  113. def check_permission(
  114. payload: PermissionCheckRequest,
  115. service: AuthServiceDep) -> PermissionCheckResponse:
  116. return service.check_permission(payload)