-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathroles.py
More file actions
128 lines (101 loc) · 3.56 KB
/
Copy pathroles.py
File metadata and controls
128 lines (101 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"""API endpoints for role management."""
from __future__ import annotations
from typing import Any
from fastapi import APIRouter, Depends, HTTPException, Request
from pydantic import BaseModel
from sqlalchemy import select
from fastapi_admin_kit.api.deps import require_api_superuser
from fastapi_admin_kit.auth.models import AdminRole
from fastapi_admin_kit.db import get_db_session
router = APIRouter(prefix="/roles", tags=["api-roles"])
class RoleCreate(BaseModel):
name: str
description: str = ""
class RoleUpdate(BaseModel):
name: str | None = None
description: str | None = None
class RoleResponse(BaseModel):
id: int
name: str
description: str | None = None
user_count: int = 0
@router.get("/", response_model=list[RoleResponse])
async def list_roles(
request: Request,
user: dict[str, Any] = Depends(require_api_superuser()),
) -> list[RoleResponse]:
"""GET /api/roles/ — list all roles (superuser only)."""
db_session = get_db_session(request)
result = await db_session.execute(select(AdminRole))
roles = result.scalars().all()
return [
RoleResponse(
id=r.id,
name=r.name,
description=r.description,
user_count=len(r.users),
)
for r in roles
]
@router.post("/", response_model=RoleResponse, status_code=201)
async def create_role(
request: Request,
body: RoleCreate,
user: dict[str, Any] = Depends(require_api_superuser()),
) -> RoleResponse:
"""POST /api/roles/ — create a role (superuser only)."""
db_session = get_db_session(request)
existing = await db_session.execute(
select(AdminRole).where(AdminRole.name == body.name)
)
if existing.scalar_one_or_none():
raise HTTPException(status_code=400, detail="Role name already exists.")
role = AdminRole(name=body.name, description=body.description)
db_session.add(role)
await db_session.flush()
await db_session.refresh(role)
return RoleResponse(
id=role.id, name=role.name, description=role.description
)
@router.put("/{role_id}", response_model=RoleResponse)
async def update_role(
request: Request,
role_id: int,
body: RoleUpdate,
user: dict[str, Any] = Depends(require_api_superuser()),
) -> RoleResponse:
"""PUT /api/roles/{id} — update a role (superuser only)."""
db_session = get_db_session(request)
role = await db_session.get(AdminRole, role_id)
if role is None:
raise HTTPException(status_code=404, detail="Role not found.")
if body.name is not None:
role.name = body.name
if body.description is not None:
role.description = body.description
await db_session.flush()
await db_session.refresh(role)
return RoleResponse(
id=role.id,
name=role.name,
description=role.description,
user_count=len(role.users),
)
@router.delete("/{role_id}", status_code=204, response_model=None)
async def delete_role(
request: Request,
role_id: int,
user: dict[str, Any] = Depends(require_api_superuser()),
) -> None:
"""DELETE /api/roles/{id} — delete a role (superuser only)."""
db_session = get_db_session(request)
role = await db_session.get(AdminRole, role_id)
if role is None:
raise HTTPException(status_code=404, detail="Role not found.")
if len(role.users) > 0:
raise HTTPException(
status_code=400,
detail=f"Cannot delete role. {len(role.users)} user(s) are still assigned.",
)
await db_session.delete(role)
await db_session.flush()