correction des erreurs de déconnexion db
parent
81a93c5683
commit
89436bd8f8
180
api/v1/auth.py
180
api/v1/auth.py
|
|
@ -1,7 +1,7 @@
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from email.mime.multipart import MIMEMultipart
|
from email.mime.multipart import MIMEMultipart
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
from fastapi import APIRouter, Depends, Form, HTTPException, status, Body
|
from fastapi import APIRouter, HTTPException, status, Body
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||||
from sqlalchemy import update, select
|
from sqlalchemy import update, select
|
||||||
|
|
@ -10,7 +10,6 @@ from models.schemas import Token, UserCreate, UserResponse
|
||||||
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 config.settings import settings
|
from config.settings import settings
|
||||||
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 services.user_service import UserService
|
||||||
|
|
@ -21,32 +20,33 @@ router = APIRouter()
|
||||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
||||||
|
|
||||||
@router.post("/signup", 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):
|
||||||
existing_user = await AuthService.get_user_by_email(user.email, db)
|
async with get_db() as db:
|
||||||
if existing_user:
|
existing_user = await AuthService.get_user_by_email(user.email, db)
|
||||||
raise HTTPException(
|
if existing_user:
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
raise HTTPException(
|
||||||
detail="Email already registered."
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
detail="Email already registered."
|
||||||
return await UserService.create_user(user, db)
|
)
|
||||||
|
return await UserService.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 = Body(...)):
|
||||||
user = await AuthService.authenticate_user(form_data.username, form_data.password, db)
|
async with get_db() as db:
|
||||||
logger.info(f"User {form_data.username} logged in")
|
user = await AuthService.authenticate_user(form_data.username, form_data.password, db)
|
||||||
if not user:
|
logger.info(f"User {form_data.username} logged in")
|
||||||
raise HTTPException(
|
if not user:
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
raise HTTPException(
|
||||||
detail="Incorrect email or password",
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
headers={"WWW-Authenticate": "Bearer"},
|
detail="Incorrect email or password",
|
||||||
)
|
headers={"WWW-Authenticate": "Bearer"},
|
||||||
access_token = AuthService.create_access_token(data={"sub": user["email"]})
|
)
|
||||||
return {"access_token": access_token, "token_type": "bearer"}
|
access_token = AuthService.create_access_token(data={"sub": user["email"]})
|
||||||
|
return {"access_token": access_token, "token_type": "bearer"}
|
||||||
|
|
||||||
@router.post("/isvalid-token", summary="Verify token validity")
|
@router.post("/isvalid-token", summary="Verify token validity")
|
||||||
async def verify_token(token: str = Body(...)):
|
async def verify_token(token: str = Body(...)):
|
||||||
try:
|
try:
|
||||||
# Décoder le token pour vérifier sa validité
|
|
||||||
payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm])
|
payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm])
|
||||||
return {"valid": True, "message": "Token is valid", "payload": payload}
|
return {"valid": True, "message": "Token is valid", "payload": payload}
|
||||||
except jwt.ExpiredSignatureError:
|
except jwt.ExpiredSignatureError:
|
||||||
|
|
@ -61,88 +61,86 @@ async def verify_token(token: str = Body(...)):
|
||||||
)
|
)
|
||||||
|
|
||||||
@router.get("/me", 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 = Body(...)):
|
||||||
return await AuthService.get_current_user(token, db)
|
async with get_db() as db:
|
||||||
|
return await AuthService.get_current_user(token, db)
|
||||||
|
|
||||||
@router.post("/reset-password")
|
@router.post("/reset-password")
|
||||||
async def reset_password(token: str = Body(...), new_password: str = Body(...), db: AsyncSession = Depends(get_db)):
|
async def reset_password(token: str = Body(...), new_password: str = Body(...)):
|
||||||
try:
|
async with get_db() as db:
|
||||||
payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm])
|
try:
|
||||||
email = payload.get("sub")
|
payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm])
|
||||||
if email is None:
|
email = payload.get("sub")
|
||||||
raise HTTPException(status_code=400, detail="Invalid token")
|
if email is None:
|
||||||
except JWTError:
|
raise HTTPException(status_code=400, detail="Invalid token")
|
||||||
raise HTTPException(status_code=400, detail="Invalid or expired token")
|
except JWTError:
|
||||||
|
raise HTTPException(status_code=400, detail="Invalid or expired token")
|
||||||
|
|
||||||
# Hash the new password
|
hashed_password = pwd_context.hash(new_password)
|
||||||
hashed_password = pwd_context.hash(new_password)
|
|
||||||
|
|
||||||
# Update the user's password
|
query = (
|
||||||
query = (
|
update(users_table)
|
||||||
update(users_table)
|
.where(users_table.c.email == email)
|
||||||
.where(users_table.c.email == email)
|
.values(hashed_password=hashed_password)
|
||||||
.values(hashed_password=hashed_password)
|
.execution_options(synchronize_session="fetch")
|
||||||
.execution_options(synchronize_session="fetch")
|
)
|
||||||
)
|
await db.execute(query)
|
||||||
await db.execute(query)
|
|
||||||
await db.commit()
|
|
||||||
|
|
||||||
return JSONResponse(content={"message": "Password updated successfully."})
|
return JSONResponse(content={"message": "Password updated successfully."})
|
||||||
|
|
||||||
@router.post("/password-reset-request")
|
@router.post("/password-reset-request")
|
||||||
async def password_reset_request(email: str, db: AsyncSession = Depends(get_db)):
|
async def password_reset_request(email: str = Body(...)):
|
||||||
query = select(users_table).where(users_table.c.email == email)
|
async with get_db() as db:
|
||||||
result = await db.execute(query)
|
query = select(users_table).where(users_table.c.email == email)
|
||||||
user = result.fetchone()
|
result = await db.execute(query)
|
||||||
if not user:
|
user = result.fetchone()
|
||||||
raise HTTPException(status_code=404, detail="User not found")
|
if not user:
|
||||||
|
raise HTTPException(status_code=404, detail="User not found")
|
||||||
|
|
||||||
# Générer un token JWT
|
reset_token = jwt.encode(
|
||||||
reset_token = jwt.encode(
|
{"sub": email, "exp": datetime.utcnow() + timedelta(hours=1)},
|
||||||
{"sub": email, "exp": datetime.utcnow() + timedelta(hours=1)},
|
settings.secret_key,
|
||||||
settings.secret_key,
|
algorithm=settings.algorithm,
|
||||||
algorithm=settings.algorithm,
|
)
|
||||||
)
|
|
||||||
|
|
||||||
reset_link = f"{settings.resetpass_url}/?token={reset_token}"
|
reset_link = f"{settings.resetpass_url}/?token={reset_token}"
|
||||||
|
|
||||||
# Envoyer le lien par email
|
try:
|
||||||
try:
|
subject = "mot de passe perdu"
|
||||||
subject = "mot de passe perdu"
|
sender_email = settings.email_username
|
||||||
sender_email = settings.email_username
|
receiver_email = email
|
||||||
receiver_email = email
|
logger.info(f"sender {settings.email_username} receiver {email}")
|
||||||
logger.info(f"sender {settings.email_username} receiver {email}")
|
|
||||||
|
|
||||||
message = MIMEMultipart("alternative")
|
message = MIMEMultipart("alternative")
|
||||||
message["Subject"] = subject
|
message["Subject"] = subject
|
||||||
message["From"] = sender_email
|
message["From"] = sender_email
|
||||||
message["To"] = receiver_email
|
message["To"] = receiver_email
|
||||||
|
|
||||||
text = f"You requested a password reset. Click the link below to reset your password:\n{reset_link}"
|
text = f"You requested a password reset. Click the link below to reset your password:\n{reset_link}"
|
||||||
html = f"""
|
html = f"""
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
<p>You requested a password reset.<br>
|
<p>You requested a password reset.<br>
|
||||||
Click the link below to reset your password:<br>
|
Click the link below to reset your password:<br>
|
||||||
<a href="{reset_link}">Redefinir mon mot de passe</a>
|
<a href="{reset_link}">Redefinir mon mot de passe</a>
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
part1 = MIMEText(text, "plain")
|
part1 = MIMEText(text, "plain")
|
||||||
part2 = MIMEText(html, "html")
|
part2 = MIMEText(html, "html")
|
||||||
message.attach(part1)
|
message.attach(part1)
|
||||||
message.attach(part2)
|
message.attach(part2)
|
||||||
|
|
||||||
with SMTP(settings.email_host, settings.email_port) as server:
|
with SMTP(settings.email_host, settings.email_port) as server:
|
||||||
server.starttls()
|
server.starttls()
|
||||||
server.login(settings.email_username, settings.email_password)
|
server.login(settings.email_username, settings.email_password)
|
||||||
server.sendmail(sender_email, receiver_email, message.as_string())
|
server.sendmail(sender_email, receiver_email, message.as_string())
|
||||||
|
|
||||||
logger.info(f"Password reset email sent to {email}")
|
logger.info(f"Password reset email sent to {email}")
|
||||||
return JSONResponse(content={"message": "Password reset link sent via email."})
|
return JSONResponse(content={"message": "Password reset link sent via email."})
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to send password reset email to {email}: {str(e)}")
|
logger.error(f"Failed to send password reset email to {email}: {str(e)}")
|
||||||
raise HTTPException(status_code=500, detail=f"Failed to send password reset email. sender {sender_email} receiver {receiver_email}")
|
raise HTTPException(status_code=500, detail=f"Failed to send password reset email. sender {sender_email} receiver {receiver_email}")
|
||||||
|
|
@ -6,5 +6,6 @@ from config.database import get_db
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@router.post("/", status_code=201)
|
@router.post("/", status_code=201)
|
||||||
async def report_issue(issue: TechnicalIssue, db=Depends(get_db)):
|
async def report_issue(issue: TechnicalIssue):
|
||||||
return await MessageService.create_issue(issue, db)
|
async with get_db() as db:
|
||||||
|
return await MessageService.create_issue(issue, db)
|
||||||
|
|
@ -11,62 +11,58 @@ router = APIRouter()
|
||||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
||||||
|
|
||||||
@router.post("/", status_code=status.HTTP_201_CREATED)
|
@router.post("/", status_code=status.HTTP_201_CREATED)
|
||||||
async def request_need(need: NeedRequestCreate, db=Depends(get_db)):
|
async def request_need(need: NeedRequestCreate):
|
||||||
|
async with get_db() as db:
|
||||||
return await NeedRequestService.create_need(need, db)
|
return await NeedRequestService.create_need(need, db)
|
||||||
|
|
||||||
@router.get("/", status_code=status.HTTP_200_OK)
|
@router.get("/", status_code=status.HTTP_200_OK)
|
||||||
async def get_all_reports(db=Depends(get_db)):
|
async def get_all_reports():
|
||||||
return await NeedRequestService.get_all_needs(db)
|
async with get_db() as db:
|
||||||
|
return await NeedRequestService.get_all_needs(db)
|
||||||
|
|
||||||
@router.get("/{need_id}", status_code=status.HTTP_200_OK)
|
@router.get("/{need_id}", status_code=status.HTTP_200_OK)
|
||||||
async def get_need(need_id: int, db=Depends(get_db)):
|
async def get_need(need_id: int):
|
||||||
|
async with get_db() as db:
|
||||||
need = await NeedRequestService.get_need(need_id, db)
|
need = await NeedRequestService.get_need(need_id, db)
|
||||||
if not need:
|
if not need:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Need request not found")
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Need request not found")
|
||||||
return need
|
return need
|
||||||
|
|
||||||
|
|
||||||
@router.put("/{need_id}", status_code=status.HTTP_200_OK)
|
@router.put("/{need_id}", status_code=status.HTTP_200_OK)
|
||||||
async def update_need(
|
async def update_need(
|
||||||
need_id: int,
|
need_id: int,
|
||||||
need_update: NeedRequestUpdate,
|
need_update: NeedRequestUpdate,
|
||||||
token: str = Depends(oauth2_scheme),
|
token: str = Depends(oauth2_scheme)
|
||||||
db=Depends(get_db),
|
|
||||||
):
|
):
|
||||||
|
async with get_db() as db:
|
||||||
|
need = await NeedRequestService.get_need(need_id, db)
|
||||||
|
if not need:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Need request not found")
|
||||||
|
|
||||||
need = await NeedRequestService.get_need(need_id, db)
|
# Vérifie si l'utilisateur est l'auteur ou un administrateur
|
||||||
if not need:
|
if NeedRequestService.verify_requester_or_admin(need_id, token, db):
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Need request not found")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
# V<>rifie si l'utilisateur est l'auteur ou un administrateur
|
detail="You do not have permission to update this need request",
|
||||||
if NeedRequestService.verify_requester_or_admin(need_id, token, db):
|
)
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_403_FORBIDDEN,
|
|
||||||
detail="You do not have permission to update this need request",
|
|
||||||
)
|
|
||||||
|
|
||||||
return await NeedRequestService.update_need(need_id, need_update, db)
|
|
||||||
|
|
||||||
|
return await NeedRequestService.update_need(need_id, need_update, db)
|
||||||
|
|
||||||
@router.delete("/{need_id}", status_code=status.HTTP_200_OK)
|
@router.delete("/{need_id}", status_code=status.HTTP_200_OK)
|
||||||
async def delete_need(
|
async def delete_need(
|
||||||
need_id: int,
|
need_id: int,
|
||||||
token: str = Depends(oauth2_scheme),
|
token: str = Depends(oauth2_scheme)
|
||||||
db=Depends(get_db),
|
|
||||||
|
|
||||||
):
|
):
|
||||||
|
async with get_db() as db:
|
||||||
|
need = await NeedRequestService.get_need(need_id, db)
|
||||||
|
if not need:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Need request not found")
|
||||||
|
|
||||||
need = await NeedRequestService.get_need(need_id, db)
|
# Vérifie si l'utilisateur est l'auteur ou un administrateur
|
||||||
if not need:
|
if NeedRequestService.verify_requester_or_admin(need_id, token, db):
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Need request not found")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
|
detail="You do not have permission to delete this need request",
|
||||||
|
)
|
||||||
|
|
||||||
# V<>rifie si l'utilisateur est l'auteur ou un administrateur
|
return await NeedRequestService.delete_need(need_id, db)
|
||||||
if NeedRequestService.verify_requester_or_admin(need_id, token, db):
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_403_FORBIDDEN,
|
|
||||||
detail="You do not have permission to delete this need request",
|
|
||||||
)
|
|
||||||
|
|
||||||
return await NeedRequestService.delete_need(need_id, db)
|
|
||||||
|
|
@ -13,31 +13,34 @@ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
||||||
|
|
||||||
@router.post("/", status_code=201)
|
@router.post("/", status_code=201)
|
||||||
async def create_report(
|
async def create_report(
|
||||||
file: Optional[UploadFile] = File(None), # Le champ photo est reçu sous forme de fichier
|
file: Optional[UploadFile] = File(None),
|
||||||
report: PersonReportCreate = Form(...), # Le champ report est reçu sous forme de chaîne JSON
|
report: PersonReportCreate = Form(...),
|
||||||
db: get_db = Depends(),
|
|
||||||
token: str = Depends(oauth2_scheme)
|
token: str = Depends(oauth2_scheme)
|
||||||
):
|
):
|
||||||
# Appeler le service pour traiter le rapport
|
async with get_db() as db:
|
||||||
try:
|
try:
|
||||||
created_report = await PersonReportService.create_report(report, db, token, file)
|
created_report = await PersonReportService.create_report(report, db, token, file)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(status_code=500, detail=f"An error occurred while creating the report: {str(e)}")
|
raise HTTPException(status_code=500, detail=f"An error occurred while creating the report: {str(e)}")
|
||||||
|
|
||||||
return created_report
|
return created_report
|
||||||
|
|
||||||
@router.put("/{report_id}")
|
@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):
|
||||||
return await PersonReportService.update_report(report_id, report, db)
|
async with get_db() as db:
|
||||||
|
return await PersonReportService.update_report(report_id, report, db)
|
||||||
|
|
||||||
@router.get("/{report_id}")
|
@router.get("/{report_id}")
|
||||||
async def get_report(report_id: int, db=Depends(get_db)):
|
async def get_report(report_id: int):
|
||||||
return await PersonReportService.get_report(report_id, db)
|
async with get_db() as db:
|
||||||
|
return await PersonReportService.get_report(report_id, db)
|
||||||
|
|
||||||
@router.get("/", response_model=list[PersonReportResponse])
|
@router.get("/", response_model=list[PersonReportResponse])
|
||||||
async def list_reports(status: Optional[str] = None, db=Depends(get_db)):
|
async def list_reports(status: Optional[str] = None):
|
||||||
return await PersonReportService.list_reports(status, db)
|
async with get_db() as db:
|
||||||
|
return await PersonReportService.list_reports(status, db)
|
||||||
|
|
||||||
@router.delete("/{report_id}", status_code=204)
|
@router.delete("/{report_id}", status_code=204)
|
||||||
async def delete_report(report_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def delete_report(report_id: int, token: str = Depends(oauth2_scheme)):
|
||||||
return await PersonReportService.delete_report(report_id, db, token)
|
async with get_db() as db:
|
||||||
|
return await PersonReportService.delete_report(report_id, db, token)
|
||||||
|
|
@ -8,25 +8,26 @@ router = APIRouter()
|
||||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
||||||
|
|
||||||
@router.post("/", status_code=201)
|
@router.post("/", status_code=201)
|
||||||
async def create_point(point: CreatePointOfInterest, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def create_point(point: CreatePointOfInterest, token: str = Depends(oauth2_scheme)):
|
||||||
return await PointsOfInterestService.create_point_of_interest(point, db, token)
|
async with get_db() as db:
|
||||||
|
return await PointsOfInterestService.create_point_of_interest(point, db, token)
|
||||||
|
|
||||||
@router.get("/{point_id}")
|
@router.get("/{point_id}")
|
||||||
async def get_point(point_id: int, db=Depends(get_db)):
|
async def get_point(point_id: int):
|
||||||
return await PointsOfInterestService.get_point_of_interest(point_id, db)
|
async with get_db() as db:
|
||||||
|
return await PointsOfInterestService.get_point_of_interest(point_id, db)
|
||||||
|
|
||||||
@router.get("/")
|
@router.get("/")
|
||||||
async def get_all_points(db=Depends(get_db)):
|
async def get_all_points():
|
||||||
return await PointsOfInterestService.get_all_points_of_interest(db)
|
async with get_db() as db:
|
||||||
|
return await PointsOfInterestService.get_all_points_of_interest(db)
|
||||||
|
|
||||||
@router.put("/{point_id}")
|
@router.put("/{point_id}")
|
||||||
async def update_point(point_id: int, point: UpdatePointOfInterest, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def update_point(point_id: int, point: UpdatePointOfInterest, token: str = Depends(oauth2_scheme)):
|
||||||
return await PointsOfInterestService.update_point_of_interest(point_id, point, db, token)
|
async with get_db() as db:
|
||||||
|
return await PointsOfInterestService.update_point_of_interest(point_id, point, db, token)
|
||||||
|
|
||||||
@router.delete("/{point_id}")
|
@router.delete("/{point_id}")
|
||||||
async def delete_point(point_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def delete_point(point_id: int, token: str = Depends(oauth2_scheme)):
|
||||||
return await PointsOfInterestService.delete_point_of_interest(point_id, db, token)
|
async with get_db() as db:
|
||||||
|
return await PointsOfInterestService.delete_point_of_interest(point_id, db, token)
|
||||||
|
|
@ -10,21 +10,26 @@ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@router.post("/", status_code=status.HTTP_201_CREATED)
|
@router.post("/", status_code=status.HTTP_201_CREATED)
|
||||||
async def report_user(report: UserReport, db=Depends(get_db)):
|
async def report_user(report: UserReport):
|
||||||
return await ReportService.create_report(report, db)
|
async with get_db() as db:
|
||||||
|
return await ReportService.create_report(report, db)
|
||||||
|
|
||||||
@router.get("/{report_id}", status_code=status.HTTP_200_OK)
|
@router.get("/{report_id}", status_code=status.HTTP_200_OK)
|
||||||
async def get_report(report_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def get_report(report_id: int, token: str = Depends(oauth2_scheme)):
|
||||||
return await ReportService.get_report_by_id(report_id, db, token)
|
async with get_db() as db:
|
||||||
|
return await ReportService.get_report_by_id(report_id, db, token)
|
||||||
|
|
||||||
@router.get("/", status_code=status.HTTP_200_OK)
|
@router.get("/", status_code=status.HTTP_200_OK)
|
||||||
async def get_all_reports(db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def get_all_reports(token: str = Depends(oauth2_scheme)):
|
||||||
return await ReportService.get_all_reports(db, token)
|
async with get_db() as db:
|
||||||
|
return await ReportService.get_all_reports(db, token)
|
||||||
|
|
||||||
@router.put("/{report_id}", status_code=status.HTTP_200_OK)
|
@router.put("/{report_id}", status_code=status.HTTP_200_OK)
|
||||||
async def update_report(report_id: int, report_update: UserReportUpdate, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def update_report(report_id: int, report_update: UserReportUpdate, token: str = Depends(oauth2_scheme)):
|
||||||
return await ReportService.update_report(report_id, report_update, db, token)
|
async with get_db() as db:
|
||||||
|
return await ReportService.update_report(report_id, report_update, db, token)
|
||||||
|
|
||||||
@router.delete("/{report_id}", status_code=status.HTTP_200_OK)
|
@router.delete("/{report_id}", status_code=status.HTTP_200_OK)
|
||||||
async def delete_report(report_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def delete_report(report_id: int, token: str = Depends(oauth2_scheme)):
|
||||||
return await ReportService.delete_report(report_id, db, token)
|
async with get_db() as db:
|
||||||
|
return await ReportService.delete_report(report_id, db, token)
|
||||||
|
|
@ -9,50 +9,50 @@ from typing import List
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
||||||
|
|
||||||
|
|
||||||
@router.post("/", status_code=201)
|
@router.post("/", status_code=201)
|
||||||
async def create_role(name: str, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def create_role(name: str, token: str = Depends(oauth2_scheme)):
|
||||||
"""
|
"""
|
||||||
Créer un nouveau rôle avec des permissions associées (réservé aux administrateurs).
|
Créer un nouveau rôle avec des permissions associées (réservé aux administrateurs).
|
||||||
"""
|
"""
|
||||||
return await RoleService.create_role(name, db, token)
|
async with get_db() as db:
|
||||||
|
return await RoleService.create_role(name, db, token)
|
||||||
|
|
||||||
@router.get("/{role_id}", response_model=Role)
|
@router.get("/{role_id}", response_model=Role)
|
||||||
async def get_role(role_id: int, db: AsyncSession = Depends(get_db)):
|
async def get_role(role_id: int):
|
||||||
"""
|
"""
|
||||||
Récupérer les détails d'un rôle spécifique.
|
Récupérer les détails d'un rôle spécifique.
|
||||||
"""
|
"""
|
||||||
return await RoleService.get_role(role_id, db)
|
async with get_db() as db:
|
||||||
|
return await RoleService.get_role(role_id, db)
|
||||||
|
|
||||||
@router.get("/", response_model=List[Role])
|
@router.get("/", response_model=List[Role])
|
||||||
async def get_all_roles(db: AsyncSession = Depends(get_db)):
|
async def get_all_roles():
|
||||||
"""
|
"""
|
||||||
Récupérer tous les rôles avec leurs permissions associées.
|
Récupérer tous les rôles avec leurs permissions associées.
|
||||||
"""
|
"""
|
||||||
return await RoleService.get_all_roles(db)
|
async with get_db() as db:
|
||||||
|
return await RoleService.get_all_roles(db)
|
||||||
|
|
||||||
@router.put("/{role_id}")
|
@router.put("/{role_id}")
|
||||||
async def update_role(role_id: int, role: Role, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def update_role(role_id: int, role: Role, token: str = Depends(oauth2_scheme)):
|
||||||
"""
|
"""
|
||||||
Mettre à jour un rôle existant (réservé aux administrateurs).
|
Mettre à jour un rôle existant (réservé aux administrateurs).
|
||||||
"""
|
"""
|
||||||
return await RoleService.update_role(role_id, role.dict(), db, token)
|
async with get_db() as db:
|
||||||
|
return await RoleService.update_role(role_id, role.dict(), db, token)
|
||||||
|
|
||||||
@router.delete("/{role_id}")
|
@router.delete("/{role_id}")
|
||||||
async def delete_role(role_id: int, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def delete_role(role_id: int, token: str = Depends(oauth2_scheme)):
|
||||||
"""
|
"""
|
||||||
Supprimer un rôle (réservé aux administrateurs).
|
Supprimer un rôle (réservé aux administrateurs).
|
||||||
"""
|
"""
|
||||||
return await RoleService.delete_role(role_id, db, token)
|
async with get_db() as db:
|
||||||
|
return await RoleService.delete_role(role_id, db, token)
|
||||||
|
|
||||||
@router.get("/roles/permissions", response_model=List[Permission])
|
@router.get("/roles/permissions", response_model=List[Permission])
|
||||||
async def get_all_permissions(db: AsyncSession = Depends(get_db)):
|
async def get_all_permissions():
|
||||||
"""
|
"""
|
||||||
Récupérer toutes les permissions disponibles.
|
Récupérer toutes les permissions disponibles.
|
||||||
"""
|
"""
|
||||||
return await RoleService.get_all_permissions(db)
|
async with get_db() as db:
|
||||||
|
return await RoleService.get_all_permissions(db)
|
||||||
|
|
@ -8,25 +8,26 @@ router = APIRouter()
|
||||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
||||||
|
|
||||||
@router.post("/", status_code=201)
|
@router.post("/", status_code=201)
|
||||||
async def create_shelter(shelter: CreateShelter, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def create_shelter(shelter: CreateShelter, token: str = Depends(oauth2_scheme)):
|
||||||
return await ShelterService.create_shelter(shelter, db, token)
|
async with get_db() as db:
|
||||||
|
return await ShelterService.create_shelter(shelter, db, token)
|
||||||
|
|
||||||
@router.get("/{shelter_id}")
|
@router.get("/{shelter_id}")
|
||||||
async def get_shelter(shelter_id: int, db=Depends(get_db)):
|
async def get_shelter(shelter_id: int):
|
||||||
return await ShelterService.get_shelter(shelter_id, db)
|
async with get_db() as db:
|
||||||
|
return await ShelterService.get_shelter(shelter_id, db)
|
||||||
|
|
||||||
@router.get("/")
|
@router.get("/")
|
||||||
async def get_all_shelters(db=Depends(get_db)):
|
async def get_all_shelters():
|
||||||
return await ShelterService.get_all_shelters(db)
|
async with get_db() as db:
|
||||||
|
return await ShelterService.get_all_shelters(db)
|
||||||
|
|
||||||
@router.put("/{shelter_id}")
|
@router.put("/{shelter_id}")
|
||||||
async def update_shelter(shelter_id: int, shelter: UpdateShelter, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def update_shelter(shelter_id: int, shelter: UpdateShelter, token: str = Depends(oauth2_scheme)):
|
||||||
return await ShelterService.update_shelter(shelter_id, shelter, db, token)
|
async with get_db() as db:
|
||||||
|
return await ShelterService.update_shelter(shelter_id, shelter, db, token)
|
||||||
|
|
||||||
@router.delete("/{shelter_id}")
|
@router.delete("/{shelter_id}")
|
||||||
async def delete_shelter(shelter_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def delete_shelter(shelter_id: int, token: str = Depends(oauth2_scheme)):
|
||||||
return await ShelterService.delete_shelter(shelter_id, db, token)
|
async with get_db() as db:
|
||||||
|
return await ShelterService.delete_shelter(shelter_id, db, token)
|
||||||
|
|
@ -9,21 +9,26 @@ router = APIRouter()
|
||||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
||||||
|
|
||||||
@router.post("/", status_code=201)
|
@router.post("/", status_code=201)
|
||||||
async def create_issue(issue: CreateTechnicalIssue, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def create_issue(issue: CreateTechnicalIssue, token: str = Depends(oauth2_scheme)):
|
||||||
return await TechnicalIssueService.create_issue(issue, db, token)
|
async with get_db() as db:
|
||||||
|
return await TechnicalIssueService.create_issue(issue, db, token)
|
||||||
|
|
||||||
@router.get("/{issue_id}")
|
@router.get("/{issue_id}")
|
||||||
async def get_issue(issue_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def get_issue(issue_id: int, token: str = Depends(oauth2_scheme)):
|
||||||
return await TechnicalIssueService.get_issue(issue_id, db, token)
|
async with get_db() as db:
|
||||||
|
return await TechnicalIssueService.get_issue(issue_id, db, token)
|
||||||
|
|
||||||
@router.get("/")
|
@router.get("/")
|
||||||
async def get_all_issues(db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def get_all_issues(token: str = Depends(oauth2_scheme)):
|
||||||
return await TechnicalIssueService.get_all_issues(db, token)
|
async with get_db() as db:
|
||||||
|
return await TechnicalIssueService.get_all_issues(db, token)
|
||||||
|
|
||||||
@router.put("/{issue_id}")
|
@router.put("/{issue_id}")
|
||||||
async def update_issue(issue_id: int, issue_data: UpdateTechnicalIssue, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def update_issue(issue_id: int, issue_data: UpdateTechnicalIssue, token: str = Depends(oauth2_scheme)):
|
||||||
return await TechnicalIssueService.update_issue(issue_id, issue_data, db, token)
|
async with get_db() as db:
|
||||||
|
return await TechnicalIssueService.update_issue(issue_id, issue_data, db, token)
|
||||||
|
|
||||||
@router.delete("/{issue_id}")
|
@router.delete("/{issue_id}")
|
||||||
async def delete_issue(issue_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def delete_issue(issue_id: int, token: str = Depends(oauth2_scheme)):
|
||||||
return await TechnicalIssueService.delete_issue(issue_id, db, token)
|
async with get_db() as db:
|
||||||
|
return await TechnicalIssueService.delete_issue(issue_id, db, token)
|
||||||
|
|
@ -10,7 +10,8 @@ router = APIRouter()
|
||||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
||||||
|
|
||||||
@router.post("/")
|
@router.post("/")
|
||||||
async def upload_file(file: UploadFile, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def upload_file(file: UploadFile, token: str = Depends(oauth2_scheme)):
|
||||||
user = await AuthService.get_current_user(token, db)
|
async with get_db() as db:
|
||||||
logger.info(f"User {user} is uploading a file")
|
user = await AuthService.get_current_user(token, db)
|
||||||
return await UploadService.upload_image_to_s3(file, user["id"])
|
logger.info(f"User {user} is uploading a file")
|
||||||
|
return await UploadService.upload_image_to_s3(file, user["id"])
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from fastapi.security import OAuth2PasswordBearer
|
from fastapi.security import OAuth2PasswordBearer
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
|
||||||
from services.user_service import UserService
|
from services.user_service import UserService
|
||||||
from models.schemas import UserUpdateRole, UserBlockBan, UserResponse
|
from models.schemas import UserUpdateRole, UserBlockBan, UserResponse
|
||||||
from config.database import get_db
|
from config.database import get_db
|
||||||
|
|
@ -11,29 +10,36 @@ router = APIRouter()
|
||||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
||||||
|
|
||||||
@router.get("/", response_model=list[UserResponse])
|
@router.get("/", response_model=list[UserResponse])
|
||||||
async def list_users(status: Optional[str] = None, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def list_users(status: Optional[str] = None, token: str = Depends(oauth2_scheme)):
|
||||||
return await UserService.list_users(token, status, db)
|
async with get_db() as db:
|
||||||
|
return await UserService.list_users(token, status, db)
|
||||||
|
|
||||||
@router.patch("/role", status_code=200)
|
@router.patch("/role", status_code=200)
|
||||||
async def change_role(user_update: UserUpdateRole, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def change_role(user_update: UserUpdateRole, token: str = Depends(oauth2_scheme)):
|
||||||
return await UserService.change_user_role(user_update, db, token)
|
async with get_db() as db:
|
||||||
|
return await UserService.change_user_role(user_update, db, token)
|
||||||
|
|
||||||
@router.post("/block", status_code=200)
|
@router.post("/block", status_code=200)
|
||||||
async def block_user(user_action: UserBlockBan, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def block_user(user_action: UserBlockBan, token: str = Depends(oauth2_scheme)):
|
||||||
return await UserService.block_user(user_action, db, token)
|
async with get_db() as db:
|
||||||
|
return await UserService.block_user(user_action, db, token)
|
||||||
|
|
||||||
@router.post("/ban", status_code=200)
|
@router.post("/ban", status_code=200)
|
||||||
async def ban_user(user_action: UserBlockBan, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def ban_user(user_action: UserBlockBan, token: str = Depends(oauth2_scheme)):
|
||||||
return await UserService.ban_user(user_action, db, token)
|
async with get_db() as db:
|
||||||
|
return await UserService.ban_user(user_action, db, token)
|
||||||
|
|
||||||
@router.post("/unblock", status_code=200)
|
@router.post("/unblock", status_code=200)
|
||||||
async def unblock_user(user_action: UserBlockBan, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def unblock_user(user_action: UserBlockBan, token: str = Depends(oauth2_scheme)):
|
||||||
return await UserService.unblock_user(user_action, db, token)
|
async with get_db() as db:
|
||||||
|
return await UserService.unblock_user(user_action, db, token)
|
||||||
|
|
||||||
@router.post("/unban", status_code=200)
|
@router.post("/unban", status_code=200)
|
||||||
async def unban_user(user_action: UserBlockBan, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def unban_user(user_action: UserBlockBan, token: str = Depends(oauth2_scheme)):
|
||||||
return await UserService.unban_user(user_action, db, token)
|
async with get_db() as db:
|
||||||
|
return await UserService.unban_user(user_action, db, token)
|
||||||
|
|
||||||
@router.get("/getuserbymail", response_model=UserResponse)
|
@router.get("/getuserbymail", response_model=UserResponse)
|
||||||
async def get_user_by_email(email: str, db=Depends(get_db), token: str = Depends(oauth2_scheme)):
|
async def get_user_by_email(email: str, token: str = Depends(oauth2_scheme)):
|
||||||
return await UserService.get_user_by_email(email, db, token)
|
async with get_db() as db:
|
||||||
|
return await UserService.get_user_by_email(email, db, token)
|
||||||
|
|
@ -1,14 +1,46 @@
|
||||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
from config.settings import settings
|
from config.settings import settings
|
||||||
import logging
|
import logging
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
DATABASE_URL = settings.database_url
|
DATABASE_URL = settings.database_url
|
||||||
engine = create_async_engine(DATABASE_URL, echo=True)
|
|
||||||
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
# Configuration optimisée du moteur
|
||||||
|
engine = create_async_engine(
|
||||||
|
DATABASE_URL,
|
||||||
|
echo=True,
|
||||||
|
pool_size=5,
|
||||||
|
max_overflow=10,
|
||||||
|
pool_timeout=30,
|
||||||
|
pool_recycle=1800,
|
||||||
|
pool_pre_ping=True
|
||||||
|
)
|
||||||
|
|
||||||
|
AsyncSessionLocal = sessionmaker(
|
||||||
|
engine,
|
||||||
|
class_=AsyncSession,
|
||||||
|
expire_on_commit=False,
|
||||||
|
autocommit=False,
|
||||||
|
autoflush=False
|
||||||
|
)
|
||||||
|
|
||||||
|
@asynccontextmanager
|
||||||
|
async def get_db():
|
||||||
|
session = AsyncSessionLocal()
|
||||||
|
try:
|
||||||
|
yield session
|
||||||
|
await session.commit()
|
||||||
|
except SQLAlchemyError as e:
|
||||||
|
await session.rollback()
|
||||||
|
logger.error(f"Database error: {str(e)}")
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
await session.close()
|
||||||
|
|
||||||
async def init_db():
|
async def init_db():
|
||||||
from models.db import metadata
|
from models.db import metadata
|
||||||
|
|
@ -18,8 +50,4 @@ async def init_db():
|
||||||
logger.info("Database tables created successfully.")
|
logger.info("Database tables created successfully.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error creating database tables: {str(e)}")
|
logger.error(f"Error creating database tables: {str(e)}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
async def get_db():
|
|
||||||
async with AsyncSessionLocal() as session:
|
|
||||||
yield session
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||||
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from config.settings import settings
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
DATABASE_URL = settings.database_url
|
||||||
|
engine = create_async_engine(DATABASE_URL, echo=True)
|
||||||
|
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||||
|
|
||||||
|
async def init_db():
|
||||||
|
from models.db import metadata
|
||||||
|
try:
|
||||||
|
async with engine.begin() as conn:
|
||||||
|
await conn.run_sync(metadata.create_all)
|
||||||
|
logger.info("Database tables created successfully.")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error creating database tables: {str(e)}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
async def get_db():
|
||||||
|
async with AsyncSessionLocal() as session:
|
||||||
|
yield session
|
||||||
Loading…
Reference in New Issue