
    {i                        d Z ddlZddlmZmZmZ ddlmZmZmZ ddl	m
Z
mZmZ ddlmZmZ ddlmZ ddlmZ erdd	lmZ dd
lmZ ddlmZ ddlmZ  e       Z e
e       e
e      fdee   deded   fdZ e
e       e
e      fdededdfdZ e
e      f	 	 	 ddZ e
e      f	 	 	 ddZ  e
e      f	 	 	 ddZ!de"deded   fdZ#d Z$y)z8
Authentication utilities and dependencies for FastAPI.
    N)datetime	timedeltatimezone)OptionalUnionTYPE_CHECKING)DependsHTTPExceptionstatus)
HTTPBearerHTTPAuthorizationCredentials)Session)selectUserAuthSession)get_db)jwt_managercredentialsdbreturnr   c                 P   K   | syt        | j                  |       d{   S 7 w)a   
    Get current user from JWT token (optional - returns None if no token or invalid).
    
    Args:
        credentials: HTTP Bearer token credentials
        db: Database session
        
    Returns:
        User model or None if not authenticated
    N)_verify_token_and_get_userr   )r   r   s     K/var/www/html/hwPaymentPortal-be-dev/hw-payment-portal-api/src/core/auth.pyget_current_user_optionalr      s'      +K,C,CRHHHHs   &$&c                    K   t        | j                  |       d{   }|st        t        j                  dddi      |S 7 &w)a)  
    Get current user from JWT token (required - raises exception if not authenticated).
    
    Args:
        credentials: HTTP Bearer token credentials
        db: Database session
        
    Returns:
        User model
        
    Raises:
        HTTPException: If authentication fails
    NzCould not validate credentialszWWW-AuthenticateBearer)status_codedetailheaders)r   r   r
   r   HTTP_401_UNAUTHORIZED)r   r   users      r   get_current_userr$   -   sN     " ,K,C,CRHHD443'2
 	
 K Is   AA'Ac                 \   K   | j                   st        t        j                  d      | S w)z
    Get current active user (must be authenticated and active).
    
    Args:
        current_user: Current authenticated user
        
    Returns:
        Active user model
        
    Raises:
        HTTPException: If user is inactive
    zInactive userr   r    )is_user_activer
   r   HTTP_400_BAD_REQUESTcurrent_users    r   get_current_active_userr+   J   s2      &&33"
 	

    *,c                 \   K   | j                   st        t        j                  d      | S w)a  
    Get current verified user (must be authenticated, active, and verified).
    
    Args:
        current_user: Current active user
        
    Returns:
        Verified user model
        
    Raises:
        HTTPException: If user is not verified
    zEmail not verifiedr&   )is_user_verifiedr
   r   r(   r)   s    r   get_current_verified_userr/   b   s2      ((33'
 	

 r,   c                 \   K   | j                   st        t        j                  d      | S w)z
    Get current superuser (must be authenticated, active, and superuser).
    
    Args:
        current_user: Current active user
        
    Returns:
        Superuser model
        
    Raises:
        HTTPException: If user is not a superuser
    zNot enough permissionsr&   )is_superuserr
   r   HTTP_403_FORBIDDENr)   s    r   get_current_superuserr3   z   s2      $$11+
 	

 r,   tokenc                   K   ddl m} ddlm} t	        j
                  |       }|sy|j                  d      }|sy|j                  d      }|syt        |      j                  |j                  | k(  |j                  dk(  |j                  dk(        }|j                  |      j                         }|sy|j                         r!|j                          |j!                          yt        |      j                  |j"                  |k(        }	|j                  |	      j                         }
|
sy|j%                          |j!                          |
S w)	z
    Verify JWT token and return the associated user.
    
    Args:
        token: JWT token string
        db: Database session
        
    Returns:
        User model or None if invalid
    r   r   r   Nr#   user_idTF)src.apps.users.models.userr   !src.apps.auth.models.auth_sessionr   r   verify_tokengetr   whereaccess_token	is_active
is_revokedexecutescalar_one_or_none
is_expiredrevokecommitidupdate_activity)r4   r   r   r   payload	user_datar6   stmtsession	user_stmtr#   s              r   r   r      s,     0= &&u-G F#ImmI&G +$$  E)%%'D
 jj113G 
		 t""477g#56I::i 335D IIKKs   EEc                       fd}|S )z
    Decorator to require authentication for a function.
    
    Usage:
        @require_auth
        def my_protected_function(current_user: User = Depends(get_current_user)):
            pass
    c                       | i |S )N )argskwargsfuncs     r   wrapperzrequire_auth.<locals>.wrapper   s    T$V$$    rM   )rP   rQ   s   ` r   require_authrS      s    %NrR   )r*   r   r   r   )%__doc__jwtr   r   r   typingr   r   r   fastapir	   r
   r   fastapi.securityr   r   sqlalchemy.ormr   
sqlalchemyr   r7   r   r8   r   src.core.databaser   src.core.utils.jwtr   securityr   r$   r+   r/   r3   strr   rS   rM   rR   r   <module>r_      s9    2 2 1 1 2 2 E "  /= $ * < ;B(:K&/I67II fI* 180A&/- < ##342 ##:;2 ##:;09C 9W 9&AQ 9xrR   