U
    }h</                     @   s.  d 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
 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 eeed	d
d Zeeed	dd Zee	ed	dd Zeedd Zeedd Zeedd Zeeed	dd Zee
ed	dd Zdd Zd$ddZdd  Z d!d" Z!d#S )%au  
Adtlas Accounts Signals

This module contains Django signals for the accounts app to handle
automatic actions when user-related events occur.

Features:
    - Auto-create user profiles
    - Log user activities
    - Manage user sessions
    - Handle role assignments
    - Password change tracking

Author: Adtlas Development Team
Version: 2.0.0
Last Updated: 2025-07-08
    )timezone)receiver)Session)	post_savepre_savepost_delete)user_logged_inuser_logged_outuser_login_failed)UserProfileUserRoleUserSession)Activity)senderc                 K   s   |rt jj|d dS )z6
    Create a Profile when a new user is created.
    )userN)r   objectsget_or_creater   instancecreatedkwargs r   0/var/www/html/Focus/src/apps/accounts/signals.pycreate_user_profile!   s    r   c                 K   s   t |dr|j  dS )z2
    Save the Profile when the user is saved.
    profileN)hasattrr   saver   r   r   r   r   r   save_user_profile*   s    
r   c                 K   sX   |j rTz6tjj|j d}|j|jkr:t |_d|_d|_	W n tj
k
rR   Y nX dS )z2
    Track when a user's password is changed.
    )pkr   N)r    r   r   getpasswordr   nowpassword_changed_atfailed_login_attemptsaccount_locked_untilDoesNotExist)r   r   r   old_instancer   r   r   track_password_change3   s    

r)   c           
   	   K   s   |j d}|r |dd }n|j d}|j dd}t |_d|_|jddgd	 tj	|d
d|rn|j
nd d||dd t|dr|jj}|rtjj|d }|r|jnt tjdd }	tjj||||dt |	dd dS )zE
    Log user login activity and create/update session tracking.
    HTTP_X_FORWARDED_FOR,r   REMOTE_ADDRHTTP_USER_AGENT last_activityr%   update_fieldsloginUser Systemz
 logged in
ip_address
user_agentr   actiondescriptionmetadatasessionsession_key   daysT)r   r6   r7   	is_activer/   
expires_at)r>   defaultsN)METAr!   splitr   r#   r/   r%   r   r   log_activityemailr   r<   r>   r   r   filterfirstexpire_date	timedeltar   update_or_create)
r   requestr   r   x_forwarded_forr6   r7   r>   r<   rC   r   r   r   log_user_loginD   s>    

rP   c                 K   s   |r|j d}|r$|dd }n|j d}|j dd}tj|dd|rR|jnd	 d
||dd t|dr|jjrt	j
j|jjdjdd dS )z?
    Log user logout activity and update session tracking.
    r*   r+   r   r,   r-   r.   logoutr3   r4   z logged outr5   r8   r<   r=   FrB   N)rE   r!   rF   r   rG   rH   r   r<   r>   r   r   rI   update)r   rN   r   r   rO   r6   r7   r   r   r   log_user_logoutw   s(    rT   c           	      K   s   |j d}|r |dd }n|j d}|j dd}|dpL|d}|rzttjj|d	}| jd
7  _|jdkrt tjdd |_	|j
ddgd tj|dd|j |||jdd W n tjk
r   Y nX dS )zB
    Log failed login attempts and implement account lockout.
    r*   r+   r   r,   r-   r.   rH   usernamerH   r?         )minutesr%   r&   r0   Zlogin_failedzFailed login attempt for user )r6   r7   Zattempt_countr8   N)rE   r!   rF   r   r   r%   r   r#   rL   r&   r   r   rG   rH   r'   )	r   credentialsrN   r   rO   r6   r7   rH   r   r   r   r   log_failed_login   s0    



r[   c                 K   sN   |rJt j|jdd|jj d|jj |jj|jj|jr>|jjnddd dS )z/
    Log when roles are assigned to users.
    Zrole_assignedRole z assigned to user N)role	role_codeassigned_byr8   )r   rG   r   r]   namerH   coder_   r   r   r   r   log_role_assignment   s    rb   c                 K   s:   t j|jdd|jj d|jj |jj|jjdd dS )z0
    Log when roles are removed from users.
    Zrole_removedr\   z removed from user )r]   r^   r8   N)r   rG   r   r]   r`   rH   ra   r   r   r   r   log_role_removal   s    rc   c                  C   s,   t jjt dd} |  }| jdd |S )zw
    Utility function to clean up expired sessions.
    This can be called by a management command or celery task.
    T)Zexpires_at__ltrB   FrR   )r   r   rI   r   r#   countrS   )Zexpired_sessionsrd   r   r   r   cleanup_expired_sessions   s    re   Z   c                 C   s.   t  t j| d }tjj|d \}}|S )zh
    Utility function to clean up old activity logs.
    Keep only activities from the last X days.
    r@   )created_at__lt)r   r#   rL   r   r   rI   delete)rA   cutoff_dateZdeleted_count_r   r   r   cleanup_old_activities   s
    rk   c              
   K   s   zrddl m} ddlm} |j|dd|dd@ |dd@ |dd	@  sh|jjdd
d td ntd W n" t	k
r } zW 5 d}~X Y nX dS )aQ  
    Create a default admin user if none exists.
    
    This method checks if there are any users in the database. If not,
    it creates a default admin user with the specified email and password.
    
    Note:
        - This method should be called after migrations have been applied.
        - It's a one-time setup operation.
    r   )Q)r   zadmin@adtlas.tvrV   T)is_superuser)is_staffrR   Zadmin123)rH   r"   zDefault admin user created.z-Admin user already exists. Skipping creation.N)
django.db.modelsrl   apps.accounts.modelsr   r   rI   existscreate_superuserprint	Exception)r   r   rl   r   er   r   r   create_default_admin
  s    &
rv   c           
      K   s   zddl m} ddlm} ddlm} ddddd	d
dddddddd
dddddddd
dddddddd
dddddddd
d
dg}|D ]0}|jj|d |d\}}|rtd|j	  qW n" t
k
r }	 zW 5 d }	~	X Y nX d S )!z
    Create default system roles if they don"t exist.
    
    This method creates the basic role structure needed for
    the application to function properly.
    r   )
Permission)ContentType)RolezSuper Administratorsuper_adminz'Full system access with all permissionssystemr?   TF)r`   ra   r:   	role_typelevelrB   
is_defaultZAdministratoradminz&Administrative access to most features   Managermanagerz,Management access to campaigns and analytics   Operatoroperatorz/Operational access to create and manage content   ZViewerZviewerz)Read-only access to view data and reportsrW   ra   )ra   rD   zCreated default role: N)django.contrib.auth.modelsrw   "django.contrib.contenttypes.modelsrx   rp   ry   r   r   rs   r`   rt   )
r   r   rw   rx   ry   Zdefault_rolesZ	role_datar]   r   ru   r   r   r   create_default_roles*  sl    



1
r   N)rf   )"__doc__django.utilsr   django.dispatchr   Zdjango.contrib.sessions.modelsr   Zdjango.db.models.signalsr   r   r   Zdjango.contrib.auth.signalsr   r	   r
   rp   r   r   r   r   Zapps.activities.modelsr   r   r   r)   rP   rT   r[   rb   rc   re   rk   rv   r   r   r   r   r   <module>   s6   






2
!
0




 