Added user demotion functionality. (#1444)

This commit is contained in:
Ryan Gordon
2024-05-12 01:59:47 +03:00
committed by GitHub
parent 7a02fd7ad7
commit 5bf123da53
2 changed files with 99 additions and 47 deletions

View File

@@ -41,6 +41,27 @@ async def promote_admin(
return
@router.patch("/demote-admin-to-user")
async def demote_admin(
user_email: UserByEmail, user: User = Depends(current_admin_user)
) -> None:
if user.role != UserRole.ADMIN:
raise HTTPException(status_code=401, detail="Unauthorized")
async with AsyncSession(get_sqlalchemy_async_engine()) as asession:
user_db = SQLAlchemyUserDatabase[User, UUID_ID](asession, User)
user_to_demote = await user_db.get_by_email(user_email.user_email)
if not user_to_demote:
raise HTTPException(status_code=404, detail="User not found")
if user_to_demote.id == user.id:
raise HTTPException(
status_code=400, detail="Cannot demote yourself from admin role"
)
user_to_demote.role = UserRole.BASIC
asession.add(user_to_demote)
await asession.commit()
return
@router.get("/users")
def list_all_users(
_: User | None = Depends(current_admin_user),

View File

@@ -45,59 +45,90 @@ const UsersTable = () => {
<TableHeaderCell>Role</TableHeaderCell>
<TableHeaderCell>
<div className="flex">
<div className="ml-auto">Promote</div>
<div className="ml-auto">Actions</div>
</div>
</TableHeaderCell>
</TableRow>
</TableHead>
<TableBody>
{users.map((user) => {
return (
<TableRow key={user.id}>
<TableCell>{user.email}</TableCell>
<TableCell>
<i>{user.role === "admin" ? "Admin" : "User"}</i>
</TableCell>
<TableCell>
<div className="flex">
<div className="ml-auto">
<Button
onClick={async () => {
const res = await fetch(
"/api/manage/promote-user-to-admin",
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
user_email: user.email,
}),
}
);
if (!res.ok) {
const errorMsg = await res.text();
setPopup({
message: `Unable to promote user - ${errorMsg}`,
type: "error",
});
} else {
mutate("/api/manage/users");
setPopup({
message: "User promoted to admin!",
type: "success",
});
{users.map((user) => (
<TableRow key={user.id}>
<TableCell>{user.email}</TableCell>
<TableCell>
<i>{user.role === "admin" ? "Admin" : "User"}</i>
</TableCell>
<TableCell>
<div className="flex justify-end space-x-2">
{user.role !== "admin" && (
<Button
onClick={async () => {
const res = await fetch(
"/api/manage/promote-user-to-admin",
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
user_email: user.email,
}),
}
}}
>
Promote to Admin!
</Button>
</div>
</div>
</TableCell>
</TableRow>
);
})}
);
if (!res.ok) {
const errorMsg = await res.text();
setPopup({
message: `Unable to promote user - ${errorMsg}`,
type: "error",
});
} else {
mutate("/api/manage/users");
setPopup({
message: "User promoted to admin!",
type: "success",
});
}
}}
>
Promote to Admin!
</Button>
)}
{user.role === "admin" && (
<Button
onClick={async () => {
const res = await fetch(
"/api/manage/demote-admin-to-user",
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
user_email: user.email,
}),
}
);
if (!res.ok) {
const errorMsg = await res.text();
setPopup({
message: `Unable to demote admin - ${errorMsg}`,
type: "error",
});
} else {
mutate("/api/manage/users");
setPopup({
message: "Admin demoted to user!",
type: "success",
});
}
}}
>
Demote to User
</Button>
)}
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>