163 lines
5.5 KiB
Python
163 lines
5.5 KiB
Python
from typing import List, Optional
|
||
|
||
from fastapi import APIRouter, Depends, Query, status
|
||
from sqlalchemy.ext.asyncio import AsyncConnection
|
||
|
||
from api.db.connection.session import get_connection_dep
|
||
from api.db.logic.account import get_user_by_login
|
||
from api.schemas.account.account import User
|
||
from api.schemas.base import bearer_schema
|
||
from api.schemas.endpoints.account import AllUserResponse, UserCreate, UserUpdate, UserFilterDTO
|
||
from api.services.auth import get_current_user
|
||
from api.services.user_role_validation import UserRoleValidator
|
||
from api.error import create_operation_error, create_validation_error
|
||
from api.services.endpoints.account import AccountService
|
||
|
||
api_router = APIRouter(
|
||
prefix="/account",
|
||
tags=["User accountModel"],
|
||
)
|
||
|
||
|
||
@api_router.get("", dependencies=[Depends(bearer_schema)], response_model=AllUserResponse)
|
||
async def get_all_account_endpoint(
|
||
page: int = Query(1, description="Page number", gt=0),
|
||
limit: int = Query(10, description="КNumber of items per page", gt=0),
|
||
search: Optional[str] = Query(None, description="Search term to filter by name or login or email"),
|
||
status_filter: Optional[List[str]] = Query(None, description="Filter by status"),
|
||
role_filter: Optional[List[str]] = Query(None, description="Filter by role"),
|
||
creator_id: Optional[int] = Query(None, description="Filter by creator id"),
|
||
order_field: Optional[str] = Query("id", description="Field to sort by"),
|
||
order_direction: Optional[str] = Query("asc", description="Sort direction (asc/desc)"),
|
||
connection: AsyncConnection = Depends(get_connection_dep),
|
||
current_user=Depends(get_current_user),
|
||
):
|
||
validator = UserRoleValidator(connection)
|
||
await validator.validate_admin(current_user)
|
||
|
||
filters = {
|
||
**({"status": status_filter} if status_filter else {}),
|
||
**({"role": role_filter} if role_filter else {}),
|
||
**({"creator_id": [str(creator_id)]} if creator_id else {}),
|
||
}
|
||
|
||
filter_dto = UserFilterDTO(
|
||
pagination={"page": page, "limit": limit},
|
||
search=search,
|
||
order={"field": order_field, "direction": order_direction},
|
||
filters=filters if filters else None,
|
||
)
|
||
|
||
service = AccountService(connection)
|
||
user_list = await service.list(filter_dto)
|
||
|
||
if user_list is None:
|
||
raise create_operation_error(
|
||
message="Accounts not found",
|
||
status_code=status.HTTP_404_NOT_FOUND,
|
||
)
|
||
|
||
return user_list
|
||
|
||
|
||
@api_router.get("/{user_id}", dependencies=[Depends(bearer_schema)], response_model=User)
|
||
async def get_account_endpoint(
|
||
user_id: int,
|
||
connection: AsyncConnection = Depends(get_connection_dep),
|
||
current_user=Depends(get_current_user),
|
||
):
|
||
validator = UserRoleValidator(connection)
|
||
await validator.validate_admin(current_user)
|
||
|
||
service = AccountService(connection)
|
||
user = await service.get(user_id)
|
||
|
||
if user is None:
|
||
raise create_operation_error(
|
||
message="Account not found",
|
||
status_code=status.HTTP_404_NOT_FOUND,
|
||
details={"user_id": user_id},
|
||
)
|
||
|
||
return user
|
||
|
||
|
||
@api_router.post("", dependencies=[Depends(bearer_schema)], response_model=User)
|
||
async def create_account_endpoint(
|
||
user: UserCreate,
|
||
connection: AsyncConnection = Depends(get_connection_dep),
|
||
current_user=Depends(get_current_user),
|
||
):
|
||
validator = UserRoleValidator(connection)
|
||
authorize_user = await validator.validate_admin(current_user)
|
||
|
||
user_validation = await get_user_by_login(connection, user.login)
|
||
|
||
if user_validation is None:
|
||
service = AccountService(connection)
|
||
new_user = await service.create(user_data=user, creator_id=authorize_user.id)
|
||
return new_user
|
||
else:
|
||
raise create_validation_error(
|
||
message="An account with this information already exists.",
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
details={"login": user.login},
|
||
)
|
||
|
||
|
||
@api_router.put("/{user_id}", dependencies=[Depends(bearer_schema)], response_model=UserUpdate)
|
||
async def update_account_endpoint(
|
||
user_id: int,
|
||
user_update: UserUpdate,
|
||
connection: AsyncConnection = Depends(get_connection_dep),
|
||
current_user=Depends(get_current_user),
|
||
):
|
||
validator = UserRoleValidator(connection)
|
||
await validator.validate_admin(current_user)
|
||
|
||
service = AccountService(connection)
|
||
user = await service.get(user_id)
|
||
|
||
if user is None:
|
||
raise create_operation_error(
|
||
message="Account not found",
|
||
status_code=status.HTTP_404_NOT_FOUND,
|
||
details={"user_id": user_id},
|
||
)
|
||
|
||
updated_values = user_update.model_dump(by_alias=True, exclude_none=True)
|
||
|
||
if not updated_values:
|
||
return user
|
||
|
||
updated_user = await service.update(
|
||
user_id=user_id,
|
||
user_update_data=updated_values,
|
||
password=user_update.password,
|
||
)
|
||
|
||
return updated_user
|
||
|
||
|
||
@api_router.delete("/{user_id}", dependencies=[Depends(bearer_schema)], response_model=User)
|
||
async def delete_account_endpoint(
|
||
user_id: int,
|
||
connection: AsyncConnection = Depends(get_connection_dep),
|
||
current_user=Depends(get_current_user),
|
||
):
|
||
validator = UserRoleValidator(connection)
|
||
await validator.validate_admin(current_user)
|
||
|
||
service = AccountService(connection)
|
||
user = await service.get(user_id)
|
||
|
||
if user is None:
|
||
raise create_operation_error(
|
||
message="Account not found",
|
||
status_code=status.HTTP_404_NOT_FOUND,
|
||
details={"user_id": user_id},
|
||
)
|
||
deleted_user = await service.delete(user_id=user_id)
|
||
|
||
return deleted_user
|