function update_user
Updates an existing user's information in a Neo4j database, including profile fields, password, and role assignments.
/tf/active/vicechatdev/CDocs/controllers/admin_controller.py
275 - 354
moderate
Purpose
This function provides a comprehensive user update mechanism for a document management system. It handles updating user profile information (username, email, name, department), password hashing, and role management. The function maps input fields to Neo4j node properties, constructs a full name from first/last name components, securely hashes passwords using SHA256, and manages user roles through the DocUser model. It's designed to work with a graph database backend and includes error handling with logging.
Source Code
def update_user(user_id: str, user_data: Dict[str, Any]) -> bool:
"""
Update an existing user.
Args:
user_id: UID of user to update
user_data: Dictionary with user information to update
Returns:
Boolean indicating success
"""
try:
# Create update properties dictionary
update_props = {}
# Map fields to node properties with correct lowercase 'department'
field_mapping = {
'username': 'username',
'email': 'Mail', # Use correct Neo4j field name 'Mail'
'first_name': 'first_name',
'last_name': 'last_name',
'department': 'department', # Corrected to lowercase
'department_id': 'department', # Alternative field name mapping to lowercase
'active': 'active'
}
# Update Name if first_name or last_name provided
if 'first_name' in user_data or 'last_name' in user_data:
# Get current user data to merge with updates
users = get_users(user_id=user_id)
if not users:
raise ResourceNotFoundError(f"User {user_id} not found")
current_user = users[0]
# Update Name field
first_name = user_data.get('first_name', current_user.get('first_name', ''))
last_name = user_data.get('last_name', current_user.get('last_name', ''))
update_props['Name'] = f"{first_name} {last_name}".strip()
# Add other fields to update properties
for field, prop in field_mapping.items():
if field in user_data and user_data[field] is not None:
update_props[prop] = user_data[field]
# Update password if provided
if 'password' in user_data and user_data['password']:
# In a real system, use a proper password hashing library
import hashlib
update_props["password"] = hashlib.sha256(
user_data['password'].encode()
).hexdigest()
# Update node properties
if update_props:
db.update_node(user_id, update_props)
# Handle roles if provided (this part is correct)
if 'roles' in user_data:
# Create DocUser instance to manage roles
from CDocs.models.user_extensions import DocUser
doc_user = DocUser(uid=user_id)
# Get current roles
current_roles = doc_user.roles
# Remove roles that aren't in the new set
for role in current_roles:
if role != 'VIEWER' and role not in user_data['roles']:
doc_user.remove_role(role)
# Add new roles
for role in user_data['roles']:
if role in settings.USER_ROLES and role not in current_roles:
doc_user.add_role(role)
return True
except Exception as e:
logger.error(f"Error updating user: {e}")
raise
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
user_id |
str | - | positional_or_keyword |
user_data |
Dict[str, Any] | - | positional_or_keyword |
Parameter Details
user_id: String UID (unique identifier) of the user to update in the database. Must correspond to an existing user node in Neo4j.
user_data: Dictionary containing user information fields to update. Supported keys include: 'username' (str), 'email' (str), 'first_name' (str), 'last_name' (str), 'department' or 'department_id' (str), 'active' (bool), 'password' (str - will be hashed), 'roles' (list of role strings). Only provided fields will be updated; omitted fields remain unchanged.
Return Value
Type: bool
Returns a boolean value: True if the user update operation completed successfully, or raises an exception if an error occurs during the update process.
Dependencies
CDocshashlib
Required Imports
from typing import Dict, Any
import logging
from CDocs import db
from CDocs.config import settings
Conditional/Optional Imports
These imports are only needed under specific conditions:
import hashlib
Condition: only when 'password' field is provided in user_data
Required (conditional)from CDocs.models.user_extensions import DocUser
Condition: only when 'roles' field is provided in user_data, or when first_name/last_name are updated (to fetch current user data)
Required (conditional)Usage Example
# Assuming CDocs is properly configured and connected to Neo4j
from typing import Dict, Any
import logging
from CDocs import db
from CDocs.config import settings
# Setup logger
logger = logging.getLogger(__name__)
# Update user profile information
user_id = "user-123-abc"
user_updates = {
'first_name': 'John',
'last_name': 'Doe',
'email': 'john.doe@example.com',
'department': 'Engineering',
'active': True
}
try:
success = update_user(user_id, user_updates)
print(f"User updated: {success}")
except Exception as e:
print(f"Failed to update user: {e}")
# Update password and roles
user_updates_with_roles = {
'password': 'newSecurePassword123',
'roles': ['EDITOR', 'REVIEWER']
}
success = update_user(user_id, user_updates_with_roles)
print(f"Password and roles updated: {success}")
Best Practices
- Always validate user_id exists before calling this function to avoid ResourceNotFoundError
- The function uses SHA256 for password hashing, which is noted as needing replacement with a proper password hashing library (e.g., bcrypt, argon2) in production
- Only include fields in user_data that need to be updated; omitted fields will not be modified
- When updating first_name or last_name, the function fetches current user data to construct the full Name field, so ensure get_users() is available
- Role updates require the role names to exist in settings.USER_ROLES; invalid roles will be ignored
- The 'VIEWER' role is treated specially and cannot be removed through this function
- Ensure proper error handling around this function as it can raise multiple exception types (ResourceNotFoundError, general Exception)
- The function uses field_mapping to translate between API field names and Neo4j property names; be aware of this mapping when debugging
- Database transactions are handled by db.update_node(); ensure your db module supports atomic updates
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function update_user_v1 75.0% similar
-
function create_user 66.7% similar
-
function get_user_by_id 65.1% similar
-
function update_node 61.0% similar
-
function update_document 58.9% similar