U
    uhe                     @   s|   d 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 G dd	 d	eZG d
d deZG dd deZdS )a"  
Core Models for Stream Processor Application

This module contains abstract base models and shared functionality
that is used across multiple applications in the Stream Processor project.
These models provide common fields and methods that promote consistency
and reduce code duplication.
    N)models)timezone)User)	timedelta)TimestampedModelc                   @   s$  e Zd ZdZejeejddZej	ddddZ
ejdd	d
Zejedd
Zejddd
ZejddddZejddddZejddddZejddd
Zejddd
Zejddd
ZG dd dZdd ZedddZd+edd d!d"Zddd#d$Z ddd%d&Z!ddd'd(Z"edd)d*Z#dS ),UserProfilez
    Extended user profile with security features.
    
    This model extends the Django User model with additional security
    and authentication features including 2FA, session tracking,
    and account security settings.
    Zsecurity_profile)	on_deleterelated_name    TzTOTP secret key for 2FA)
max_lengthblank	help_textFz$Whether 2FA is enabled for this user)defaultr   zBackup codes for 2FA recoveryr   z+Number of consecutive failed login attemptszAccount lockout expiration time)nullr   r   z#IP address of last successful loginz!Timestamp of last password changez.Whether user must reset password on next login   z-Maximum number of concurrent sessions allowedi  zSession timeout in minutesc                   @   s   e Zd ZdZdZdS )zUserProfile.MetazUser Security ProfilezUser Security ProfilesN)__name__
__module____qualname__verbose_nameverbose_name_plural r   r   ?/var/www/html/StreamProcessor/src/apps/authentication/models.pyMeta\   s   r   c                 C   s   d| j j S )NzSecurity Profile for )userusernameselfr   r   r   __str__`   s    zUserProfile.__str__)returnc                 C   s   | j s
dS t | j k S )z
        Check if the account is currently locked.
        
        Returns:
            bool: True if account is locked, False otherwise
        F)account_locked_untilr   nowr   r   r   r   is_account_lockedc   s    zUserProfile.is_account_locked   N)duration_minutesr   c                 C   s&   t  t|d | _| jdgd dS )z
        Lock the account for a specified duration.
        
        Args:
            duration_minutes: How long to lock the account
        )minutesr   update_fieldsN)r   r    r   r   save)r   r#   r   r   r   lock_accountn   s    zUserProfile.lock_accountc                 C   s    d| _ d| _| jddgd dS )zE
        Unlock the account and reset failed login attempts.
        Nr   r   failed_login_attemptsr%   )r   r)   r'   r   r   r   r   unlock_accountx   s    zUserProfile.unlock_accountc                 C   s4   |  j d7  _ | j dkr"| d | jdgd dS )zX
        Increment failed login attempts and lock account if threshold reached.
              r"   r)   r%   N)r)   r(   r'   r   r   r   r   increment_failed_attempts   s    

z%UserProfile.increment_failed_attemptsc                 C   s   d| _ | jdgd dS )z6
        Reset failed login attempts counter.
        r   r)   r%   N)r)   r'   r   r   r   r   reset_failed_attempts   s    z!UserProfile.reset_failed_attemptsc                 C   s   | j S )z
        Check if the user needs to change their password.
        
        Returns:
            bool: True if password change is required, False otherwise
        )password_reset_requiredr   r   r   r   needs_password_change   s    z!UserProfile.needs_password_change)r"   )$r   r   r   __doc__r   OneToOneFieldr   CASCADEr   	CharFieldZtotp_secretBooleanFieldZis_2fa_enabled	JSONFieldlistZbackup_codesPositiveIntegerFieldr)   DateTimeFieldr   GenericIPAddressFieldZlast_login_ipZlast_password_changer/   Zmax_concurrent_sessionsZsession_timeout_minutesr   r   boolr!   intr(   r*   r-   r.   r0   r   r   r   r   r      st   
	r   c                   @   s\   e Zd ZdZejddZe Zej	ddZ
e ZejdddZG dd	 d	Zd
d ZdS )LoginAttemptz7
    Track login attempts for security monitoring.
       )r   Tr   d   )r   r   c                   @   s   e Zd ZdZdZdgZdS )zLoginAttempt.MetazLogin AttemptzLogin Attemptsz-created_atNr   r   r   r   r   orderingr   r   r   r   r      s   r   c                 C   s&   | j r
dnd}| j d| d| j S )NZSuccessFailed - )successr   
ip_address)r   statusr   r   r   r      s    zLoginAttempt.__str__N)r   r   r   r1   r   r4   r   r:   rF   	TextField
user_agentr5   rE   Zfailure_reasonr   r   r   r   r   r   r=      s   r=   c                   @   sp   e Zd ZdZejeejdZej	dddZ
e ZejddZejddZejddZG d	d
 d
Zdd ZdS )UserSessionz%
    Track active user sessions.
    )r   (   T)r   uniquer?   )r   )auto_nowc                   @   s   e Zd ZdZdZdgZdS )zUserSession.MetazUser SessionzUser Sessionsz-last_activityNrA   r   r   r   r   r      s   r   c                 C   s   | j j d| jd d  dS )NrD      z...)r   r   session_keyr   r   r   r   r      s    zUserSession.__str__N)r   r   r   r1   r   
ForeignKeyr   r3   r   r4   rO   r:   rF   rH   rI   r5   	is_activer9   Zlast_activityr   r   r   r   r   r   rJ      s   rJ   )r1   uuid	django.dbr   django.utilsr   django.contrib.auth.modelsr   datetimer   Zapps.core.modelsr   r   r=   rJ   r   r   r   r   <module>   s   	 