From 23123a3bcee15cf5ef131ff664e0d6ad306841b0 Mon Sep 17 00:00:00 2001 From: Andrei Duvakin Date: Sun, 9 Feb 2025 21:52:25 +0500 Subject: [PATCH] =?UTF-8?q?=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20=D1=8D?= =?UTF-8?q?=D0=BD=D0=B4-=D0=BF=D0=BE=D0=B8=D0=BD=D1=82=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=BA=D0=B0=20=D0=BF=D0=B0=D1=86=D0=B8=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/application/users_repository.py | 9 ++++ .../{auth_routes.py => auth_router.py} | 0 api/app/controllers/patients_router.py | 17 ++++++++ api/app/domain/entities/patient.py | 3 +- api/app/infrastructure/dependencies.py | 42 +++++++++++++++++++ api/app/main.py | 4 +- 6 files changed, 73 insertions(+), 2 deletions(-) rename api/app/controllers/{auth_routes.py => auth_router.py} (100%) create mode 100644 api/app/controllers/patients_router.py create mode 100644 api/app/infrastructure/dependencies.py 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