🔍 Code Extractor

function update_user

Maturity: 60

Updates an existing user's information in a Neo4j database, including profile fields, password, and role assignments.

File:
/tf/active/vicechatdev/CDocs/controllers/admin_controller.py
Lines:
275 - 354
Complexity:
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

  • CDocs
  • hashlib

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

Similar Components

AI-powered semantic similarity - components with related functionality:

  • function update_user_v1 75.0% similar

    Updates user information in a Neo4j graph database, including username, full name, email, department, and active status, with automatic audit logging.

    From: /tf/active/vicechatdev/CDocs/controllers/admin_controller.py
  • function create_user 66.7% similar

    Creates a new user in the system with validation, password hashing, and role assignment, including CDocs user extension setup.

    From: /tf/active/vicechatdev/CDocs/controllers/admin_controller.py
  • function get_user_by_id 65.1% similar

    Retrieves user data from a Neo4j graph database by user ID, including associated roles and formatted name fields.

    From: /tf/active/vicechatdev/CDocs/controllers/admin_controller.py
  • function update_node 61.0% similar

    Updates properties of a Neo4j graph database node identified by its unique UID, automatically adding a modification timestamp.

    From: /tf/active/vicechatdev/CDocs/db/db_operations.py
  • function update_document 58.9% similar

    Updates properties of a controlled document including title, description, status, owner, and metadata, with special handling for status transitions that require format conversions or publishing workflows.

    From: /tf/active/vicechatdev/document_controller_backup.py
← Back to Browse