diff --git a/backend/open_webui/models/users.py b/backend/open_webui/models/users.py index e06e6957f..025e79bd8 100644 --- a/backend/open_webui/models/users.py +++ b/backend/open_webui/models/users.py @@ -239,15 +239,17 @@ class UserRoleUpdateForm(BaseModel): class UserUpdateForm(BaseModel): - role: str - name: str - email: str - profile_image_url: str + role: Optional[str] = None + name: Optional[str] = None + email: Optional[str] = None + profile_image_url: Optional[str] = None password: Optional[str] = None - @field_validator('profile_image_url') + @field_validator('profile_image_url', mode='before') @classmethod - def check_profile_image_url(cls, v: str) -> str: + def check_profile_image_url(cls, v: Optional[str]) -> Optional[str]: + if v is None: + return v return validate_profile_image_url(v) diff --git a/backend/open_webui/routers/users.py b/backend/open_webui/routers/users.py index 336e54c44..9fd2479ad 100644 --- a/backend/open_webui/routers/users.py +++ b/backend/open_webui/routers/users.py @@ -580,7 +580,7 @@ async def update_user_by_id( detail=ERROR_MESSAGES.ACTION_PROHIBITED, ) - if form_data.role != 'admin': + if form_data.role is not None and 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, @@ -597,7 +597,7 @@ async def update_user_by_id( user = await Users.get_user_by_id(user_id, db=db) if user: - if form_data.email.lower() != user.email: + if form_data.email is not None and form_data.email.lower() != user.email: email_user = await Users.get_user_by_email(form_data.email.lower(), db=db) if email_user: raise HTTPException( @@ -614,17 +614,26 @@ async def update_user_by_id( hashed = get_password_hash(form_data.password) await Auths.update_user_password_by_id(user_id, hashed, db=db) - await Auths.update_email_by_id(user_id, form_data.email.lower(), db=db) - updated_user = await Users.update_user_by_id( - user_id, - { - 'role': form_data.role, - 'name': form_data.name, - 'email': form_data.email.lower(), - 'profile_image_url': form_data.profile_image_url, - }, - db=db, - ) + # Build update dict from only the provided fields + update_data = {} + if form_data.role is not None: + update_data['role'] = form_data.role + if form_data.name is not None: + update_data['name'] = form_data.name + if form_data.email is not None: + update_data['email'] = form_data.email.lower() + await Auths.update_email_by_id(user_id, form_data.email.lower(), db=db) + if form_data.profile_image_url is not None: + update_data['profile_image_url'] = form_data.profile_image_url + + if update_data: + updated_user = await Users.update_user_by_id( + user_id, + update_data, + db=db, + ) + else: + updated_user = user if updated_user: # If the role changed, disconnect all socket sessions so stale