diff --git a/api/app/application/users_repository.py b/api/app/application/users_repository.py index fb294b5..1cc5958 100644 --- a/api/app/application/users_repository.py +++ b/api/app/application/users_repository.py @@ -30,6 +30,15 @@ class UsersRepository: result = await self.db.execute(stmt) return result.scalars().first() + async def get_by_id_with_role(self, user_id: int) -> Optional[User]: + stmt = ( + select(User) + .filter(User.id == user_id) + .options(joinedload(User.role)) + ) + result = await self.db.execute(stmt) + return result.scalars().first() + async def create(self, user: User) -> User: self.db.add(user) await self.db.commit() diff --git a/api/app/controllers/auth_routes.py b/api/app/controllers/auth_router.py similarity index 100% rename from api/app/controllers/auth_routes.py rename to api/app/controllers/auth_router.py diff --git a/api/app/controllers/patients_router.py b/api/app/controllers/patients_router.py new file mode 100644 index 0000000..4c1a48c --- /dev/null +++ b/api/app/controllers/patients_router.py @@ -0,0 +1,17 @@ +from fastapi import APIRouter, Depends +from sqlalchemy.ext.asyncio import AsyncSession + +from app.database.session import get_db +from app.infrastructure.dependencies import get_current_user +from app.infrastructure.patients_service import PatientsService + +router = APIRouter() + + +@router.get("/patients/") +async def get_all_patients( + db: AsyncSession = Depends(get_db), + user=Depends(get_current_user) +): + patients_service = PatientsService(db) + return await patients_service.get_all_patients() diff --git a/api/app/domain/entities/patient.py b/api/app/domain/entities/patient.py index b622a1e..d8babde 100644 --- a/api/app/domain/entities/patient.py +++ b/api/app/domain/entities/patient.py @@ -1,3 +1,4 @@ +import datetime from typing import Optional from pydantic import BaseModel @@ -8,7 +9,7 @@ class PatientEntity(BaseModel): first_name: str last_name: str patronymic: Optional[str] - birthday: str + birthday: datetime.date address: Optional[str] email: Optional[str] phone: Optional[str] diff --git a/api/app/infrastructure/dependencies.py b/api/app/infrastructure/dependencies.py new file mode 100644 index 0000000..1d97970 --- /dev/null +++ b/api/app/infrastructure/dependencies.py @@ -0,0 +1,42 @@ +from fastapi import Depends, HTTPException, Security +from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials +import jwt +from sqlalchemy.ext.asyncio import AsyncSession + +from app.database.session import get_db +from app.domain.models.users import User +from app.settings import get_auth_data +from app.application.users_repository import UsersRepository + +security = HTTPBearer() + + +async def get_current_user( + credentials: HTTPAuthorizationCredentials = Security(security), + db: AsyncSession = Depends(get_db) +): + auth_data = get_auth_data() + + try: + payload = jwt.decode(credentials.credentials, auth_data["secret_key"], algorithms=[auth_data["algorithm"]]) + except jwt.ExpiredSignatureError: + raise HTTPException(status_code=401, detail="Token has expired") + except jwt.InvalidTokenError: + raise HTTPException(status_code=401, detail="Invalid token") + + user_id = payload.get("user_id") + if user_id is None: + raise HTTPException(status_code=401, detail="Invalid token") + + user = await UsersRepository(db).get_by_id_with_role(user_id) + if user is None: + raise HTTPException(status_code=401, detail="User not found") + + return user + + +def require_admin(user: User = Depends(get_current_user)): + if user.role.title != "Администратор": + raise HTTPException(status_code=403, detail="Access denied") + + return user diff --git a/api/app/main.py b/api/app/main.py index 76b9283..7d9a201 100644 --- a/api/app/main.py +++ b/api/app/main.py @@ -1,8 +1,9 @@ from fastapi import FastAPI from starlette.middleware.cors import CORSMiddleware -from app.controllers.auth_routes import router as auth_router +from app.controllers.auth_router import router as auth_router from app.controllers.register_routes import router as register_router +from app.controllers.patients_router import router as patients_router from app.settings import settings @@ -19,6 +20,7 @@ def start_app(): api_app.include_router(auth_router, prefix=settings.APP_PREFIX, tags=['auth']) api_app.include_router(register_router, prefix=settings.APP_PREFIX, tags=['register']) + api_app.include_router(patients_router, prefix=settings.APP_PREFIX, tags=['patients']) return api_app