corrections for deployment
parent
00474e3ef2
commit
ede9d84474
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
|
||||||
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)
|
result = await db.execute(query)
|
||||||
await db.commit()
|
role = result.mappings().first()
|
||||||
user_id = result.inserted_primary_key[0]
|
return role
|
||||||
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)}")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue