From c99f4d898629676e8b9031ca55a8993db4cabbd5 Mon Sep 17 00:00:00 2001 From: gulimabr Date: Mon, 19 Jan 2026 15:20:10 -0300 Subject: [PATCH] fixed project admin being able to create superadmin users --- backend/src/main.py | 14 ++++++++++++++ frontend/src/pages/AdminPage.tsx | 13 +++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/backend/src/main.py b/backend/src/main.py index 083e903..9eb2544 100644 --- a/backend/src/main.py +++ b/backend/src/main.py @@ -740,6 +740,13 @@ async def update_member_role( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid role id {role_data.role_id}" ) + + allowed_role_names = {"editor", "auditor", "admin", "viewer"} + if role.role_name not in allowed_role_names: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Project admins cannot assign this role" + ) # Update the user's role from src.repositories import UserRepository @@ -798,6 +805,13 @@ async def create_project_user( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid role id {user_data.role_id}" ) + + allowed_role_names = {"editor", "auditor", "admin", "viewer"} + if role.role_name not in allowed_role_names: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Project admins cannot create users with this role" + ) # Create user in Keycloak keycloak_sub = await KeycloakAdminService.create_user( diff --git a/frontend/src/pages/AdminPage.tsx b/frontend/src/pages/AdminPage.tsx index d446659..57d5dcc 100644 --- a/frontend/src/pages/AdminPage.tsx +++ b/frontend/src/pages/AdminPage.tsx @@ -82,6 +82,9 @@ export default function AdminPage() { // Check if user is admin const isAdmin = user?.role_id === 3 + const allowedRoleNames = ['editor', 'auditor', 'admin', 'viewer'] + const allowedRoles = roles.filter(role => allowedRoleNames.includes(role.role_name)) + // Redirect if not admin useEffect(() => { if (!isAdmin) { @@ -539,6 +542,12 @@ export default function AdminPage() { {members.map((member) => { const isCurrentUser = member.id === user?.db_user_id + const roleOptions = allowedRoleNames.includes(member.role_name) + ? allowedRoles + : [ + ...allowedRoles, + ...roles.filter(role => role.id === member.role_id) + ] return ( @@ -575,7 +584,7 @@ export default function AdminPage() { }`} title={isCurrentUser && member.role_id === 3 ? t('memberRoles.cannotDemoteSelf') : ''} > - {roles.map((role) => ( + {roleOptions.map((role) => ( @@ -1011,7 +1020,7 @@ export default function AdminPage() { onChange={(e) => setNewRoleId(parseInt(e.target.value))} className="w-full px-3 py-2 border border-gray-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-teal-500" > - {roles.map((role) => ( + {allowedRoles.map((role) => (