U
    gnhC                     @   s   d Z ddlmZ ddlmZ ddl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d
lZddlmZmZmZ G dd dejZG dd deZG dd dejZG dd dejZG dd dejZd
S )a  
Adtlas Authentication Forms

Enhanced authentication forms for the Adtlas DAI Management System.
Includes login, registration, password reset, and profile management forms.

Features:
    - Enhanced login form with remember me functionality
    - User registration with profile creation
    - Password reset with secure token system
    - Profile management forms
    - Form validation and security measures

Author: Adtlas Development Team
Version: 2.0.0
Last Updated: 2025-07-09
    )forms)authenticate)UserCreationFormPasswordResetForm)validate_password)ValidationError)gettext_lazy)timezone)	timedeltaN)UserProfilePasswordResetTokenc                       s   e Zd ZdZejdejddddddededd	Zej	ej
dd
ddded
eddZejddejddddededdZd fdd	Z fddZdd Z  ZS )	LoginFormzS
    Enhanced login form with remember me functionality and security features.
       input100Email AddressTclassplaceholderrequiredZ	autofocusZattrs#Enter your registered email address
max_lengthwidgetlabel	help_textPasswordr   r   r   zEnter your passwordr   r   r   Fform-check-inputzremember-me)r   idzRemember mezKeep me logged in for 30 days)r   initialr   r   r   Nc                    s   || _ d| _t j|| dS )zN
        Initialize the form with request context for authentication.
        N)request
user_cachesuper__init__)selfr#   argskwargs	__class__  src/apps/authentication/forms.pyr&   G   s    zLoginForm.__init__c                    sL  t   }|d}|d}|rH|rH|  }ztjj|d}| r^tt	ddd|j
sttt	ddd|jstt	d	d
dt| j||d| _| jdkr| jd7  _|jdkrt tdd |_|jddgd tt	dddn(|jdkrd|_d|_|jddgd W n( tjk
rF   tt	dddY nX |S )zF
        Validate login credentials and check account status.
        emailpasswordr.   zoAccount is temporarily locked due to multiple failed login attempts. Please try again later or contact support.Zaccount_lockedcodez:Your account has been deactivated. Please contact support.Zaccount_inactivez_Please verify your email address before logging in. Check your inbox for the verification link.Zemail_not_verified)usernamer/   N         )Zminutesfailed_login_attemptsaccount_locked_until)Zupdate_fieldsz,Invalid email or password. Please try again.Zinvalid_credentialsr   )r%   cleangetlowerstripr   objectsZis_account_lockedr   _	is_activeis_verifiedr   r#   r$   r7   r	   nowr
   r8   saveDoesNotExist)r'   cleaned_datar.   r/   userr*   r,   r-   r9   O   s\    




zLoginForm.cleanc                 C   s   | j S )z0
        Return the authenticated user.
        )r$   r'   r,   r,   r-   get_user   s    zLoginForm.get_user)N)__name__
__module____qualname____doc__r   
EmailField
EmailInputr>   r.   	CharFieldPasswordInputr/   BooleanFieldCheckboxInputZremember_mer&   r9   rG   __classcell__r,   r,   r*   r-   r   !   sD   
Kr   c                       s  e Zd ZdZejdejdddddededd	Zej	d
ej
dddddededd	Zej	d
ej
dddddededd	Zej	ejdddddededdZej	ejdddddededdZej	ddej
ddddededdZej	ddej
ddddededdZej	ddej
dddded ed!dZejdejd"d#ided$d%ed&id'ZG d(d) d)Z fd*d+Zd,d- Zd.d/ Zd2 fd0d1	Z  ZS )3UserRegistrationFormz@
    Enhanced user registration form with profile creation.
    r   r   r   Tr   r   zEnter a valid email addressr      
First NamezEnter your first name	Last NamezEnter your last namer   zEnter a strong passwordr   zConfirm PasswordzRe-enter your password   FzPhone Number (Optional))r   r   zPhone Numberz"Enter your phone number (optional))r   r   r   r   r   d   zJob Title (Optional)z	Job TitlezEnter your job title (optional)zCompany (Optional)ZCompanyz"Enter your company name (optional)r   r    z2I agree to the Terms of Service and Privacy Policyr   z5You must accept the terms and conditions to register.)r   r   r   Zerror_messagesc                   @   s   e Zd ZeZdZdS )zUserRegistrationForm.Meta)r.   
first_name	last_name	password1	password2N)rH   rI   rJ   r   modelfieldsr,   r,   r,   r-   Meta  s   r_   c                    s$   t  j|| d| jkr | jd= d S )Nr3   )r%   r&   r^   r'   r(   r)   r*   r,   r-   r&     s    
zUserRegistrationForm.__init__c                 C   s^   | j d}|rZ|  }tjj|d r>tt	dddt
d|sZtt	ddd|S )	z7
        Validate email uniqueness and format.
        r.   r0   z2An account with this email address already exists.Zemail_existsr1   z0^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$z#Please enter a valid email address.Zinvalid_email)rD   r:   r;   r<   r   r=   filterexistsr   r>   rematch)r'   r.   r,   r,   r-   clean_email  s    z UserRegistrationForm.clean_emailc                 C   s>   | j d}|r:tdd|}td|s:ttddd|S )z;
        Validate phone number format if provided.
        phone_numberz[^\d+] z^\+?1?\d{9,15}$z"Please enter a valid phone number.Zinvalid_phoner1   )rD   r:   rc   subrd   r   r>   )r'   Zphoner,   r,   r-   clean_phone_number)  s    z'UserRegistrationForm.clean_phone_numberc                    sr   t  jdd}| jd   |_|j|_d|_|rn|  tj	j
|| jdd| jdd| jddd |S )	z:
        Save user and create associated profile.
        Fcommitr.   rf   rg   	job_titlecompany)rE   rf   rl   rm   )r%   rB   rD   r;   r<   r.   r3   r@   r   r=   creater:   )r'   rk   rE   r*   r,   r-   rB   ;  s    	zUserRegistrationForm.save)T)rH   rI   rJ   rK   r   rL   rM   r>   r.   rN   	TextInputrY   rZ   rO   r[   r\   rf   rl   rm   rP   rQ   Zterms_acceptedr_   r&   re   ri   rB   rR   r,   r,   r*   r-   rS      s   

  rS   c                   @   sL   e Zd ZdZejdejddddddededd	Zd
d Z	dd Z
dS )PasswordResetRequestFormz-
    Form for requesting password reset.
    r   r   r   Tr   r   r   r   c                 C   sR   | j d}|rN|  }ztjj|dd}|| _W n tjk
rL   Y nX |S )z6
        Validate email exists and is active.
        r.   T)r.   r?   )rD   r:   r;   r<   r   r=   rE   rC   )r'   r.   rE   r,   r,   r-   re   e  s    
z$PasswordResetRequestForm.clean_emailc                 C   s2   t | dr.tjj| jt tdd d}|S dS )z=
        Create password reset token and send email.
        rE   r4   )Zhours)rE   Z
expires_atN)hasattrr   r=   rn   rE   r	   rA   r
   )r'   Zreset_tokenr,   r,   r-   rB   v  s    
zPasswordResetRequestForm.saveN)rH   rI   rJ   rK   r   rL   rM   r>   r.   re   rB   r,   r,   r,   r-   rp   T  s   rp   c                       s   e Zd ZdZejejdddddededdZejejdd	ddded	ed
dZ	d fdd	Z
dd Z fddZdd Z  ZS )PasswordResetConfirmFormz?
    Form for confirming password reset with new password.
    r   zNew PasswordTr   r   zEnter your new passwordr   zConfirm New PasswordzRe-enter your new passwordNc                    s   || _ t j|| d S )N)rE   r%   r&   )r'   rE   r(   r)   r*   r,   r-   r&     s    z!PasswordResetConfirmForm.__init__c              
   C   sX   | j d}|rT| jrTzt|| j W n, tk
rR } zt|jW 5 d}~X Y nX |S )z1
        Validate new password strength.
        new_password1N)rD   r:   rE   r   r   Zmessages)r'   r/   er,   r,   r-   clean_new_password1  s    
z,PasswordResetConfirmForm.clean_new_password1c                    sB   t   }|d}|d}|r>|r>||kr>ttddd|S )z1
        Validate password confirmation.
        rs   new_password2z&The two password fields did not match.Zpassword_mismatchr1   )r%   r9   r:   r   r>   )r'   rD   r[   r\   r*   r,   r-   r9     s    


zPasswordResetConfirmForm.cleanc                 C   s8   | j r4| j | jd  t | j _| j   | j S dS )z,
        Set new password for user.
        rs   N)rE   Zset_passwordrD   r	   rA   Zpassword_changed_atrB   rF   r,   r,   r-   rB     s    
zPasswordResetConfirmForm.save)N)rH   rI   rJ   rK   r   rN   rO   r>   rs   rv   r&   ru   r9   rB   rR   r,   r,   r*   r-   rr     s.   

rr   c                       s|   e Zd ZdZG dd dZejdejddidedd	Z	ejdejddided
d	Z
 fddZd fdd	Z  ZS )ProfileFormz4
    Form for editing user profile information.
    c                   @   s,  e Zd ZeZddddddddd	d
dddddddgZejddidejddddejddidejddidej	ddidejddidejddidejddidejddidejddidejddidej
ddidej
ddidej
ddidejddidejddidejddiddZdS )zProfileForm.Metarf   biorl   rm   websiteaddress_line1address_line2citystatepostal_codecountryr	   languagethemenotifications_enabledemail_notificationssms_notificationsr   form-controlr      )r   Zrowsr    )rf   rx   rl   rm   ry   rz   r{   r|   r}   r~   r   r	   r   r   r   r   r   N)rH   rI   rJ   r   r]   r^   r   ro   ZTextareaZURLInputZSelectrQ   Zwidgetsr,   r,   r,   r-   r_     sJ                r_   rT   r   r   r   rU   )r   r   r   rV   c                    sF   | dd | _t j|| | jrB| jj| jd _| jj| jd _d S )NrE   rY   rZ   )poprE   r%   r&   rY   r^   r"   rZ   r`   r*   r,   r-   r&     s
    zProfileForm.__init__Tc                    sR   t  jdd}| jrN| jdd| j_| jdd| j_|rN| j  |  |S )z;
        Save profile and update user information.
        Frj   rY   rg   rZ   )r%   rB   rE   rD   r:   rY   rZ   )r'   rk   Zprofiler*   r,   r-   rB     s    
zProfileForm.save)T)rH   rI   rJ   rK   r_   r   rN   ro   r>   rY   rZ   r&   rB   rR   r,   r,   r*   r-   rw     s   rw   )rK   Zdjangor   Zdjango.contrib.authr   Zdjango.contrib.auth.formsr   r   Z'django.contrib.auth.password_validationr   Zdjango.core.exceptionsr   Zdjango.utils.translationr   r>   Zdjango.utilsr	   Zdatetimer
   rc   Zapps.accounts.modelsr   r   r   ZFormr   rS   rp   rr   Z	ModelFormrw   r,   r,   r,   r-   <module>   s"     43E