Files
rentman-clone/backend/app/api/v1/roles.py
T

89 lines
2.9 KiB
Python
Raw Normal View History

"""Role management endpoints (admin)."""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.api.deps import require_permission
from app.db.session import get_async_session
from app.models import User, Role
from app.schemas.role import RoleCreateRequest, RoleUpdateRequest, RoleResponse
router = APIRouter(prefix="/roles", tags=["roles"])
@router.get("", response_model=list[RoleResponse])
async def list_roles(
current_user: User = Depends(require_permission("roles:read")),
session: AsyncSession = Depends(get_async_session),
):
"""List all roles within the current account."""
account_id = current_user.account_id
result = await session.execute(
select(Role).where(Role.account_id == account_id).order_by(Role.name)
)
roles = result.scalars().all()
return [RoleResponse.model_validate(r) for r in roles]
@router.post("", response_model=RoleResponse, status_code=status.HTTP_201_CREATED)
async def create_role(
body: RoleCreateRequest,
current_user: User = Depends(require_permission("roles:write")),
session: AsyncSession = Depends(get_async_session),
):
"""Create a new role within the current account."""
account_id = current_user.account_id
# Check name uniqueness within account
existing = await session.execute(
select(Role).where(Role.account_id == account_id, Role.name == body.name)
)
if existing.scalars().first():
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="A role with this name already exists in your account",
)
role = Role(
account_id=account_id,
name=body.name,
description=body.description,
permissions=body.permissions,
)
session.add(role)
await session.commit()
await session.refresh(role)
return RoleResponse.model_validate(role)
@router.put("/{role_id}", response_model=RoleResponse)
async def update_role(
role_id: str,
body: RoleUpdateRequest,
current_user: User = Depends(require_permission("roles:write")),
session: AsyncSession = Depends(get_async_session),
):
"""Update a role's permissions, name, or description."""
account_id = current_user.account_id
result = await session.execute(
select(Role).where(Role.id == role_id, Role.account_id == account_id)
)
role = result.scalars().first()
if not role:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Role not found",
)
if body.name is not None:
role.name = body.name
if body.description is not None:
role.description = body.description
if body.permissions is not None:
role.permissions = body.permissions
await session.commit()
await session.refresh(role)
return RoleResponse.model_validate(role)