o
    ?7il                     @   s   U d Z ddlZddlZddlmZ ddlmZ eeZ	da
eej ed< dejfddZd	edefd
dZd	edefddZd	eddfddZdS )zD
Login security utilities
Account lockout and failed login tracking
    N)settings)Optional_redis_clientreturnc                   C   s<   t du rtjrtjtjdda t S tjtjtjddda t S )zGet or create Redis clientNT)decode_responsesr   )hostportdbr   )r   r   	REDIS_URLredisfrom_urlRedis
REDIS_HOST
REDIS_PORT r   r   ?/lsinfo/ai/hellotax_ai/base_platform/app/core/login_security.pyget_redis_client   s   r   emailc              
   C   sf   zt  }d|  }||}|dkr||d |W S  ty2 } ztd|  tdd}~ww )z
    Record a failed login attempt

    Args:
        email: User email

    Returns:
        Number of failed attempts

    Raises:
        RuntimeError: If Redis is unavailable (fail-close strategy)
    failed_login:   i  z.Redis unavailable for recording failed login: :Login security system unavailable. Please try again later.N)r   increxpire	ExceptionloggererrorRuntimeErrorr   clientkeyattemptser   r   r   record_failed_login#   s   

r"   c              
   C   sh   zt  }d|  }||}|du rW dS t|dkW S  ty3 } ztd|  tdd}~ww )z
    Check if account is locked due to failed login attempts

    Args:
        email: User email

    Returns:
        True if account is locked

    Raises:
        RuntimeError: If Redis is unavailable (fail-close strategy)
    r   NF   z*Redis unavailable for account lock check: r   )r   getintr   r   r   r   r   r   r   r   is_account_lockedC   s   

r&   c              
   C   sX   zt  }d|  }|| W dS  ty+ } ztd|  W Y d}~dS d}~ww )za
    Reset failed login attempts after successful login

    Args:
        email: User email
    r   z1Redis unavailable for resetting failed attempts: N)r   deleter   r   r   )r   r   r   r!   r   r   r   reset_failed_attempts`   s   
r(   )__doc__r   logging
app.configr   typingr   	getLogger__name__r   r   r   __annotations__r   strr%   r"   boolr&   r(   r   r   r   r   <module>   s    
 