o
    &ahE                     @   s   d 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dlmZ ddlZddlZdd	lmZ e	 ZG d
d deZG dd deZG dd deZG dd deZdS )z
Authentication Models Module

This module contains models related to authentication and authorization
including login attempts, password reset tokens, and session management.

Author: Senior Django Developer
Date: 2024
    )models)gettext_lazy)timezone)get_user_model)MinLengthValidator)	BaseModelN)	timedeltac                   @   s  e Zd ZdZejeejddededdZ	ej
ededdZejed	ed
dZejdededdZejdededdZejddededdZejddededdZejddededdZG dd dZdd Zed%dd Zed&d"d#Zd$S )'LoginAttempta   
    Model to track login attempts for security monitoring.
    
    This model helps in implementing security features like:
    - Account lockout after multiple failed attempts
    - Suspicious activity detection
    - Login analytics and monitoring
    TUserzUser who attempted to login)	on_deletenullblankverbose_name	help_textzAttempted Emailz#Email address used in login attemptr   r   
IP Addressz)IP address from which login was attempted
User Agent Browser/client user agent stringr   r   r   FzIs Successfulz(Whether the login attempt was successfuldefaultr   r   d   zFailure ReasonzReason for login failure
max_lengthr   r   r   Countryz&Country from which login was attemptedCityz#City from which login was attemptedc                   @   sT   e Zd ZedZedZdgZdZej	ddgdej	ddgdej	d	dgdgZ
d
S )zLoginAttempt.MetazLogin AttemptzLogin Attempts-created_atZauth_login_attemptattempted_email
created_atfields
ip_addressis_successfulN__name__
__module____qualname___r   verbose_name_pluralorderingdb_tabler   Indexindexes r-   r-   PC:\Users\vibe-look\OneDrive\Desktop\Adtlas_V\src\apps\authentification\models.pyMeta_   s    r/   c                 C   s(   | j rdnd}| j d| d| j dS )z+String representation of the login attempt.ZSuccessZFailed -  ()N)r"   r   r   )selfstatusr-   r-   r.   __str__j   s   zLoginAttempt.__str__   c                 C   s(   t  t|d }| jj|d|d S )a%  
        Get count of failed login attempts for an email within specified hours.
        
        Args:
            email (str): Email address to check
            since_hours (int): Number of hours to look back
            
        Returns:
            int: Number of failed attempts
        hoursF)r   r"   created_at__gteNr   nowr   objectsfiltercount)clsemailsince_hours
since_timer-   r-   r.   get_failed_attempts_counto   s   z&LoginAttempt.get_failed_attempts_count
   c                 C   s0   t  t|d }| jj|d|d }||kS )aT  
        Check if an IP address has too many failed attempts.
        
        Args:
            ip_address (str): IP address to check
            max_attempts (int): Maximum allowed failed attempts
            since_hours (int): Number of hours to look back
            
        Returns:
            bool: True if IP is suspicious
        r7   F)r!   r"   r9   Nr:   )r?   r!   Zmax_attemptsrA   rB   Zfailed_countr-   r-   r.   is_ip_suspicious   s   zLoginAttempt.is_ip_suspiciousN)r6   )rD   r6   )r$   r%   r&   __doc__r   
ForeignKeyr
   CASCADEr'   user
EmailFieldr   GenericIPAddressFieldr!   	TextField
user_agentBooleanFieldr"   	CharFieldZfailure_reasoncountrycityr/   r5   classmethodrC   rE   r-   r-   r-   r.   r	      sh    

r	   c                       s  e Zd ZdZejeejededdZ	ej
ddededd	Zejed
eddZejdededdZejddededdZejededdZejddededdZG dd dZdd Z fddZed(dd Zd!d" Zd)d$d%Zed&d' Z  ZS )*PasswordResetTokenz
    Model for managing password reset tokens.
    
    This model provides secure password reset functionality with:
    - Time-limited tokens
    - One-time use tokens
    - Secure token generation
    r
   z$User for whom the token is generatedr   r   r   r   TTokenzPassword reset tokenr   uniquer   r   
Expires AtWhen the token expiresr   FIs UsedWhether the token has been usedr   Used AtWhen the token was usedr   r   r   r   zRequested IPz)IP address from which reset was requestedzUsed IPz$IP address from which token was usedc                   @   P   e Zd ZedZedZdgZdZej	dgdej	ddgdej	d	gdgZ
d
S )zPasswordResetToken.MetazPassword Reset TokenzPassword Reset Tokensr   Zauth_password_reset_tokentokenr   rI   is_used
expires_atNr#   r-   r-   r-   r.   r/          r/   c                 C   s   d| j j d| j dS )z2String representation of the password reset token.zReset token for r1   r2   N)rI   r@   r   r3   r-   r-   r.   r5      s   zPasswordResetToken.__str__c                    @   | j s|  | _ | jst tdd | _t j|i | dS )
        Override save to generate token and set expiration.
        
        Automatically generates a secure token and sets expiration time
        if not already set.
        r6   r7   Nr`   generate_tokenrb   r   r;   r   supersaver3   argskwargs	__class__r-   r.   rj      
   
zPasswordResetToken.save@   c                    (   t jt j  d fddt| D S )
        Generate a secure random token.
        
        Args:
            length (int): Length of the token
            
        Returns:
            str: Secure random token
         c                 3       | ]}t  V  qd S Nsecretschoice.0r'   alphabetr-   r.   	<genexpr>       z4PasswordResetToken.generate_token.<locals>.<genexpr>Nstringascii_lettersdigitsjoinrangelengthr-   r|   r.   rh         z!PasswordResetToken.generate_tokenc                 C      | j  o
t | jk S z
        Check if the token is valid (not used and not expired).
        
        Returns:
            bool: True if token is valid
        Nra   r   r;   rb   rd   r-   r-   r.   is_valid     zPasswordResetToken.is_validNc                 C   s.   d| _ t | _|r|| _| jg dd dS )z
        Mark the token as used.
        
        Args:
            ip_address (str): IP address from which token was used
        T)ra   used_atused_ipupdate_fieldsN)ra   r   r;   r   r   rj   r3   r!   r-   r-   r.   	use_token  s
   
zPasswordResetToken.use_tokenc                 C   &   | j jt d}| }|  |S )z~
        Remove expired tokens from the database.
        
        Returns:
            int: Number of tokens deleted
        Zexpires_at__ltNr<   r=   r   r;   r>   delete)r?   Zexpired_tokensr>   r-   r-   r.   cleanup_expired     z"PasswordResetToken.cleanup_expiredrq   rv   )r$   r%   r&   rF   r   rG   r
   rH   r'   rI   rO   r`   DateTimeFieldrb   rN   ra   r   rK   Zrequested_ipr   r/   r5   rj   staticmethodrh   r   r   rR   r   __classcell__r-   r-   rn   r.   rS      s`    

rS   c                       s  e Zd ZdZejeejededdZ	ej
ddededd	Zejed
eddZejededdZejdededdZejddededdZejddededdZG dd dZdd Z fddZed&dd Zd!d" Zd'd$d%Z  ZS )(EmailVerificationTokenz
    Model for managing email verification tokens.
    
    This model handles email verification functionality with:
    - Secure token generation
    - Time-limited verification
    - One-time use tokens
    r
   z1User for whom the verification token is generatedrT   r   TrU   zEmail verification tokenrV   ZEmailzEmail address to verifyr   rX   rY   FrZ   r[   r   r\   r]   r^   zVerified IPz(IP address from which email was verifiedc                   @   r_   )zEmailVerificationToken.MetazEmail Verification TokenzEmail Verification Tokensr   Zauth_email_verification_tokenr`   r   rI   ra   r@   Nr#   r-   r-   r-   r.   r/   h  rc   r/   c                 C   s   d| j  d| j dS )z6String representation of the email verification token.zVerification token for r1   r2   N)r@   r   rd   r-   r-   r.   r5   s  s   zEmailVerificationToken.__str__c                    re   )rf      r7   Nrg   rk   rn   r-   r.   rj   w  rp   zEmailVerificationToken.saverq   c                    rr   )rs   rt   c                 3   ru   rv   rw   rz   r|   r-   r.   r~     r   z8EmailVerificationToken.generate_token.<locals>.<genexpr>Nr   r   r-   r|   r.   rh     r   z%EmailVerificationToken.generate_tokenc                 C   r   r   r   rd   r-   r-   r.   r     r   zEmailVerificationToken.is_validNc                 C   s8   d| _ t | _|r|| _| jg dd | j  dS )z
        Mark the token as used and verify the user's email.
        
        Args:
            ip_address (str): IP address from which verification was completed
        T)ra   r   verified_ipr   N)ra   r   r;   r   r   rj   rI   verify_emailr   r-   r-   r.   r     s   
z#EmailVerificationToken.verify_emailr   rv   )r$   r%   r&   rF   r   rG   r
   rH   r'   rI   rO   r`   rJ   r@   r   rb   rN   ra   r   rK   r   r/   r5   rj   r   rh   r   r   r   r-   r-   rn   r.   r   +  s\    
r   c                   @   sz  e Zd ZdZejeejededdZ	ej
ddededd	Zejed
eddZejdededdZej
ddededdZej
ddededdZej
ddededdZejdededdZejdededdZejeded dZej
dded!ed"dZej
dded#ed$dZG d%d& d&Zd'd( Zd)d* Zd+d, Zed-d. Zed/d0 Z d1S )2UserSessionz
    Model for tracking user sessions.
    
    This model provides enhanced session management with:
    - Session tracking across devices
    - Security monitoring
    - Session invalidation capabilities
    r
   zUser who owns this sessionrT   (   TzSession KeyzDjango session keyrV   r   zIP address of the sessionr   r   r   r   2   zDevice Typez(Type of device (mobile, desktop, tablet)r   r   ZBrowserzBrowser name and versionzOperating Systemz!Operating system name and versionz	Is Activez'Whether the session is currently activer   zLast Activityz When the session was last active)auto_nowr   r   rX   zWhen the session expiresr   zCountry of the sessionr   zCity of the sessionc                   @   sP   e Zd ZedZedZdgZdZej	ddgdej	dgdej	d	gdgZ
d
S )zUserSession.MetazUser SessionzUser Sessionsz-last_activityZauth_user_sessionrI   	is_activer   session_keylast_activityNr#   r-   r-   r-   r.   r/     s    r/   c                 C   s   | j j d| j d| j dS )z*String representation of the user session.r0   r1   r2   N)rI   r@   r!   r   rd   r-   r-   r.   r5     s   zUserSession.__str__c                 C   s   t  | jkS )zy
        Check if the session is expired.
        
        Returns:
            bool: True if session is expired
        N)r   r;   rb   rd   r-   r-   r.   
is_expired"  s   zUserSession.is_expiredc                 C   s   d| _ | jdgd dS )z
        Invalidate the session.
        
        Marks the session as inactive and can be used to
        force logout from specific devices.
        Fr   r   N)r   rj   rd   r-   r-   r.   
invalidate+  s   zUserSession.invalidatec                 C   r   )z
        Remove expired sessions from the database.
        
        Returns:
            int: Number of sessions deleted
        r   Nr   )r?   Zexpired_sessionsr>   r-   r-   r.   r   5  r   zUserSession.cleanup_expiredc                 C   s   | j j|dt dS )z
        Get all active sessions for a user.
        
        Args:
            user: User instance
            
        Returns:
            QuerySet: Active sessions for the user
        T)rI   r   Zexpires_at__gtN)r<   r=   r   r;   )r?   rI   r-   r-   r.   get_active_sessions_for_userD  s
   z(UserSession.get_active_sessions_for_userN)!r$   r%   r&   rF   r   rG   r
   rH   r'   rI   rO   r   rK   r!   rL   rM   Zdevice_typeZbrowserZoperating_systemrN   r   r   r   rb   rP   rQ   r/   r5   r   r   rR   r   r   r-   r-   r-   r.   r     s    
	

r   )rF   	django.dbr   django.utils.translationr   r'   django.utilsr   django.contrib.authr   django.core.validatorsr   Zapps.common.modelsr   rx   r   datetimer   r
   r	   rS   r   r   r-   r-   r-   r.   <module>   s"   
~  	