After_Chido_Api/services/user_service.py

131 lines
4.8 KiB
Python

from sqlalchemy import select, update, insert
from fastapi import Depends, HTTPException, status
from models.schemas import UserCreate, UserResponse, UserUpdateRole, UserBlockBan
from config.database import get_db
from models.db import users_table
from services.auth_service import AuthService
from utils.security import get_password_hash
from typing import Optional
from utils.logging import logger
class UserService:
@staticmethod
async def list_users(token: str, status: Optional[str] = None, db=Depends(get_db)):
await AuthService.check_permissions(token, db, ["admin","collectivité","état"] )
query = select(users_table)
if status:
query = query.where(users_table.c.status == status)
result = await db.execute(query)
users = result.mappings().all()
return [UserResponse(**user) for user in users]
@staticmethod
async def create_user(user: UserCreate, db):
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,
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
async def change_user_role(user_update: UserUpdateRole, db, token: str):
await AuthService.check_permissions(token, db, ["admin"])
query = (
update(users_table)
.where(users_table.c.email == user_update.email)
.values(role=user_update.new_role)
)
result = await db.execute(query)
await db.commit()
if result.rowcount == 0:
raise HTTPException(status_code=404, detail="User not found")
return {"message": f"Role updated to {user_update.new_role}"}
@staticmethod
async def block_user(user_action: UserBlockBan, db, token: str):
await AuthService.admin_required(token, db)
query = (
update(users_table)
.where(users_table.c.email == user_action.email)
.values(is_blocked=True)
)
result = await db.execute(query)
await db.commit()
if result.rowcount == 0:
raise HTTPException(status_code=404, detail="User not found")
return {"message": f"User {user_action.email} blocked"}
@staticmethod
async def ban_user(user_action: UserBlockBan, db, token: str):
await AuthService.admin_required(token, db)
query = (
update(users_table)
.where(users_table.c.email == user_action.email)
.values(is_banned=True)
)
result = await db.execute(query)
await db.commit()
if result.rowcount == 0:
raise HTTPException(status_code=404, detail="User not found")
return {"message": f"User {user_action.email} banned"}
@staticmethod
async def unblock_user(user_action: UserBlockBan, db, token: str):
await AuthService.admin_required(token, db)
query = (
update(users_table)
.where(users_table.c.email == user_action.email)
.values(is_blocked=False)
)
result = await db.execute(query)
await db.commit()
if result.rowcount == 0:
raise HTTPException(status_code=404, detail="User not found")
return {"message": f"User {user_action.email} unblocked"}
@staticmethod
async def unban_user(user_action: UserBlockBan, db, token: str):
await AuthService.admin_required(token, db)
query = (
update(users_table)
.where(users_table.c.email == user_action.email)
.values(is_banned=False)
)
result = await db.execute(query)
await db.commit()
if result.rowcount == 0:
raise HTTPException(status_code=404, detail="User not found")
return {"message": f"User {user_action.email} unbanned"}