Browse Source

refac: role update ui

Timothy Jaeryang Baek 4 weeks ago
parent
commit
e41e375aab

+ 1 - 0
backend/open_webui/models/users.py

@@ -95,6 +95,7 @@ class UserRoleUpdateForm(BaseModel):
 
 
 
 
 class UserUpdateForm(BaseModel):
 class UserUpdateForm(BaseModel):
+    role: str
     name: str
     name: str
     email: str
     email: str
     profile_image_url: str
     profile_image_url: str

+ 17 - 21
backend/open_webui/routers/users.py

@@ -165,22 +165,6 @@ async def update_default_user_permissions(
     return request.app.state.config.USER_PERMISSIONS
     return request.app.state.config.USER_PERMISSIONS
 
 
 
 
-############################
-# UpdateUserRole
-############################
-
-
-@router.post("/update/role", response_model=Optional[UserModel])
-async def update_user_role(form_data: UserRoleUpdateForm, user=Depends(get_admin_user)):
-    if user.id != form_data.id and form_data.id != Users.get_first_user().id:
-        return Users.update_user_role_by_id(form_data.id, form_data.role)
-
-    raise HTTPException(
-        status_code=status.HTTP_403_FORBIDDEN,
-        detail=ERROR_MESSAGES.ACTION_PROHIBITED,
-    )
-
-
 ############################
 ############################
 # GetUserSettingsBySessionUser
 # GetUserSettingsBySessionUser
 ############################
 ############################
@@ -333,11 +317,22 @@ async def update_user_by_id(
     # Prevent modification of the primary admin user by other admins
     # Prevent modification of the primary admin user by other admins
     try:
     try:
         first_user = Users.get_first_user()
         first_user = Users.get_first_user()
-        if first_user and user_id == first_user.id and session_user.id != user_id:
-            raise HTTPException(
-                status_code=status.HTTP_403_FORBIDDEN,
-                detail=ERROR_MESSAGES.ACTION_PROHIBITED,
-            )
+        if first_user:
+            if user_id == first_user.id:
+                if session_user.id != user_id:
+                    # If the user trying to update is the primary admin, and they are not the primary admin themselves
+                    raise HTTPException(
+                        status_code=status.HTTP_403_FORBIDDEN,
+                        detail=ERROR_MESSAGES.ACTION_PROHIBITED,
+                    )
+
+                if form_data.role != "admin":
+                    # If the primary admin is trying to change their own role, prevent it
+                    raise HTTPException(
+                        status_code=status.HTTP_403_FORBIDDEN,
+                        detail=ERROR_MESSAGES.ACTION_PROHIBITED,
+                    )
+
     except Exception as e:
     except Exception as e:
         log.error(f"Error checking primary admin status: {e}")
         log.error(f"Error checking primary admin status: {e}")
         raise HTTPException(
         raise HTTPException(
@@ -365,6 +360,7 @@ async def update_user_by_id(
         updated_user = Users.update_user_by_id(
         updated_user = Users.update_user_by_id(
             user_id,
             user_id,
             {
             {
+                "role": form_data.role,
                 "name": form_data.name,
                 "name": form_data.name,
                 "email": form_data.email.lower(),
                 "email": form_data.email.lower(),
                 "profile_image_url": form_data.profile_image_url,
                 "profile_image_url": form_data.profile_image_url,

+ 1 - 0
src/lib/apis/users/index.ts

@@ -393,6 +393,7 @@ export const updateUserById = async (token: string, userId: string, user: UserUp
 		},
 		},
 		body: JSON.stringify({
 		body: JSON.stringify({
 			profile_image_url: user.profile_image_url,
 			profile_image_url: user.profile_image_url,
+			role: user.role,
 			email: user.email,
 			email: user.email,
 			name: user.name,
 			name: user.name,
 			password: user.password !== '' ? user.password : undefined
 			password: user.password !== '' ? user.password : undefined

+ 1 - 37
src/lib/components/admin/Users/UserList.svelte

@@ -52,27 +52,6 @@
 
 
 	let showUserChatsModal = false;
 	let showUserChatsModal = false;
 	let showEditUserModal = false;
 	let showEditUserModal = false;
-	let showUpdateRoleModal = false;
-
-	const onUpdateRole = (user) => {
-		if (user.role === 'user') {
-			updateRoleHandler(user.id, 'admin');
-		} else if (user.role === 'pending') {
-			updateRoleHandler(user.id, 'user');
-		} else {
-			updateRoleHandler(user.id, 'pending');
-		}
-	};
-	const updateRoleHandler = async (id, role) => {
-		const res = await updateUserRole(localStorage.token, id, role).catch((error) => {
-			toast.error(`${error}`);
-			return null;
-		});
-
-		if (res) {
-			getUserList();
-		}
-	};
 
 
 	const deleteUserHandler = async (id) => {
 	const deleteUserHandler = async (id) => {
 		const res = await deleteUserById(localStorage.token, id).catch((error) => {
 		const res = await deleteUserById(localStorage.token, id).catch((error) => {
@@ -133,21 +112,6 @@
 	}}
 	}}
 />
 />
 
 
-<RoleUpdateConfirmDialog
-	bind:show={showUpdateRoleModal}
-	on:confirm={() => {
-		onUpdateRole(selectedUser);
-	}}
-	message={$i18n.t(`Are you sure you want to update this user\'s role to **{{ROLE}}**?`, {
-		ROLE:
-			selectedUser?.role === 'user'
-				? 'admin'
-				: selectedUser?.role === 'pending'
-					? 'user'
-					: 'pending'
-	})}
-/>
-
 {#key selectedUser}
 {#key selectedUser}
 	<EditUserModal
 	<EditUserModal
 		bind:show={showEditUserModal}
 		bind:show={showEditUserModal}
@@ -415,7 +379,7 @@
 								class=" translate-y-0.5"
 								class=" translate-y-0.5"
 								on:click={() => {
 								on:click={() => {
 									selectedUser = user;
 									selectedUser = user;
-									showUpdateRoleModal = true;
+									showEditUserModal = !showEditUserModal;
 								}}
 								}}
 							>
 							>
 								<Badge
 								<Badge

+ 18 - 0
src/lib/components/admin/Users/UserList/EditUserModal.svelte

@@ -19,6 +19,7 @@
 
 
 	let _user = {
 	let _user = {
 		profile_image_url: '',
 		profile_image_url: '',
+		role: 'pending',
 		name: '',
 		name: '',
 		email: '',
 		email: '',
 		password: ''
 		password: ''
@@ -95,6 +96,23 @@
 
 
 					<div class=" px-5 pt-3 pb-5">
 					<div class=" px-5 pt-3 pb-5">
 						<div class=" flex flex-col space-y-1.5">
 						<div class=" flex flex-col space-y-1.5">
+							<div class="flex flex-col w-full">
+								<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Role')}</div>
+
+								<div class="flex-1">
+									<select
+										class="w-full rounded-sm text-sm bg-transparent disabled:text-gray-500 dark:disabled:text-gray-500 outline-hidden"
+										bind:value={_user.role}
+										disabled={_user.id == sessionUser.id}
+										required
+									>
+										<option value="admin">{$i18n.t('Admin')}</option>
+										<option value="user">{$i18n.t('User')}</option>
+										<option value="pending">{$i18n.t('Pending')}</option>
+									</select>
+								</div>
+							</div>
+
 							<div class="flex flex-col w-full">
 							<div class="flex flex-col w-full">
 								<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Email')}</div>
 								<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Email')}</div>