o
    "i                     @   s   d Z ddlmZmZ ddlmZ ddlZddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZmZ dd
lmZmZ ddlmZ eeZG dd dee
eef Zee
ZdS )z!
CRUD operations for User model.
    )OptionalList)SessionN)CRUDBase)User)Role)UserRole)
UserCreate
UserUpdate)get_password_hashverify_password)RBACBootstrapServicec                   @   sd  e Zd ZdZdddededee dee fdd	Z	ddded
edee dee fddZ
ddddededededee f
ddZddddededee dedef
ddZdedededee fddZdddeded ededef
d!d"Zdedefd#d$Zdedefd%d&Zdedefd'd(Zded)edee fd*d+Zded)ed,ee ddfd-d.ZdS )/CRUDUserzE
    CRUD operations for User model with authentication support.
    N)	tenant_iddbemailr   returnc                C   6   | ttj|k}|dur|tj|k}| S )z
        Get user by email.

        Args:
            db: Database session
            email: User email
            tenant_id: Optional tenant ID for filtering

        Returns:
            User instance or None
        N)queryr   filterr   r   first)selfr   r   r   r    r   5/lsinfo/ai/hellotax_ai/base_platform/app/crud/user.pyget_by_email      zCRUDUser.get_by_emailusernamec                C   r   )z
        Get user by username.

        Args:
            db: Database session
            username: Username
            tenant_id: Optional tenant ID for filtering

        Returns:
            User instance or None
        N)r   r   r   r   r   r   )r   r   r   r   r   r   r   r   get_by_username+   r   zCRUDUser.get_by_usernamer   d   )skiplimitr   r    c                C   s&   | ttj|k|| S )a  
        Get users by company ID.

        Args:
            db: Database session
            tenant_id: Company (tenant) ID
            skip: Number of records to skip
            limit: Maximum number of records to return

        Returns:
            List of user instances
        )r   r   r   r   offsetr    all)r   r   r   r   r    r   r   r   get_by_company>   s
   
zCRUDUser.get_by_companyT)
created_bycommitobj_inr$   r%   c             
   C   s   t |j|jt|j|j|jd}|| |rE|  |	| z	t
|| W |S  tyD } ztd|  W Y d}~|S d}~ww |S )a2  
        Create a new user with hashed password.

        Args:
            db: Database session
            obj_in: User creation schema
            created_by: User ID who created this user
            commit: Whether to commit the transaction

        Returns:
            Created user instance
        )r   namehashed_passwordr   rolezFailed to assign role: N)r   r   r'   r   passwordr   r)   addr%   refreshr   sync_user_role_binding	Exceptionloggerwarning)r   r   r&   r$   r%   db_objer   r   r   createV   s(   

zCRUDUser.creater*   c                C   s*   | j ||d}|sdS t||jsdS |S )a  
        Authenticate user by email and password.

        Args:
            db: Database session
            email: User email
            password: Plain text password

        Returns:
            User instance if authentication successful, None otherwise
        )r   N)r   r   r(   )r   r   r   r*   userr   r   r   authenticate   s   zCRUDUser.authenticate)r%   r4   new_passwordc                C   s.   t ||_|| |r|  || |S )a  
        Update user password.

        Args:
            db: Database session
            user: User instance
            new_password: New plain text password
            commit: Whether to commit the transaction

        Returns:
            Updated user instance
        )r   r(   r+   r%   r,   )r   r   r4   r6   r%   r   r   r   update_password   s   


zCRUDUser.update_passwordc                 C   s   |j S )z
        Check if user is active.

        Args:
            user: User instance

        Returns:
            True if user is active
        )	is_activer   r4   r   r   r   r8      s   
zCRUDUser.is_activec                 C   
   |j dkS )z
        Check if user is platform admin.

        Args:
            user: User instance

        Returns:
            True if user is platform admin
        platform_adminr)   r9   r   r   r   is_platform_admin      

zCRUDUser.is_platform_adminc                 C   r:   )z
        Check if user is customer admin.

        Args:
            user: User instance

        Returns:
            True if user is customer admin
        customer_adminr<   r9   r   r   r   is_customer_admin   r>   zCRUDUser.is_customer_adminuser_idc                C   s\   | ttj|ktjdk }dd |D }|sg S | ttj|tjdk S )z
        Get all roles for a user.

        Args:
            db: Database session
            user_id: User ID

        Returns:
            List of Role instances
        Fc                 S   s   g | ]}|j qS r   )role_id).0urr   r   r   
<listcomp>   s    z&CRUDUser.get_roles.<locals>.<listcomp>)	r   r   r   rA   
is_deletedr"   r   idin_)r   r   rA   
user_rolesrole_idsr   r   r   	get_roles   s   


zCRUDUser.get_rolesrJ   c                C   s^   | ttj|ktjdk }|D ]}d|_q|D ]}t||d}|| q|  dS )z
        Update roles for a user.

        Args:
            db: Database session
            user_id: User ID
            role_ids: List of role IDs to assign
        FT)rA   rB   N)r   r   r   rA   rF   r"   r+   r%   )r   r   rA   rJ   existingrD   rB   	user_roler   r   r   update_roles   s   

zCRUDUser.update_roles)__name__
__module____qualname____doc__r   strr   intr   r   r   r   r#   r	   boolr3   r5   r7   r8   r=   r@   r   rK   rN   r   r   r   r   r      sp    ((

)

"r   )rR   typingr   r   sqlalchemy.ormr   loggingapp.crud.baser   app.models.userr   app.models.roler   app.models.user_roler   app.schemas.userr	   r
   app.core.securityr   r   *app.services.access.rbac_bootstrap_servicer   	getLoggerrO   r/   r   r4   r   r   r   r   <module>   s    
 z