corrections for deployment

main
Anaz 2025-01-21 12:29:25 +04:00
parent 00474e3ef2
commit ede9d84474
5 changed files with 93 additions and 66 deletions

View File

@ -13,13 +13,14 @@ from config.settings import settings
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from jose import jwt, JWTError from jose import jwt, JWTError
from smtplib import SMTP from smtplib import SMTP
from services.user_service import UserService
from utils.logging import logger from utils.logging import logger
from utils.security import verify_password, get_password_hash, pwd_context from utils.security import get_password_hash, pwd_context
router = APIRouter() router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
@router.post("/signup", response_model=UserResponse, status_code=201, summary="User Signup") @router.post("/signup", status_code=201, summary="User Signup")
async def signup(user: UserCreate, db=Depends(get_db)): async def signup(user: UserCreate, db=Depends(get_db)):
existing_user = await AuthService.get_user_by_email(user.email, db) existing_user = await AuthService.get_user_by_email(user.email, db)
if existing_user: if existing_user:
@ -27,8 +28,7 @@ async def signup(user: UserCreate, db=Depends(get_db)):
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Email already registered." detail="Email already registered."
) )
user.password = get_password_hash(user.password) return await UserService.create_user(user, db)
return await AuthService.create_user(user, db)
@router.post("/token", response_model=Token, summary="Login and get access token") @router.post("/token", response_model=Token, summary="Login and get access token")
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(), db=Depends(get_db)): async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(), db=Depends(get_db)):
@ -42,7 +42,7 @@ async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(
access_token = AuthService.create_access_token(data={"sub": user["email"]}) access_token = AuthService.create_access_token(data={"sub": user["email"]})
return {"access_token": access_token, "token_type": "bearer"} return {"access_token": access_token, "token_type": "bearer"}
@router.get("/me", response_model=UserResponse, summary="Get current user") @router.get("/me", summary="Get current user")
async def read_users_me(token:str = Depends(oauth2_scheme) , db=Depends(get_db)): async def read_users_me(token:str = Depends(oauth2_scheme) , db=Depends(get_db)):
return await AuthService.get_current_user(token, db) return await AuthService.get_current_user(token, db)

View File

@ -1,5 +1,6 @@
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile from fastapi import APIRouter, Depends, File, HTTPException, UploadFile
from fastapi.security import OAuth2PasswordBearer from fastapi.security import OAuth2PasswordBearer
from pydantic import ValidationError
from services.person_report_service import PersonReportService from services.person_report_service import PersonReportService
from models.schemas import PersonReportCreate, PersonReportUpdate, PersonReportResponse, UserResponse from models.schemas import PersonReportCreate, PersonReportUpdate, PersonReportResponse, UserResponse
from config.database import get_db from config.database import get_db
@ -9,15 +10,32 @@ from services.auth_service import AuthService
router = APIRouter() router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
@router.post("/", response_model=PersonReportResponse, status_code=201) @router.post("/", status_code=201)
async def create_report(report: PersonReportCreate, image_file: UploadFile = File(None), db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def create_report(
return await PersonReportService.create_report(report, db, image_file, token) report: str, # Le champ report est reçu sous forme de chaîne JSON
image_file: Optional[UploadFile] = File(None), # L'image est facultative
db: get_db = Depends(),
token: str = Depends(oauth2_scheme)
):
try:
# Valider et convertir la chaîne JSON en objet PersonReportCreate
report_data = PersonReportCreate.model_validate_json(report)
except ValidationError as e:
raise HTTPException(status_code=422, detail=f"Invalid report data: {e}")
@router.put("/{report_id}", response_model=PersonReportResponse) # Appeler le service pour traiter le rapport
try:
created_report = await PersonReportService.create_report(report_data, db, image_file, token)
except Exception as e:
raise HTTPException(status_code=500, detail=f"An error occurred while creating the report: {str(e)}")
return created_report
@router.put("/{report_id}")
async def update_report(report_id: int, report: PersonReportUpdate, db=Depends(get_db)): async def update_report(report_id: int, report: PersonReportUpdate, db=Depends(get_db)):
return await PersonReportService.update_report(report_id, report, db) return await PersonReportService.update_report(report_id, report, db)
@router.get("/{report_id}", response_model=PersonReportResponse) @router.get("/{report_id}")
async def get_report(report_id: int, db=Depends(get_db)): async def get_report(report_id: int, db=Depends(get_db)):
return await PersonReportService.get_report(report_id, db) return await PersonReportService.get_report(report_id, db)

View File

@ -30,15 +30,7 @@ class UserBase(BaseModel):
class UserCreate(UserBase): class UserCreate(UserBase):
password: str password: str
role: Role role: str
# Validation au niveau du modèle
@model_validator(mode="before")
def convert_role_to_dict(cls, values):
role = values.get("role")
if isinstance(role, str):
values["role"] = {"id": 0, "name": role, "permissions": []}
return values
class UserResponse(BaseModel): class UserResponse(BaseModel):
email: EmailStr email: EmailStr

View File

@ -26,15 +26,13 @@ class AuthService:
@staticmethod @staticmethod
def verify_password(plain_password: str, hashed_password: str) -> bool: def verify_password(plain_password: str, hashed_password: str) -> bool:
passEncr = pwd_context.hash(plain_password) passEncr = pwd_context.hash(plain_password)
passEncrTest123Azerty = pwd_context.hash("123Azerty") passEncrTest123Azerty = pwd_context.hash("123Azerty+@")
logger.info("password 123Azerty encrypted : " +passEncrTest123Azerty) logger.info("password 123Azerty+@ encrypted : " +passEncrTest123Azerty)
passEncrTestAzerty = pwd_context.hash("Azerty") logger.info("password input : " +plain_password)
logger.info("password Azerty encrypted : " +passEncrTestAzerty) logger.info("password input and encrypted : " +passEncr)
logger.info("password en clair : " +plain_password) logger.info("password hashed (in BDD) : "+ hashed_password)
logger.info("password encrypted : " +passEncr) logger.info("verification plain_password & hashed_password (in BDD) : "+ str(pwd_context.verify(plain_password, hashed_password)))
logger.info("password hashed : "+ hashed_password) logger.info("verification plain_password & 123Azerty+@ encrypted : "+ str(pwd_context.verify(plain_password, passEncrTest123Azerty)))
logger.info("verification plain_password & hashed_password : "+ str(pwd_context.verify(plain_password, hashed_password)))
logger.info("verification plain_password & 123Azerty encrypted : "+ str(pwd_context.verify(plain_password, passEncrTest123Azerty)))
return pwd_context.verify(plain_password, hashed_password) return pwd_context.verify(plain_password, hashed_password)
@staticmethod @staticmethod
@ -117,33 +115,39 @@ class AuthService:
"is_deleted": user["is_deleted"], "is_deleted": user["is_deleted"],
} }
# @staticmethod
# async def create_user(user: UserCreate, db):
# result = await db.execute(select(users_table))
# users = result.fetchall()
# role = "admin" if len(users) == 0 else user.role
# hashed_password = AuthService.get_password_hash(user.password)
# query = insert(users_table).values(
# email=user.email,
# full_name=user.full_name,
# phone=user.phone,
# date_of_birth=user.date_of_birth,
# organization=user.organization,
# hashed_password=hashed_password,
# role=role
# )
# try:
# result = await db.execute(query)
# await db.commit()
# user_id = result.inserted_primary_key[0]
# logger.info("user created", extra={"user_id": user_id, "email": user.email, "role": role})
# return {"id": user_id, "email": user.email, "role": role}
# except Exception as e:
# await db.rollback()
# logger.error("could not create user", extra={"error": str(e)})
# raise HTTPException(status_code=500, detail=f"Could not create user: {str(e)}")
@staticmethod @staticmethod
async def create_user(user: UserCreate, db): async def get_role_by_name(role_name: str, db: AsyncSession = Depends(get_db)):
result = await db.execute(select(users_table)) query = select(roles_table).where(roles_table.c.name == role_name)
users = result.fetchall() result = await db.execute(query)
role = "admin" if len(users) == 0 else user.role role = result.mappings().first()
return role
hashed_password = AuthService.get_password_hash(user.password)
query = insert(users_table).values(
email=user.email,
full_name=user.full_name,
phone=user.phone,
date_of_birth=user.date_of_birth,
organization=user.organization,
hashed_password=hashed_password,
role=role
)
try:
result = await db.execute(query)
await db.commit()
user_id = result.inserted_primary_key[0]
logger.info("user created", extra={"user_id": user_id, "email": user.email, "role": role})
return {"id": user_id, "email": user.email, "role": role}
except Exception as e:
await db.rollback()
logger.error("could not create user", extra={"error": str(e)})
raise HTTPException(status_code=500, detail=f"Could not create user: {str(e)}")

View File

@ -1,19 +1,21 @@
from sqlalchemy import select, update, insert from sqlalchemy import select, update, insert
from fastapi import Depends, HTTPException, status from fastapi import Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from models.schemas import UserCreate, UserResponse, UserUpdateRole, UserBlockBan from models.schemas import UserCreate, UserResponse, UserUpdateRole, UserBlockBan
from config.database import get_db from config.database import get_db
from models.db import users_table from models.db import users_table
from services.auth_service import AuthService from services.auth_service import AuthService
from utils.security import get_password_hash from utils.security import get_password_hash
from typing import Optional from typing import Optional
from utils.logging import logger
class UserService: class UserService:
@staticmethod @staticmethod
async def list_users(token: str, status: Optional[str] = None, db=Depends(get_db)): async def list_users(token: str, status: Optional[str] = None, db=Depends(get_db)):
await AuthService.check_permissions(token, ["admin"], db) await AuthService.check_permissions(token, db, ["admin","collectivité","état"] )
query = select(users_table) query = select(users_table)
if status: if status:
@ -24,29 +26,40 @@ class UserService:
@staticmethod @staticmethod
async def create_user(user: UserCreate, db): async def create_user(user: UserCreate, db):
hashed_password = get_password_hash(user.password)
query = users_table.insert().values( role = await AuthService.get_role_by_name(user.role, db)
if not role:
raise HTTPException(status_code=400, detail=f"Role '{user.role}' does not exist.")
result = await db.execute(select(users_table))
users = result.fetchall()
role = "admin" if len(users) == 0 else user.role
hashed_password = AuthService.get_password_hash(user.password)
query = insert(users_table).values(
email=user.email, email=user.email,
full_name=user.full_name, full_name=user.full_name,
phone=user.phone, phone=user.phone,
date_of_birth=user.date_of_birth, date_of_birth=user.date_of_birth,
organization=user.organization, organization=user.organization,
hashed_password=hashed_password, hashed_password=hashed_password,
role=user.role, # Par défaut, rôle "user" role=role
is_active=True,
is_banned=False
) )
try: try:
await db.execute(query) result = await db.execute(query)
await db.commit() await db.commit()
return {"message": "User created successfully"} user_id = result.inserted_primary_key[0]
logger.info("user created", extra={"user_id": user_id, "email": user.email, "role": role})
return {"id": user_id, "email": user.email, "role": role}
except Exception as e: except Exception as e:
await db.rollback() await db.rollback()
raise HTTPException(status_code=500, detail=f"Error creating user: {str(e)}") logger.error("could not create user", extra={"error": str(e)})
raise HTTPException(status_code=500, detail=f"Could not create user: {str(e)}")
@staticmethod @staticmethod
async def change_user_role(user_update: UserUpdateRole, db, token: str): async def change_user_role(user_update: UserUpdateRole, db, token: str):
await AuthService.check_permissions(token, ["admin"], db) await AuthService.check_permissions(token, db, ["admin"])
query = ( query = (
update(users_table) update(users_table)