U
    45hH                     @   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mZmZ dd	lmZ dd
lmZmZ ddl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dl'm(Z(m)Z)m*Z*m+Z+ ddl,m-Z-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7 G dd deZ8G dd deeZ9G dd d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=G d$d% d%eZ>G d&d' d'eZ?G d(d) d)eZ@G d*d+ d+e&ZAG d,d- d-e&ZBG d.d/ d/eZCG d0d1 d1eZDG d2d3 d3eZEd4S )5a  
Adtlas Authentication Views

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

Features:
    - Enhanced login with remember me functionality
    - User registration with email verification
    - Password reset with secure tokens
    - Profile management
    - Activity logging and session management

Author: Adtlas Development Team
Version: 2.0.0
Last Updated: 2025-07-09
    )	timedelta)timezone)transaction)messages)JsonResponse)redirect)ViewFormView)LoginRequiredMixin)loginlogout)PasswordChangeViewPasswordChangeDoneViewPasswordResetViewPasswordResetDoneViewPasswordResetConfirmViewPasswordResetCompleteView)default_token_generator)urlsafe_base64_decode)	force_str)reverse_lazy)TemplateView)	LoginFormUserRegistrationFormPasswordResetRequestFormPasswordResetConfirmForm)UserUserSessionRoleUserRolePasswordResetToken)Activity)get_client_ip)log_user_activityc                       sH   e Zd ZdZdZeZ fddZ fddZdd Z	 fd	d
Z
  ZS )	LoginViewzS
    Enhanced login view with remember me functionality and security features.
    zauthentication/login.htmlc                    s$   |j jrtdS t j|f||S z<
        Redirect authenticated users to dashboard.
        core:dashboarduseris_authenticatedr   superdispatchselfrequestargskwargs	__class__ 4/var/www/html/Focus/src/apps/authentication/views.pyr+   >   s    zLoginView.dispatchc                    s   t   }| j|d< |S )z:
        Pass request to form for authentication.
        r.   )r*   get_form_kwargsr.   r-   r0   r1   r3   r4   r5   F   s    

zLoginView.get_form_kwargsc                 C   sV  |  }t| j| |jdr0| jjd n| jjd t |_	t |_
|jddgd tj|dd|rv|jnd	 d
| jt| j| jjdd|jddddd tjj|| jjjt| j| jjddt t t|jdrdndd ddd t| jd|  d | jjdp>| jjd}|rNt|S tdS )z*
        Handle successful login.
        remember_mei ' r   
last_loginlast_activity)update_fieldsr   User Systemz performed loginHTTP_USER_AGENT FZemail_password)r7   login_methodr(   actiondescriptionr.   
ip_address
user_agentmetadata      )daysT)rC   rD   r9   
expires_at	is_active)r(   session_keydefaultszWelcome back, !nextr&   )get_user
auth_loginr.   cleaned_datagetsession
set_expiryr   nowr8   r9   saver!   log_activityemailr"   METAr   objectsupdate_or_createrK   r   r   successget_short_nameGETPOSTr   )r-   formr(   next_urlr3   r3   r4   
form_validN   sJ    

 zLoginView.form_validc                    s   |  r(|  D ]}t| jt| q|j D ]N\}}|dkr2|j| jp\|	dd
 }|D ]}t| j| d|  qbq2|jst| jd |jd}|rt |S )zR
        Handle failed login attempt and convert form errors to messages.
        __all___ : z&Please check your input and try again.rX   )non_field_errorsr   errorr.   strerrorsitemsfieldslabelreplacetitlerQ   rR   r*   form_invalid)r-   r`   rh   fieldrj   
field_namerX   r1   r3   r4   rp      s    zLoginView.form_invalid)__name__
__module____qualname____doc__template_namer   
form_classr+   r5   rb   rp   __classcell__r3   r3   r1   r4   r$   7   s   =r$   c                   @   s    e Zd ZdZdd Zdd ZdS )
LogoutViewz4
    Enhanced logout view with session cleanup.
    c                 C   s
   |  |S )z(
        Handle logout request.
        )post)r-   r.   r3   r3   r4   rR      s    zLogoutView.getc              
   C   s   |j }tj|dd|r|jnd d|t||jddddid	 z(tjj||j	j
d
d}d|_|  W n tjk
r   Y nX t| t|d tdS )z,
        Handle logout and cleanup.
        r   r;   r<   z performed logoutr=   r>   logout_methodZuser_initiatedr@   T)r(   rK   rJ   Fz&You have been successfully logged out.
auth:login)r(   r!   rW   rX   r"   rY   rR   r   rZ   rS   rK   rJ   rV   DoesNotExistauth_logoutr   r\   r   )r-   r.   r(   Zuser_sessionr3   r3   r4   r{      s.    zLogoutView.postN)rs   rt   ru   rv   rR   r{   r3   r3   r3   r4   rz      s   rz   c                       s<   e Zd ZdZdZeZ fddZdd Z fddZ	  Z
S )	RegisterViewz7
    User registration view with profile creation.
    zauthentication/register.htmlc                    s$   |j jrtdS t j|f||S r%   r'   r,   r1   r3   r4   r+      s    zRegisterView.dispatchc                 C   s   t   | }z(tjjddd}tjj||ddd W n tjk
rP   Y nX t	j
|dd|rf|jnd d	| jd
t|jt|t| j| jjddd|jdd
 W 5 Q R X t| jd tdS )z1
        Handle successful registration.
        T)
is_defaultrJ   Nz)Default role assigned during registration)r(   roleassigned_bynotescreater;   r<   z performed creater   r=   r>   Z
email_form)Zregistration_methodZemail_verified
r(   rA   rB   r.   object_type	object_idobject_reprrC   rD   rE   zMAccount created successfully! Please check your email to verify your account.r}   )r   atomicrV   r   rZ   rR   r   r   r~   r!   rW   rX   r.   ri   idr"   rY   is_verifiedr   r\   r   )r-   r`   r(   default_roler3   r3   r4   rb      s>    

zRegisterView.form_validc                    s   |  r(|  D ]}t| jt| q|j D ]N\}}|dkr2|j| jp\|	dd
 }|D ]}t| j| d|  qbq2t |S )zQ
        Handle failed registration and convert form errors to messages.
        rc   rd   re   rf   )rg   r   rh   r.   ri   rj   rk   rl   rm   rn   ro   r*   rp   )r-   r`   rh   rq   rj   rr   r1   r3   r4   rp     s    zRegisterView.form_invalid)rs   rt   ru   rv   rw   r   rx   r+   rb   rp   ry   r3   r3   r1   r4   r      s   -r   c                   @   s    e Zd ZdZdZeZdd ZdS )PasswordResetRequestViewz&
    Password reset request view.
    z*authentication/password_reset_request.htmlc                 C   sz   |  }t| jd |rrtj|jdd|jr4|jjnd d| jdt|j	t|t
| j| jjddd	d
id
 tdS )z0
        Handle password reset request.
        z`If the email address exists in our system, you will receive password reset instructions shortly.adminr;   r<   z performed adminr    r=   r>   rA   Zpassword_reset_requestedr   r}   )rV   r   r\   r.   r!   rW   r(   rX   ri   r   r"   rY   rR   r   )r-   r`   reset_tokenr3   r3   r4   rb   -  s&    z#PasswordResetRequestView.form_validN)rs   rt   ru   rv   rw   r   rx   rb   r3   r3   r3   r4   r   &  s   r   c                       s<   e Zd ZdZdZeZ fddZ fddZdd Z	  Z
S )	r   z+
    Password reset confirmation view.
    *authentication/password_reset_confirm.htmlc                    s   | d| _zBtjj | jdd| _| j rBt|d tdW S | jj	| _	W n* tj
k
rx   t|d td Y S X t j|f||S )z;
        Validate reset token before showing form.
        tokenF)r   is_usedz:Password reset link has expired. Please request a new one.zauth:password_reset_requestz6Invalid password reset link. Please request a new one.)rR   r   r    rZ   r   
is_expiredr   rh   r   r(   r~   r*   r+   r,   r1   r3   r4   r+   S  s    

z!PasswordResetConfirmView.dispatchc                    s   t   }| j|d< |S )z$
        Pass user to form.
        r(   )r*   r5   r(   r6   r1   r3   r4   r5   k  s    

z(PasswordResetConfirmView.get_form_kwargsc                 C   s   t  r | }d| j_| j  tj|dd|r8|jnd d| jdt	|j
t	|t| j| jjddd	d
id
 W 5 Q R X t| jd tdS )z3
        Handle successful password reset.
        Tupdater;   r<   z performed updater   r=   r>   rA   Zpassword_reset_completedr   zBPassword reset successfully! Please log in with your new password.r}   )r   r   rV   r   r   r!   rW   rX   r.   ri   r   r"   rY   rR   r   r\   r   )r-   r`   r(   r3   r3   r4   rb   s  s*    

z#PasswordResetConfirmView.form_valid)rs   rt   ru   rv   rw   r   rx   r+   r5   rb   ry   r3   r3   r1   r4   r   L  s   r   c                   @   s$   e Zd ZdZdZdZdZedZdS )CustomPasswordResetViewz%
    Custom password reset view.
    z"authentication/password_reset.htmlz(authentication/password_reset_email.htmlz)authentication/password_reset_subject.txtzauth:password_reset_doneN)	rs   rt   ru   rv   rw   email_template_namesubject_template_namer   success_urlr3   r3   r3   r4   r     s
   r   c                   @   s   e Zd ZdZdZdS )CustomPasswordResetDoneViewz*
    Custom password reset done view.
    z'authentication/password_reset_done.htmlNrs   rt   ru   rv   rw   r3   r3   r3   r4   r     s   r   c                   @   s   e Zd ZdZdZedZdS )CustomPasswordResetConfirmViewz-
    Custom password reset confirm view.
    r   zauth:password_reset_completeN)rs   rt   ru   rv   rw   r   r   r3   r3   r3   r4   r     s   r   c                   @   s   e Zd ZdZdZdS )CustomPasswordResetCompleteViewz.
    Custom password reset complete view.
    z+authentication/password_reset_complete.htmlNr   r3   r3   r3   r4   r     s   r   c                   @   s   e Zd ZdZdd ZdS )AccountActivationViewz"
    Account activation view.
    c                 C   s   zt t|}tjj|d}W n" ttttjfk
r@   d}Y nX |dk	rt	
||rd|_d|_|  tj|dd|j d|dt|jt|t||jdd	d
did
 t|d tdS t|d tdS dS )z,
        Handle account activation.
        )pkNTr   r;   z activated their accountr   r=   r>   rA   Zaccount_activatedr   z-Your account has been activated successfully!zauth:activation_completez*Activation link is invalid or has expired.r}   )r   r   r   rZ   rR   	TypeError
ValueErrorOverflowErrorr~   r   check_tokenr   rJ   rV   r!   rW   rX   ri   r   r"   rY   r   r\   r   rh   )r-   r.   uidb64r   uidr(   r3   r3   r4   rR     s2    
zAccountActivationView.getNrs   rt   ru   rv   rR   r3   r3   r3   r4   r     s   r   c                   @   s   e Zd ZdZdZdS )ActivationSentViewz2
    Activation email sent confirmation view.
    z#authentication/activation_sent.htmlNr   r3   r3   r3   r4   r     s   r   c                   @   s   e Zd ZdZdZdS )ActivationCompleteViewz+
    Account activation complete view.
    z'authentication/activation_complete.htmlNr   r3   r3   r3   r4   r     s   r   c                   @   s   e Zd ZdZdd ZdS )CheckEmailAvailabilityViewz7
    Check if email is available for registration.
    c              
   C   s   zZ|j dd  }|s2tddddddW S tjj|d	 }t| |d
dddW S  t	k
r } z tdt
|dddd W Y S d}~X Y nX dS )z?
        Check if email is available for registration.
        rX   r>   FzEmail is requiredrh   )	availablerh   status   )r   )rX   r\   )r   rX   r   N)r^   rR   lowerstripr   r   rZ   filterexists	Exceptionri   )r-   r.   rX   r   er3   r3   r4   rR     s4    zCheckEmailAvailabilityView.getNr   r3   r3   r3   r4   r     s   r   c                       s,   e Zd ZdZdZedZ fddZ  ZS )CustomPasswordChangeViewzD
    Custom password change view with additional functionality.
    z"accounts/auth/password_change.htmlzaccounts:password_change_donec                    sH   t  |}t| jjdt| j| jjdd| jd t	| jd |S )Npassword_changer=   r>   )r(   rA   rC   rD   r.   z,Your password has been changed successfully.)
r*   rb   r#   r.   r(   r"   rY   rR   r   r\   )r-   r`   responser1   r3   r4   rb     s    z#CustomPasswordChangeView.form_valid)	rs   rt   ru   rv   rw   r   r   rb   ry   r3   r3   r1   r4   r     s   r   c                   @   s   e Zd ZdZdZdS )CustomPasswordChangeDoneViewz+
    Custom password change done view.
    z'accounts/auth/password_change_done.htmlNr   r3   r3   r3   r4   r   *  s   r   N)Frv   datetimer   django.utilsr   	django.dbr   django.contribr   django.httpr   django.shortcutsr   django.views.genericr   r	   django.contrib.auth.mixinsr
   django.contrib.authr   rP   r   r   django.contrib.auth.viewsr   r   r   r   r   r   django.contrib.auth.tokensr   django.utils.httpr   django.utils.encodingr   django.urlsr   r   Zapps.authentication.formsr   r   r   r   apps.accounts.modelsr   r   r   r   r    apps.activities.modelsr!   apps.common.utilsr"   Zapps.activities.helpersr#   r$   rz   r   r   r   r   r   r   r   r   r   r   r   r   r3   r3   r3   r4   <module>   sF    q/O&J
('