
    k)i1                     p   d Z ddlZddlmZmZmZ ddlmZmZmZm	Z	 ddl
mZmZ ddlmZ ddlmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZmZmZmZmZm Z m!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+ dedede,dee   fdZ-	 	 	 d,dede.de,de,dededee,   dee,   dee,   dee   fdZ/dede.de.fdZ0dede,de1fd Z2dede.fd!Z3	 	 d-ded"edee,   dee,   deee   e,f   f
d#Z4ded$edeee   e,f   fd%Z5dededee   fd&Z6d'ede!fd(Z7ded)edeee   e,f   fd*Z8d.dedee.   dee e,f   fd+Z9y)/zE
Authentication controller for handling auth-related business logic.
    N)datetime	timedeltatimezone)DictOptionalTupleUnion)HTTPExceptionstatus)Session)selectand_update)EmailStr)User)AuthSession)LoginRequestSchemaLoginResponseSchemaRegisterRequestSchemaRegisterResponseSchemaRefreshTokenRequestSchemaAuthTokenSchemaLogoutResponseSchemaUserProfileSchema)UserCreateSchema)create_user)jwt_manager)verify_password)settingsdbemailpasswordreturnc                 R   t        t              j                  t        j                  |k(        }t	        t        d      r.|j                  t        j
                  j                  d            }| j                  |      j                         }|syt        ||j                        sy|S )z
    Authenticate user by email and password.
    
    Args:
        db: Database session
        email: User's email address
        password: Plain text password
        
    Returns:
        User model if authentication successful, None otherwise
    
deleted_atN)r   r   wherer!   hasattrr%   is_executescalar_one_or_noner   hashed_password)r    r!   r"   stmtusers        T/var/www/html/hwPaymentPortal-be-dev/hw-payment-portal-api/src/apps/auth/services.pyauthenticate_userr/       s     $<djjE12Dt\"zz$//--d34::d..0D 8T%9%9:K    user_idaccess_tokenrefresh_tokenaccess_token_expires_atrefresh_token_expires_at
ip_address
user_agentdevice_infoc	                     	 t        ||||||||dd
      }	| j                  |	       | j                          | j                  |	       |	S # t        $ r}
| j                          Y d}
~
yd}
~
ww xY w)z$Create a new authentication session.TF)
r1   r2   r3   r4   r5   r6   r7   r8   	is_active
is_revokedN)r   addcommitrefresh	Exceptionrollback)r    r1   r2   r3   r4   r5   r6   r7   r8   auth_sessiones              r.   create_auth_sessionrC   <   st    "%'$;%=!!#
 	|
		


<  
s   AA 	A.A))A.c                    	 t        j                  t        j                        }t	        t
              j                  t        t
        j                  |k(  t
        j                  dk(  t
        j                  dk(              j                  dd||      }| j                  |      }| j                          |j                  S # t        $ r | j!                          Y yw xY w)z&Revoke all active sessions for a user.TFr:   r;   
revoked_at
updated_atr   )r   nowr   utcr   r   r&   r   r1   r:   r;   valuesr)   r=   rowcountr?   r@   )r    r1   rH   r,   results        r.   revoke_all_user_sessionsrM   `   s    ll8<<( ;U''72))T1**e3 V	   	" D!
		 
s   B>C CCc                    	 t        j                  t        j                        }t	        t
              j                  t        t
        j                  |k(  t
        j                  dk(  t
        j                  dk(              j                  dd||      }| j                  |      }| j                          |j                  dkD  S # t        $ r | j!                          Y yw xY w)z
    Revoke a specific session by access token.
    
    Args:
        db: Database session
        access_token: The access token to revoke
        
    Returns:
        True if session was revoked, False otherwise
    TFrE   r   )r   rH   r   rI   r   r   r&   r   r2   r:   r;   rJ   r)   r=   rK   r?   r@   )r    r2   rH   r,   rL   s        r.   revoke_session_by_tokenrO      s    ll8<<( ;U,,<))T1**e3 V	   	" D!
		"" 
s   CC C C c                    	 t        j                  t        j                        }t	        t
              j                  t        t
        j                  |k  t
        j                  dk(              j                  d|      }| j                  |      }| j                          |j                  S # t        $ r | j                          Y yw xY w)z)Clean up expired authentication sessions.TF)r:   rG   r   )r   rH   r   rI   r   r   r&   r   r4   r:   rJ   r)   r=   rK   r?   r@   )r    rH   r,   rL   s       r.   cleanup_expired_sessionsrQ      s    ll8<<( ;U77#=))T1 V   	 D!
		 
s   B*B- -C	C	
login_datac                    t        | |j                  |j                        }|sy|j                  sy|j                  |j                  t        |dd      |j                  |j                  t        |dd      |j                  |j                  t        |dd      d	}d	|i}d	|i}t        t        j                  
      }t        t        j                        }	t        j                  ||      }
t        j                   ||	      }t#        j$                  t&        j(                        |z   }t#        j$                  t&        j(                        |	z   }t+        | |j                  |
|||||       t#        j$                  t&        j(                        |_        | j/                          t1        d|j                  |j                  |j                  |j                  |
|dt        j                  dz  	      }|dfS )a  
    Login user with email and password.
    
    Args:
        db: Database session
        login_data: Login request data
        ip_address: Client IP address
        user_agent: Client user agent
        
    Returns:
        Tuple of login response and message
    )NzIncorrect email or password)NzInactive userusernameNphoneis_superuserF	r1   r!   rT   
first_name	last_namerU   r:   is_verifiedrV   r-   minutes)days)r    r1   r2   r3   r4   r5   r6   r7   zAuthentication successfulbearer<   )	messager1   r!   r:   rZ   r2   r3   
token_type
expires_inzLogin successful)r/   r!   r"   is_user_activeidgetattrrX   rY   r:   rZ   r   r   jwt_expires_minutesjwt_refresh_expires_daysr   create_access_tokencreate_refresh_tokenr   rH   r   rI   rC   
last_loginr=   r   )r    rR   r6   r7   r-   	user_data
token_datarefresh_token_dataaccess_token_expiresrefresh_token_expiresr2   r3   access_expires_atrefresh_expires_atlogin_responses                  r.   
login_userrs      s   & R!1!1:3F3FGD2$ 77D*d3oo^^w-^^''ne<
I 		J
 		
 %X-I-IJ%8+L+LM22:?STL445GI^_M !X\\25II!hll36KK!# 1!3	 ll8<<0DOIIK )+jj..$$!#//"4
N ---r0   register_datac           	      B   t        |j                  |j                  |j                  |j                  |j
                  dd      }t        | ||j                        \  }}|d|fS t        d|j                  |j                  |j                  |j                        }||fS )z
    Register a new user.
    
    Args:
        db: Database session
        register_data: Registration request data
        
    Returns:
        Tuple of registration response and message
    TF)r!   rX   middle_namerY   rU   r:   rZ   NzRegistration successful)r`   r1   r!   r:   rZ   )r   r!   rX   rv   rY   rU   r   r"   r   rd   r:   rZ   )r    rt   user_create_datar-   r`   register_responses         r.   register_userry   !  s     (!! ++!--))!!  $4m6L6LMMD'|W} /)jj..$$ g%%r0   c                    t        t              j                  t        j                  |k(        }t	        t        d      r.|j                  t        j
                  j                  d            }| j                  |      j                         S )z
    Get user by email address.
    
    Args:
        db: Database session
        email: User's email address
        
    Returns:
        User model if found, None otherwise
    r%   N)	r   r   r&   r!   r'   r%   r(   r)   r*   )r    r!   r,   s      r.   get_user_by_emailr{   L  s`     $<djjE12Dt\"zz$//--d34::d..00r0   r-   c                 ,    t        j                  |       S )z
    Get current user profile information.
    
    Args:
        user: Current authenticated user
        
    Returns:
        User profile schema
    )r   model_validate)r-   s    r.   get_current_user_profiler~   ^  s     ++D11r0   refresh_requestc                 
   t        j                  |j                        }|sy|j                  d      dk7  ry|j                  d      }|sy|j                  d      }t	        t
              j                  t
        j                  |k(        }| j                  |      j                         }|r|j                  sy|j                  |j                  t        |dd	      |j                  |j                  t        |d
d	      |j                  |j                   t        |dd      d	}d|i}t#        t$        j&                        }	t        j(                  ||	      }
t+        |
|j                  dt$        j&                  dz        }|dfS )z
    Refresh access token using refresh token.
    
    Args:
        db: Database session
        refresh_request: Refresh token request data
        
    Returns:
        Tuple of new tokens and message
    )NzInvalid refresh tokentyper>   )NzInvalid token typer-   r1   )NzUser not found or inactiverT   NrU   rV   FrW   r[   r^   r_   )r2   r3   ra   rb   zToken refreshed successfully)r   verify_tokenr3   getr   r   r&   rd   r)   r*   rc   r!   re   rX   rY   r:   rZ   r   r   rf   rh   r   )r    r   payloadrk   r1   	user_stmtr-   updated_user_datarl   rn   new_access_tokentoken_responses               r.   refresh_access_tokenr   k  sc    &&'D'DEG, {{6i')F#I,mmI&G t""477g#56I::i 335Dt**1 77D*d3oo^^w-^^''ne<
 	!J %X-I-IJ"66zCWX %%%33//"4	N 999r0   c                 L    d}|rt        | |      }t        d|      }|d| dfS )z
    Logout user by revoking session(s).
    
    Args:
        db: Database session
        user_id: User ID to revoke all sessions
        
    Returns:
        Tuple of logout response and message
    r   zLogout successful)r`   logged_out_sessionszLogged out z session(s))rM   r   )r    r1   sessions_revokedlogout_responses       r.   logout_userr     sB     3B@*#,O
 k*:);;GGGr0   )NNN)NN)N):__doc__uuidr   r   r   typingr   r   r   r	   fastapir
   r   sqlalchemy.ormr   
sqlalchemyr   r   r   pydantic.networksr   src.apps.users.models.userr   !src.apps.auth.models.auth_sessionr   !src.apps.auth.schemas.auth_commonr   r   r   r   r   r   r   r   "src.apps.users.schemas.user_commonr   src.apps.users.servicesr   src.apps.auth.utils.jwtr   src.core.utils.passwordr   src.core.configr   strr/   intrC   rM   boolrO   rQ   rs   ry   r{   r~   r   r    r0   r.   <module>r      s`    2 2 / / ) " + + & + 9	 	 	 @ / / 3 $' ( c htn F !% $!%!!! ! 	!
 &! '! ! ! #! k!H 3 3 @& &s &t &R S @ !% $	X.X."X. X. 	X.
 8'(#-.X.v(&(&((& 8*+S01(&V1' 1( 1x~ 1$
24 
2,= 
2@:@:.@: 8O$c)*@:FHG Hhsm HuEY[^E^?_ Hr0   