U
    Lnh;                    @   sD  d Z ddlZddlmZmZ ddlmZmZ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mZmZ ddlmZmZmZmZ ddlmZ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+m,Z, ddl-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 ddl7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z= ddl>m?Z?m@Z@mAZAmBZBmCZC ddlDmEZE ddlFmGZG ddlHmIZI eJeKZLG dd dee/ZMG dd dee1ZNG dd dee3ZOG d d! d!eee3ZPG d"d# d#eee.ZQG d$d% d%eee/ZRG d&d' d'eee0ZSG d(d) d)eee1ZTG d*d+ d+eee2ZUG d,d- d-ee/ZVG d.d/ d/ee1ZWG d0d1 d1eee.ZXG d2d3 d3eee/ZYG d4d5 d5eee0ZZG d6d7 d7eee1Z[G d8d9 d9eee2Z\G d:d; d;eee.Z]G d<d= d=eee2Z^G d>d? d?eee5Z_G d@dA dAeee5Z`G dBdC dCeee5ZaG dDdE dEeee6ZbdS )Fa  
Focus Accounts Views Module

This module contains all class-based views for the accounts application,
including user management, authentication, profiles, roles,
and security features.

The module follows Django best practices by using class-based views (CBVs)
for better code organization, reusability, and maintainability.

Author: Focus Development Team
Version: 1.0.0
Created: 2025-01-01
Last Updated: 2025-01-01

Classes:
    Authentication Views: 
        - PasswordChangeView: Handles password changes 
    
    Profile Management Views:
        - ProfileDetailView: Shows user profile details
        - ProfileUpdateView: Updates user profiles

    Dashboard Views:
        - DashboardView: Main accounts dashboard
        - UserStatsView: User statistics and analytics
    
    User Management Views:
        - UserListView: Lists all users with pagination and filtering
        - UserDetailView: Shows detailed user information
        - UserCreateView: Creates new users
        - UserUpdateView: Updates existing users
        - UserDeleteView: Soft deletes users
    
    Role Management Views:
        - RoleListView: Lists all roles
        - RoleDetailView: Shows role details
        - RoleCreateView: Creates new roles
        - RoleUpdateView: Updates existing roles
        - RoleDeleteView: Deletes roles
    
    Security Views:
        - UserSessionListView: Lists active user sessions
        - UserSessionDeleteView: Terminates user sessions
        - SecurityLogView: Shows security audit logs
    
    N)datetime	timedelta)AnyDictOptional)messages)LoginRequiredMixinPermissionRequiredMixin)PermissionDenied)	Paginator)transaction)QCountAvg)HttpRequestHttpResponseJsonResponseHttp404)get_object_or_404redirect)reverse_lazyreverse)timezone)method_decorator)
cache_page)csrf_exempt)require_http_methodsrequire_POST)	ListView
DetailView
CreateView
UpdateView
DeleteViewTemplateViewFormViewRedirectViewView   )UserProfileRoleUserRoleUserSessionPasswordResetToken)UserUpdateFormProfileUpdateFormRoleFormRoleAssignmentFormUserCreateForm)user_has_permission)get_client_ip)log_user_activityc                       sF   e Zd ZdZeZdZdZd
ddZe	e
ee	f d fdd	Z  ZS )ProfileDetailView
  
    Display detailed user profile information.
    
    This view shows comprehensive profile information for a user,
    including personal details, and activity summary.
    
    Attributes:
        model (Model): The Profile model
        template_name (str): Template for rendering profile details
        context_object_name (str): Name of the context variable for the profile
    
    Methods:
        get_object: Returns the profile object
        get_context_data: Adds additional context for profile display
    %accounts/profiles/profile_detail.htmlprofileNc                 C   s^   | j d}|r@tt|d}|| jjkrH| jjdsHtdn| jj}tj	j
|d\}}|S a2  
        Return the profile object.
        
        This method gets the profile for the specified user or
        the current user if no user is specified.
        
        Args:
            queryset: Optional queryset to use
            
        Returns:
            Profile: The profile object
        user_ididzaccounts.view_profilez/You don't have permission to view this profile.userkwargsgetr   r(   requestr?   has_permr
   r)   objectsget_or_createselfquerysetr;   r?   r9   created rK   ./var/www/html/Focus/src/apps/accounts/views.py
get_objectt   s    
zProfileDetailView.get_objectrA   returnc                    s   t  jf |}|d }|j}|d| p.|j d|j d ||d< |jjddd	d	|d
< || j
jkp| j
jd|d< |j|j|j |jjdd d|d< |S z
        Add additional context for profile display.
        
        Args:
            **kwargs: Additional keyword arguments from parent class
            
        Returns:
            Dict[str, Any]: Context dictionary with additional data
        r9   z
Profile - zProfile information for 
page_titlepage_descriptionuser_objT	is_activerolerole__levelactive_rolesaccounts.change_profileZcan_edit_profile)Zmember_since
last_logintotal_rolesrY   Zprofile_statssuperget_context_datar?   updateget_full_nameusernameuserrole_setfilterselect_relatedorder_byrC   rD   date_joinedr[   countrH   rA   contextr9   r?   	__class__rK   rL   r_      s0    

z"ProfileDetailView.get_context_data)N__name__
__module____qualname____doc__r)   modeltemplate_namecontext_object_namerM   r   r   strr_   __classcell__rK   rK   rk   rL   r6   ^   s   
r6   c                       sh   e Zd ZdZeZeZdZdddZ	e
eee
f d fddZeed	 fd
dZedddZ  ZS )ProfileUpdateView\  
    Update user profile information.
    
    This view provides a form for updating profile information
    including personal details and preferences.
    
    Attributes:
        model (Model): The Profile model
        form_class (Form): Form class for profile updates
        template_name (str): Template for rendering the update form
    
    Methods:
        get_object: Returns the profile object to update
        get_context_data: Adds additional context for the form
        form_valid: Handles successful form submission
        get_success_url: Returns URL to redirect to after update
    #accounts/profiles/profile_form.htmlNc                 C   s^   | j d}|r@tt|d}|| jjkrH| jjdsHtdn| jj}tj	j
|d\}}|S z
        Return the profile object to update.
        
        Args:
            queryset: Optional queryset to use
            
        Returns:
            Profile: The profile object to update
        r;   r<   rZ   z/You don't have permission to edit this profile.r>   r@   rG   rK   rK   rL   rM      s    
zProfileUpdateView.get_objectrN   c                    sL   t  jf |}|d }|d|j p,|jj d|jj ddd |S 
        Add additional context for the form.
        
        Args:
            **kwargs: Additional keyword arguments from parent class
            
        Returns:
            Dict[str, Any]: Context dictionary with additional data
        objectzEdit Profile - zUpdate profile information for UpdatezUpdate ProfilerR   rS   Zform_actionZsubmit_textr^   r_   r`   r?   ra   rb   rH   rA   rj   r9   rk   rK   rL   r_      s    z"ProfileUpdateView.get_context_dataformrO   c                    sD   t  |}t| jjdd| jjj t| jd t	| jd |S z
        Handle successful form submission.
        
        Args:
            form (ProfileUpdateForm): The validated form
            
        Returns:
            HttpResponse: Redirect response to success URL
        profile_updatedzUpdated profile for user r?   actiondescription
ip_addressz&Profile has been updated successfully.
r^   
form_validr5   rC   r?   r}   rb   r4   r   successrH   r   responserk   rK   rL   r     s    zProfileUpdateView.form_validrO   c                 C   s   t dd| jjjidS 
        Return URL to redirect to after successful update.
        
        Returns:
            str: The success URL
        zaccounts:profile_detailr;   rA   r   r}   r?   r=   rH   rK   rK   rL   get_success_url"  s    z!ProfileUpdateView.get_success_url)Nrn   ro   rp   rq   r)   rr   r/   
form_classrs   rM   r   r   ru   r_   r   r   r   rv   rK   rK   rk   rL   rw      s   
rw   c                       sr   e Zd ZdZdZeeeef d fddZeeef dddZ	eeef dd	d
Z
deedddZ  ZS )DashboardViewa
  
    Main accounts dashboard view.
    
    This view provides an overview of the accounts system including
    statistics, recent activity, and quick access to common functions.
    
    Attributes:
        template_name (str): Template for rendering the dashboard
    
    Methods:
        get_context_data: Adds dashboard data to the context
        get_user_statistics: Gets user-related statistics
        get_role_statistics: Gets role-related statistics
        get_recent_activity: Gets recent system activity
    z!accounts/dashboard/dashboard.htmlrN   c                    s   t  jf |}|ddd ||  |  d |  |d< g }| jjdrl|	dt
dd	d
d | jjdr|	dt
dddd | jjdr|	dt
dddd ||d< |S )z
        Add dashboard data to the context.
        
        Args:
            **kwargs: Additional keyword arguments from parent class
            
        Returns:
            Dict[str, Any]: Context dictionary with dashboard data
        zAccounts Dashboardz*Overview of the accounts management systemrQ   )
user_stats
role_statsrecent_activityaccounts.add_userCreate Userzaccounts:user_createz	user-pluszAdd a new user account)titleurliconr   accounts.view_userzManage Usersaccounts:user_listuserszView and manage user accountsaccounts.view_rolezManage Rolesaccounts:role_listshieldzView and manage user rolesquick_links)r^   r_   r`   get_user_statisticsget_role_statisticsget_recent_activityrC   r?   rD   appendr   )rH   rA   rj   r   rk   rK   rL   r_   D  sD    zDashboardView.get_context_datar   c                 C   s   t  }|tdd }|tdd }tj tjjdd tjjdd tjj|d tjj|d tjj|d d	S )
zt
        Get user-related statistics.
        
        Returns:
            Dict[str, Any]: User statistics
           days   TrU   is_staffdate_joined__gtelast_login__gte)totalactivestaffZnew_last_30_daysZnew_last_7_daysZlogged_in_last_7_days)r   nowr   r(   rE   rh   rd   rH   r   Zlast_30_daysZlast_7_daysrK   rK   rL   r   ~  s    z!DashboardView.get_user_statisticsc                 C   s2   t j t jjdd t jjdd  dS )zt
        Get role-related statistics.
        
        Returns:
            Dict[str, Any]: Role statistics
        TrU   )userrole__is_active)r   r   Z
with_users)r*   rE   rh   rd   distinctr   rK   rK   rL   r     s    z!DashboardView.get_role_statistics
   )limitrO   c                 C   sZ   z<ddl m} |jjddddddgd	d
dd| W S  tk
rT   g  Y S X dS )z
        Get recent system activity.
        
        Args:
            limit (int): Maximum number of activities to return
            
        Returns:
            list: List of recent activities
        r   Activityuser_createduser_updateduser_deletedrole_createdrole_updatedrole_deleted)Z
action__inr?   -created_atN)apps.activities.modelsr   rE   rd   re   rf   ImportError)rH   r   r   rK   rK   rL   r     s&    
    z!DashboardView.get_recent_activity)r   )rn   ro   rp   rq   rs   r   r   ru   r_   r   r   intlistr   rv   rK   rK   rk   rL   r   0  s   :r   c                       sr   e Zd ZdZdZdZeeeef d fddZ	eeef ddd	Z
eeef dd
dZedddZ  ZS )UserStatsViewaM  
    User statistics and analytics view.
    
    This view provides detailed analytics about user activity,
    registration trends, and usage patterns.
    
    Attributes:
        template_name (str): Template for rendering user statistics
        permission_required (str): Required permission to access this view
    
    Methods:
        get_context_data: Adds statistics data to the context
        get_registration_trends: Gets user registration trends
        get_login_activity: Gets login activity statistics
        get_role_distribution: Gets role distribution statistics
    z"accounts/dashboard/user_stats.htmlr   rN   c                    s@   t  jf |}|ddd ||  |  |  d |S )z
        Add statistics data to the context.
        
        Args:
            **kwargs: Additional keyword arguments from parent class
            
        Returns:
            Dict[str, Any]: Context dictionary with statistics data
        zUser Statisticsz1Detailed analytics about user activity and trendsrQ   )Zregistration_trendsZlogin_activityZrole_distribution)r^   r_   r`   get_registration_trendsget_login_activityget_role_distributionrH   rA   rj   rk   rK   rL   r_     s    zUserStatsView.get_context_datar   c                 C   s   t  }|tdd }g }tdD ]f}|td|d  d jdd}|td| d jdd}tjj||d }|	|
d|d	 q"tt|tjj|d
 dS )z
        Get user registration trends over time.
        
        Returns:
            Dict[str, Any]: Registration trend data
        im  r      r   r'   )day)r   Zdate_joined__ltz%Y-%m)monthrh   r   )monthlyZtotal_last_year)r   r   r   rangereplacer(   rE   rd   rh   r   strftimer   reversed)rH   r   Zlast_12_monthsZmonthly_registrationsimonth_start	month_endrh   rK   rK   rL   r     s&    


z%UserStatsView.get_registration_trendsc                 C   sZ   t  }|tdd }|tdd }tjj|d tjj|d tjjdd dS )zz
        Get login activity statistics.
        
        Returns:
            Dict[str, Any]: Login activity data
        r   r   r   r   T)Zlast_login__isnull)Zactive_last_30_daysZactive_last_7_daysZnever_logged_in)r   r   r   r(   rE   rd   rh   r   rK   rK   rL   r     s    z UserStatsView.get_login_activityc                 C   s(   t tjjtdddddddS )zv
        Get role distribution statistics.
        
        Returns:
            list: Role distribution data
        userrole__userTr   
user_countnamer   z-user_count)r   r*   rE   annotater   valuesrf   r   rK   rK   rL   r   *  s    
 z#UserStatsView.get_role_distribution)rn   ro   rp   rq   rs   permission_requiredr   r   ru   r_   r   r   r   r   rv   rK   rK   rk   rL   r     s   "r   c                       sp   e Zd ZdZeZdZdZdZdZ	dd Z
eeeef d fd	d
ZedddZeeef dddZ  ZS )UserListViewan  
    Display a paginated list of all users with filtering and search capabilities.
    
    This view provides a comprehensive user management interface with features
    including search, filtering by role, pagination, and bulk actions.
    
    Attributes:
        model (Model): The User model
        template_name (str): Template for rendering the user list
        context_object_name (str): Name of the context variable for the user list
        paginate_by (int): Number of users per page
        permission_required (str): Required permission to access this view
    
    Methods:
        get_queryset: Returns filtered and searched user queryset
        get_context_data: Adds additional context for filtering and statistics
        get_search_query: Extracts search query from request parameters
        get_filter_params: Extracts filter parameters from request
    zaccounts/users/user_list.htmlr      r   c                 C   sB  t jdd}|  }|rV|t|dt|dB t|dB t|dB t|dB }|  }|dd	k	r||j|d d
}|dd	k	r|j|d d}|dr|j|d dd}|dr|j|d d}|dr|j|d d}| j	j
dd}dddddddddddd dd!g}||kr0||}n
|d}| S )"a  
        Return filtered and searched user queryset.
        
        This method applies search and filter parameters to the base
        queryset to provide dynamic filtering capabilities.
        
        Returns:
            QuerySet: Filtered user queryset
        r9   userrole_set__role)Zusername__icontains)Zemail__icontains)Zfirst_name__icontains)Zlast_name__icontains)Z profile__phone_number__icontainsrV   NrU   r   r   rW   T)Zuserrole__role__idr   date_joined_fromr   date_joined_to)Zdate_joined__lteordering-date_joinedrb   	-usernameemail-email
first_name-first_name	last_namez
-last_namerg   r[   -last_loginz
-is_active)r(   rE   re   prefetch_relatedget_search_queryrd   r   get_filter_paramsrB   rC   GETrf   r   )rH   rI   search_queryfilter_paramsr   valid_orderingsrK   rK   rL   get_querysetV  sl    	


       	

zUserListView.get_querysetrN   c                    s   t  jf |}|ddd ||  |  | jjddd |tj	j
ddd	d
dddddddddg
d tj	 }tj	j
dd }tj	j
dd }tj	j
t tdd d }|d|||| ||di |S )a  
        Add additional context for filtering and statistics.
        
        This method extends the base context with filter options,
        search parameters, and user statistics.
        
        Args:
            **kwargs: Additional keyword arguments from parent class
            
        Returns:
            Dict[str, Any]: Context dictionary with additional data
        zUser Managementz+Manage system users, roles, and permissionsrQ   r   r   )r   r   current_orderingTrU   r   )rb   zUsername (A-Z))r   zUsername (Z-A))r   zEmail (A-Z))r   zEmail (Z-A))r   zFirst Name (A-Z))r   zFirst Name (Z-A))rg   zDate Joined (Oldest))r   zDate Joined (Newest))r[   zLast Login (Oldest))r   zLast Login (Recent))available_rolesZordering_optionsr   r   r   r   r   )r   r   inactiver   recent)r^   r_   r`   r   r   rC   r   rB   r*   rE   rd   rf   r(   rh   r   r   r   )rH   rA   rj   total_usersactive_usersZstaff_usersZrecent_usersrk   rK   rL   r_     sP    


zUserListView.get_context_datar   c                 C   s   | j jdd S )z
        Extract search query from request parameters.
        
        Returns:
            str: The search query string
        search )rC   r   rB   stripr   rK   rK   rL   r     s    zUserListView.get_search_queryc              	   C   s*  i }| j jdr(| j jddk|d< | j jdrL| j jddk|d< | j jdrzt| j jd|d< W n ttfk
r   Y nX | j jdrz"t| j jdd |d< W n ttfk
r   Y nX | j jdr&z"t| j jdd |d< W n ttfk
r$   Y nX |S )z
        Extract filter parameters from request.
        
        Returns:
            Dict[str, Any]: Dictionary of filter parameters
        rV   truer   rW   r   z%Y-%m-%dr   )	rC   r   rB   r   
ValueError	TypeErrorr   strptimedate)rH   paramsrK   rK   rL   r     s6      zUserListView.get_filter_params)rn   ro   rp   rq   r(   rr   rs   rt   paginate_byr   r   r   r   ru   r_   r   r   rv   rK   rK   rk   rL   r   :  s   IB	r   c                       sr   e Zd ZdZeZdZdZdZd fdd	Z	e
eee
f d fd	d
ZdeeedddZeedddZ  ZS )UserDetailViewa  
    Display detailed information about a specific user.
    
    This view shows comprehensive user information including profile data,
    role assignments, activity history, and security information.
    
    Attributes:
        model (Model): The User model
        template_name (str): Template for rendering user details
        context_object_name (str): Name of the context variable for the user
        permission_required (str): Required permission to access this view
    
    Methods:
        get_object: Returns the user object with related data
        get_context_data: Adds additional context for user details
        get_user_activity: Gets recent activity for the user
        get_user_sessions: Gets active sessions for the user
    zaccounts/users/user_detail.htmlrT   r   Nc                    s4   |dkr|   }|d}|ddd}t |S )aC  
        Return the user object with related data.
        
        This method optimizes the query by selecting related data
        to avoid N+1 query problems.
        
        Args:
            queryset: Optional queryset to use
            
        Returns:
            User: The user object with related data
        Nr9   r   sessionsreset_tokens)r   re   r   r^   rM   )rH   rI   rk   rK   rL   rM   /  s    
zUserDetailView.get_objectrN   c                    s   t  jf |}|d }|d| p(|j d|j d |jjdddd}|||	 rp|
 jnd	d
 | ||d< | ||d< || |j|jjdt d d | jjd|d< | jjd|d< |S )a  
        Add additional context for user details.
        
        This method extends the base context with user-specific data
        including activity history, sessions, and role information.
        
        Args:
            **kwargs: Additional keyword arguments from parent class
            
        Returns:
            Dict[str, Any]: Context dictionary with additional data
        rT   zUser Details - zDetailed information for user rQ   TrU   rW   rX   N)rY   Zhighest_roler   active_sessionsF)is_usedexpires_at__gt)account_lockedfailed_login_attemptsZpassword_reset_tokensaccounts.change_userZcan_edit_useraccounts.delete_userZcan_delete_user)r^   r_   r`   ra   rb   rc   rd   re   rf   existsfirstrW   get_user_activityget_user_sessionsis_account_lockedr  r  r   r   rh   rC   r?   rD   )rH   rA   rj   rT   rY   rk   rK   rL   r_   I  s<    

zUserDetailView.get_context_datar   )r?   r   rO   c                 C   sH   z*ddl m} |jj|ddd| W S  tk
rB   g  Y S X dS )a  
        Get recent activity for the user.
        
        Args:
            user (User): The user to get activity for
            limit (int): Maximum number of activities to return
            
        Returns:
            list: List of recent user activities
        r   r   r>   r   N)r   r   rE   rd   rf   r   )rH   r?   r   r   rK   rK   rL   r    s    z UserDetailView.get_user_activityr?   rO   c                 C   s   t jj|dt ddS )z
        Get active sessions for the user.
        
        Args:
            user (User): The user to get sessions for
            
        Returns:
            list: List of active user sessions
        Tr?   rV   r  -last_activity)r,   rE   rd   r   r   rf   )rH   r?   rK   rK   rL   r    s    
z UserDetailView.get_user_sessions)N)r   )rn   ro   rp   rq   r(   rr   rs   rt   r   rM   r   r   ru   r_   r   r   r  r  rv   rK   rK   rk   rL   r
    s   7r
  c                       s   e Zd ZdZeZeZdZdZ	e
dZeeeef d fddZejeed fd	d
Zeed fddZeddddZ  ZS )UserCreateViewa  
    Create a new user account.
    
    This view provides a form for creating new user accounts with
    profile information and initial role assignments.
    
    Attributes:
        model (Model): The User model
        form_class (Form): Form class for user creation
        template_name (str): Template for rendering the creation form
        permission_required (str): Required permission to access this view
        success_url (str): URL to redirect to after successful creation
    
    Methods:
        get_context_data: Adds additional context for the form
        form_valid: Handles successful form submission
        form_invalid: Handles failed form submission
        send_welcome_email: Sends welcome email to new user
    accounts/users/user_form.htmlr   r   rN   c                    sD   t  jf |}|ddddd |dtjjddd	i |S )
r|   zCreate New Userz2Create a new user account with profile informationCreater   r   r   TrU   r   )r^   r_   r`   r*   rE   rd   rf   r   rk   rK   rL   r_     s     zUserCreateView.get_context_datar   c           	         s  t  |}| j}|jdd|jddd}| D ]\}}|r8t|j|| q8|j  |jd}|rz2t	j
j|dd}tj
j||| jjt dd	 W n$ t	jk
r   t| jd
 Y nX | | t| jjdd|j d|j dt| jd t| jd|j d |S )ab  
        Handle successful form submission.
        
        This method creates the user account, sets up the profile,
        assigns initial roles, and sends a welcome email.
        
        Args:
            form (UserCreationForm): The validated form
            
        Returns:
            HttpResponse: Redirect response to success URL
        phone_numberr  bior  r   Zinitial_roleT)r=   rV   z*Initial role assigned during user creation)r?   rW   assigned_by
valid_fromnotesz>Selected role not found. User created without role assignment.r   zCreated new user account:  ()r   User account " " has been created successfully.)r^   r   r}   cleaned_datarB   itemssetattrr9   saver*   rE   r+   createrC   r?   r   r   DoesNotExistr   warningsend_welcome_emailr5   rb   r   r4   r   )	rH   r   r   r?   profile_datafieldvalueZinitial_role_idrW   rk   rK   rL   r     sJ    



zUserCreateView.form_validc                    s   t | jd t |S )z
        Handle failed form submission.
        
        Args:
            form (UserCreationForm): The invalid form
            
        Returns:
            HttpResponse: Response with form errors
        z.Please correct the errors below and try again.)r   errorrC   r^   form_invalid)rH   r   rk   rK   rL   r5  "  s
    zUserCreateView.form_invalidNr  c              
   C   sd   zt d|j  W nH tk
r^ } z*t d|j d|  t| jd W 5 d}~X Y nX dS )zx
        Send welcome email to new user.
        
        Args:
            user (User): The newly created user
        z Welcome email sent to new user: z Failed to send welcome email to : z?User created successfully, but welcome email could not be sent.N)loggerinfor   	Exceptionr4  r   r/  rC   )rH   r?   erK   rK   rL   r0  4  s    z!UserCreateView.send_welcome_email)rn   ro   rp   rq   r(   rr   r2   r   rs   r   r   success_urlr   r   ru   r_   r   atomicr   r   r5  r0  rv   rK   rK   rk   rL   r    s   Br  c                       sv   e Zd ZdZeZeZdZdZ	d fdd	Z
eeeef d fdd	Zejeed
 fddZedddZ  ZS )UserUpdateViewa  
    Update an existing user account.
    
    This view provides a form for updating user account information
    including profile data and role assignments.
    
    Attributes:
        model (Model): The User model
        form_class (Form): Form class for user updates
        template_name (str): Template for rendering the update form
        permission_required (str): Required permission to access this view
    
    Methods:
        get_object: Returns the user object to update
        get_context_data: Adds additional context for the form
        form_valid: Handles successful form submission
        get_success_url: Returns URL to redirect to after update
    r  r  Nc                    s2   t  |}| jjds.|| jjkr.td|S )z
        Return the user object to update.
        
        Args:
            queryset: Optional queryset to use
            
        Returns:
            User: The user object to update
        r  z,You don't have permission to edit this user.)r^   rM   rC   r?   rD   r
   rH   rI   objrk   rK   rL   rM   n  s
    
zUserUpdateView.get_objectrN   c                    s|   t  jf |}|d }|d| p(|j d|j ddd |dtjjdd	d
i |j	jdd	
d|d< |S )r|   r}   zEdit User - zUpdate information for user r~   zUpdate Userr   r   TrU   r   rW   Zcurrent_roles)r^   r_   r`   ra   rb   r*   rE   rd   rf   rc   re   rH   rA   rj   rT   rk   rK   rL   r_     s$    
 zUserUpdateView.get_context_datar   c              	      s  t jj| jjd}t |}| j}|jdd|jddd}| D ]\}}|dk	rJt	|j
|| qJ|j
  g }dD ]<}t||}	t||}
|	|
kr||| d|	 d	|
 d
 q||rt| jjdd|j dd| t| jd t| jd|j d |S )z
        Handle successful form submission.
        
        Args:
            form (UserUpdateForm): The validated form
            
        Returns:
            HttpResponse: Redirect response to success URL
        pkr  r  r   r!  N)rb   r   r   r   rV   r   z: "u   " → ""r   zUpdated user r6  z, r   r'   " has been updated successfully.)r(   rE   rB   r}   rB  r^   r   r)  r*  r+  r9   r,  getattrr   r5   rC   r?   rb   joinr4   r   r   )rH   r   Zoriginal_userr   r?   r1  r2  r3  changes	old_value	new_valuerk   rK   rL   r     s8    


zUserUpdateView.form_validr   c                 C   s   t dd| jjidS )r   accounts:user_detailrB  r   r   r}   rB  r   rK   rK   rL   r     s    zUserUpdateView.get_success_url)N)rn   ro   rp   rq   r(   rr   r.   r   rs   r   rM   r   r   ru   r_   r   r<  r   r   r   rv   rK   rK   rk   rL   r=  T  s   "5r=  c                       sl   e Zd ZdZeZdZdZedZ	d fdd	Z
ejeeeedd	d
Zeeeef d fddZ  ZS )UserDeleteViewa  
    Soft delete a user account.
    
    This view provides confirmation and soft deletion of user accounts.
    Users are deactivated rather than permanently deleted to maintain
    data integrity and audit trails.
    
    Attributes:
        model (Model): The User model
        template_name (str): Template for deletion confirmation
        permission_required (str): Required permission to access this view
        success_url (str): URL to redirect to after deletion
    
    Methods:
        get_object: Returns the user object to delete
        delete: Performs soft deletion instead of hard deletion
        get_context_data: Adds additional context for confirmation
    z'accounts/users/user_confirm_delete.htmlr  r   Nc                    s2   t  |}|jrtd|| jjkr.td|S )z
        Return the user object to delete.
        
        Args:
            queryset: Optional queryset to use
            
        Returns:
            User: The user object to delete
        z%Superuser accounts cannot be deleted.z#You cannot delete your own account.)r^   rM   is_superuserr
   rC   r?   r>  rk   rK   rL   rM     s    
zUserDeleteView.get_objectrC   argsrA   rO   c                 O   s   |   | _| j}d|_|jdgd tjj|ddjdt	 |j
d tjj|ddjdt	 d t|j
dd	|j d
|j dt|d t|d|j d t| jS )a  
        Perform soft deletion instead of hard deletion.
        
        This method deactivates the user account and terminates
        all active sessions instead of permanently deleting the user.
        
        Args:
            request (HttpRequest): The HTTP request object
            *args: Additional positional arguments
            **kwargs: Additional keyword arguments
            
        Returns:
            HttpResponse: Redirect response to success URL
        FrV   update_fieldsT)r?   rV   )rV   Zdeactivated_atZdeactivated_by)rV   last_activityr   Deactivated user account: r%  r&  r   r'  z$" has been deactivated successfully.)rM   r}   rV   r,  r+   rE   rd   r`   r   r   r?   r,   r5   rb   r   r4   r   r   r   r;  rH   rC   rO  rA   r?   rK   rK   rL   delete  s6    
	zUserDeleteView.deleterN   c                    sv   t  jf |}|d }|d| p(|j d|j d ||jjdd tj	j|dt
 d d |S )	
        Add additional context for confirmation.
        
        Args:
            **kwargs: Additional keyword arguments from parent class
            
        Returns:
            Dict[str, Any]: Context dictionary with additional data
        r}   zDelete User - zConfirm deletion of user rQ   TrU   r  )Zactive_roles_countZactive_sessions_count)r^   r_   r`   ra   rb   rc   rd   rh   r,   rE   r   r   r@  rk   rK   rL   r_   M  s    
	zUserDeleteView.get_context_data)N)rn   ro   rp   rq   r(   rr   rs   r   r   r;  rM   r   r<  r   r   r   rU  r   ru   r_   rv   rK   rK   rk   rL   rL    s   8rL  c                       sF   e Zd ZdZeZdZdZd
ddZe	e
ee	f d fdd	Z  ZS )UserProfileDetailViewr7   r8   r9   Nc                 C   s^   | j d}|r@tt|d}|| jjkrH| jjdsHtdn| jj}tj	j
|d\}}|S r:   r@   rG   rK   rK   rL   rM     s    
z UserProfileDetailView.get_objectrN   c                    s   t  jf |}|d }|j}|d| p.|j d|j d ||d< |jjddd	d	|d
< || j
jkp| j
jd|d< |j|j|j |jjdd d|d< |S rP   r]   ri   rk   rK   rL   r_     s0    

z&UserProfileDetailView.get_context_data)Nrm   rK   rK   rk   rL   rW  r  s   
rW  c                       sh   e Zd ZdZeZeZdZdddZ	e
eee
f d fddZeed	 fd
dZedddZ  ZS )UserProfileUpdateViewrx   ry   Nc                 C   s^   | j d}|r@tt|d}|| jjkrH| jjdsHtdn| jj}tj	j
|d\}}|S rz   r@   rG   rK   rK   rL   rM     s    
z UserProfileUpdateView.get_objectrN   c                    sL   t  jf |}|d }|d|j p,|jj d|jj ddd |S r{   r   r   rk   rK   rL   r_     s    z&UserProfileUpdateView.get_context_datar   c                    sD   t  |}t| jjdd| jjj t| jd t	| jd |S r   r   r   rk   rK   rL   r     s    z UserProfileUpdateView.form_validr   c                 C   s   t dd| jjjidS r   r   r   rK   rK   rL   r   6  s    z%UserProfileUpdateView.get_success_url)Nr   rK   rK   rk   rL   rX    s   
rX  c                       sL   e Zd ZdZeZdZdZdZdZ	dd Z
eeeef d fd	d
Z  ZS )RoleListViewa  
    Display a list of all roles with filtering capabilities.
    
    This view provides a comprehensive role management interface
    with search, filtering, and pagination.
    
    Attributes:
        model (Model): The Role model
        template_name (str): Template for rendering the role list
        context_object_name (str): Name of the context variable for the role list
        paginate_by (int): Number of roles per page
        permission_required (str): Required permission to access this view
    
    Methods:
        get_queryset: Returns filtered role queryset
        get_context_data: Adds additional context for filtering
    zaccounts/roles/role_list.htmlroles   r   c                 C   s   t jjtdddd}| jjdd }|rR|t	|dt	|dB t	|d	B }| jjd
}|dk	rx|j|dkd}| jjdd}ddddddg}||kr|
|}n
|
d}|S )zw
        Return filtered role queryset.
        
        Returns:
            QuerySet: Filtered role queryset
        r   Tr   r   r   r  )Zname__icontains)Zcode__icontains)Zdescription__icontainsrV   Nr  rU   r   levelr   z-namecodez-codez-level)r*   rE   r   r   rC   r   rB   r  rd   r   rf   )rH   rI   r   rV   r   r   rK   rK   rL   r   ^  s*    

zRoleListView.get_querysetrN   c                    s   t  jf |}|ddd || jjdd| jjdd| jjdd	 tj }tjj	d
d }|d|||| di |S )
        Add additional context for filtering.
        
        Args:
            **kwargs: Additional keyword arguments from parent class
            
        Returns:
            Dict[str, Any]: Context dictionary with additional data
        zRole Managementz#Manage system roles and permissionsrQ   r   r  r   r\  rV   )r   r   Zis_active_filterTrU   r   )r   r   r   )
r^   r_   r`   rC   r   rB   r*   rE   rh   rd   )rH   rA   rj   r\   rY   rk   rK   rL   r_     s(    
zRoleListView.get_context_data)rn   ro   rp   rq   r*   rr   rs   rt   r	  r   r   r   r   ru   r_   rv   rK   rK   rk   rL   rY  D  s   $rY  c                       s@   e Zd ZdZeZdZdZdZe	e
ee	f d fddZ  ZS )RoleDetailViewa  
    Display detailed information about a specific role.
    
    This view shows comprehensive role information including
    permissions, assigned users, and usage statistics.
    
    Attributes:
        model (Model): The Role model
        template_name (str): Template for rendering role details
        context_object_name (str): Name of the context variable for the role
        permission_required (str): Required permission to access this view
    
    Methods:
        get_context_data: Adds additional context for role details
    zaccounts/roles/role_detail.htmlrW   r   rN   c                    s   t  jf |}|d }|d|j d|j d tjj|dddd|d	< tjj|d
	 tjj|dd	 d|d< | j
jd|d< | j
jd|d< |S )z
        Add additional context for role details.
        
        Args:
            **kwargs: Additional keyword arguments from parent class
            
        Returns:
            Dict[str, Any]: Context dictionary with additional data
        rW   zRole Details - zDetailed information for role rQ   T)userrole__roler   r9   rb   Zassigned_users)r`  r   r   r   accounts.change_roleZcan_edit_roleaccounts.delete_roleZcan_delete_role)r^   r_   r`   r   r(   rE   rd   re   rf   rh   rC   r?   rD   rH   rA   rj   rW   rk   rK   rL   r_     s.    


	zRoleDetailView.get_context_data)rn   ro   rp   rq   r*   rr   rs   rt   r   r   r   ru   r_   rv   rK   rK   rk   rL   r_    s   r_  c                       s\   e Zd ZdZeZeZdZdZ	e
dZeeeef d fddZeed fd	d
Z  ZS )RoleCreateViewa_  
    Create a new role.
    
    This view provides a form for creating new roles with
    permissions and access level configuration.
    
    Attributes:
        model (Model): The Role model
        form_class (Form): Form class for role creation
        template_name (str): Template for rendering the creation form
        permission_required (str): Required permission to access this view
        success_url (str): URL to redirect to after successful creation
    
    Methods:
        get_context_data: Adds additional context for the form
        form_valid: Handles successful form submission
    accounts/roles/role_form.htmlzaccounts.add_roler   rN   c                    s&   t  jf |}|ddddd |S )r|   zCreate New Rolez4Create a new role with permissions and access levelsr  zCreate Roler   )r^   r_   r`   r   rk   rK   rL   r_     s    zRoleCreateView.get_context_datar   c                    sZ   t  |}| j}t| jjdd|j d|j dt| jd t	
| jd|j d |S )
        Handle successful form submission.
        
        Args:
            form (RoleForm): The validated form
            
        Returns:
            HttpResponse: Redirect response to success URL
        r   zCreated new role: r%  r&  r   Role "r(  r^   r   r}   r5   rC   r?   r   r]  r4   r   r   rH   r   r   rW   rk   rK   rL   r     s    zRoleCreateView.form_valid)rn   ro   rp   rq   r*   rr   r0   r   rs   r   r   r;  r   r   ru   r_   r   r   rv   rK   rK   rk   rL   re    s   re  c                       sb   e Zd ZdZeZeZdZdZ	e
eee
f d fddZeed fdd	Zed
ddZ  ZS )RoleUpdateViewaZ  
    Update an existing role.
    
    This view provides a form for updating role information
    including permissions and access levels.
    
    Attributes:
        model (Model): The Role model
        form_class (Form): Form class for role updates
        template_name (str): Template for rendering the update form
        permission_required (str): Required permission to access this view
    
    Methods:
        get_context_data: Adds additional context for the form
        form_valid: Handles successful form submission
        get_success_url: Returns URL to redirect to after update
    rf  rb  rN   c                    s>   t  jf |}|d }|d|j d|j ddd |S )r|   r}   zEdit Role - zUpdate information for role r~   zUpdate Roler   )r^   r_   r`   r   rd  rk   rK   rL   r_   U  s    

zRoleUpdateView.get_context_datar   c                    sZ   t  |}| j}t| jjdd|j d|j dt| jd t	
| jd|j d |S )rg  r   zUpdated role: r%  r&  r   rh  rD  ri  rj  rk   rK   rL   r   m  s    zRoleUpdateView.form_validr   c                 C   s   t dd| jjidS )r   zaccounts:role_detailrB  r   rK  r   rK   rK   rL   r     s    zRoleUpdateView.get_success_url)rn   ro   rp   rq   r*   rr   r0   r   rs   r   r   r   ru   r_   r   r   r   rv   rK   rK   rk   rL   rk  <  s   rk  c                       sf   e Zd ZdZeZdZdZedZ	d fdd	Z
eeeedd	d
Zeeeef d fddZ  ZS )RoleDeleteViewaN  
    Delete a role.
    
    This view provides confirmation and deletion of roles.
    Roles with assigned users cannot be deleted.
    
    Attributes:
        model (Model): The Role model
        template_name (str): Template for deletion confirmation
        permission_required (str): Required permission to access this view
        success_url (str): URL to redirect to after deletion
    
    Methods:
        get_object: Returns the role object to delete
        delete: Performs role deletion with validation
        get_context_data: Adds additional context for confirmation
    z'accounts/roles/role_confirm_delete.htmlrc  r   Nc                    s*   t  |}|jjdd r&td|S )z
        Return the role object to delete.
        
        Args:
            queryset: Optional queryset to use
            
        Returns:
            Role: The role object to delete
        TrU   zZCannot delete role with active user assignments. Please remove all user assignments first.)r^   rM   rc   rd   r  r
   r>  rk   rK   rL   rM     s    
zRoleDeleteView.get_objectrN  c                 O   s`   |   | _| j}t|jdd|j d|j dt|d |  t	|d|j d t
| jS )aI  
        Perform role deletion with validation.
        
        Args:
            request (HttpRequest): The HTTP request object
            *args: Additional positional arguments
            **kwargs: Additional keyword arguments
            
        Returns:
            HttpResponse: Redirect response to success URL
        r   zDeleted role: r%  r&  r   rh  z " has been deleted successfully.)rM   r}   r5   r?   r   r]  r4   rU  r   r   r   r;  )rH   rC   rO  rA   rW   rK   rK   rL   rU    s    
zRoleDeleteView.deleterN   c                    s^   t  jf |}|d }|d|j d|j d ||j |jjdd d |S )rV  r}   zDelete Role - zConfirm deletion of role rQ   TrU   ra  )r^   r_   r`   r   rc   rh   rd   rd  rk   rK   rL   r_     s    

zRoleDeleteView.get_context_data)N)rn   ro   rp   rq   r*   rr   rs   r   r   r;  rM   r   r   r   rU  r   ru   r_   rv   rK   rK   rk   rL   rl    s   $rl  c                       sL   e Zd ZdZeZdZdZdZdZ	dd Z
eeeef d fd	d
Z  ZS )UserSessionListViewa  
    Display a list of active user sessions for security monitoring.
    
    This view provides a comprehensive session management interface
    with filtering and session termination capabilities.
    
    Attributes:
        model (Model): The UserSession model
        template_name (str): Template for rendering the session list
        context_object_name (str): Name of the context variable for the session list
        paginate_by (int): Number of sessions per page
        permission_required (str): Required permission to access this view
    
    Methods:
        get_queryset: Returns filtered session queryset
        get_context_data: Adds additional context for filtering
    z#accounts/security/session_list.htmlr  2   zaccounts.view_usersessionc                 C   s   t jd}| jjdddk}|r6|jdt d}| jjdd	 }|r||t
|dt
|d	B t
|d
B t
|dB }| jjdd}ddddddddg}||kr||}n
|d}|S )z}
        Return filtered session queryset.
        
        Returns:
            QuerySet: Filtered session queryset
        r?   active_onlyr  TrV   r  r   r  )Zuser__username__icontains)Zuser__email__icontains)Zip_address__icontains)Zuser_agent__icontainsr   r  user__usernamez-user__username
created_atr   rR  
expires_atz-expires_at)r,   rE   re   rC   r   rB   rd   r   r   r  r   rf   )rH   rI   Zshow_active_onlyr   r   r   rK   rK   rL   r   !  s@        
z UserSessionListView.get_querysetrN   c                    s   t  jf |}|ddd || jjdd| jjdd| jjdd	d	kd
 tj }tjj	dt
 d }|d|||| di |S )r^  zActive User Sessionsz'Monitor and manage active user sessionsrQ   r   r  r   r  ro  r  )r   r   ro  Trp  session_stats)r   r   expired)r^   r_   r`   rC   r   rB   r,   rE   rh   rd   r   r   )rH   rA   rj   Ztotal_sessionsr  rk   rK   rL   r_   L  s.    

z$UserSessionListView.get_context_data)rn   ro   rp   rq   r,   rr   rs   rt   r	  r   r   r   r   ru   r_   rv   rK   rK   rk   rL   rm    s   +rm  c                       sX   e Zd ZdZeZdZdZedZ	e
eeedddZeeeef d fd	d
Z  ZS )UserSessionDeleteViewa%  
    Terminate a user session.
    
    This view allows administrators to terminate specific user sessions
    for security purposes.
    
    Attributes:
        model (Model): The UserSession model
        template_name (str): Template for session termination confirmation
        permission_required (str): Required permission to access this view
        success_url (str): URL to redirect to after termination
    
    Methods:
        delete: Performs session termination
        get_context_data: Adds additional context for confirmation
    z-accounts/security/session_confirm_delete.htmlzaccounts.delete_usersessionzaccounts:session_listrN  c                 O   s|   |   | _| j}d|_t |_|jddgd t|jdd|jj	 d|j
 dt|d	 t|d
|jj	 d t| jS )a?  
        Perform session termination.
        
        Args:
            request (HttpRequest): The HTTP request object
            *args: Additional positional arguments
            **kwargs: Additional keyword arguments
            
        Returns:
            HttpResponse: Redirect response to success URL
        FrV   rR  rP  Zsession_terminatedzTerminated session for user z (IP: r&  r   zSession for user "z" has been terminated.)rM   r}   rV   r   r   rR  r,  r5   r?   rb   r   r4   r   r   r   r;  )rH   rC   rO  rA   sessionrK   rK   rL   rU    s     

zUserSessionDeleteView.deleterN   c                    s>   t  jf |}|d }|d|jj d|jj d |S )rV  r}   zTerminate Session - z#Confirm termination of session for rQ   )r^   r_   r`   r?   rb   )rH   rA   rj   rw  rk   rK   rL   r_     s    z&UserSessionDeleteView.get_context_data)rn   ro   rp   rq   r,   rr   rs   r   r   r;  r   r   r   rU  r   ru   r_   rv   rK   rK   rk   rL   rv  x  s   &rv  c                       s,   e Zd ZdZdZdd Z fddZ  ZS )UserActivateViewz*
    View to activate a user account.
    r  c                 O   s   t dd|d idS NrJ  rB  r   r   rH   rO  rA   rK   rK   rL   get_redirect_url  s    z!UserActivateView.get_redirect_urlc                    s   t t|d d}d|_|  t|jdd|jt|d|j t	||j
dd|d		 t|d
|j d t j|f||S )NrB  rA  Tr`   r(   zActivated user account: HTTP_USER_AGENTr  	r?   r   object_type	object_idobject_reprdetailsr   
user_agentrC   User z has been activated.r   r(   rV   r,  r5   r?   r=   ru   rb   r4   METArB   r   r   r^   rT  rk   rK   rL   rB     s     
zUserActivateView.getrn   ro   rp   rq   r   r|  rB   rv   rK   rK   rk   rL   rx    s   rx  c                       s,   e Zd ZdZdZdd Z fddZ  ZS )UserDeactivateViewz,
    View to deactivate a user account.
    r  c                 O   s   t dd|d idS ry  rz  r{  rK   rK   rL   r|    s    z#UserDeactivateView.get_redirect_urlc                    s   t t|d d}d|_|  t|jdd|jt|d|j t	||j
dd|d		 t|d
|j d t j|f||S )NrB  rA  Fr`   r(   rS  r}  r  r~  r  z has been deactivated.r  rT  rk   rK   rL   rB     s     
zUserDeactivateView.getr  rK   rK   rk   rL   r    s   r  c                       s,   e Zd ZdZdZdd Z fddZ  ZS )UserUnlockViewz(
    View to unlock a user account.
    r  c                 O   s   t dd|d idS ry  rz  r{  rK   rK   rL   r|  	  s    zUserUnlockView.get_redirect_urlc                    sz   t t|d d}|  t|jdd|jt|d|j t||j	
dd|d	 t|d	|j d
 t j
|f||S )NrB  rA  r`   r(   zUnlocked user account: r}  r  r~  r  z has been unlocked.)r   r(   r,  r5   r?   r=   ru   rb   r4   r  rB   r   r   r^   rT  rk   rK   rL   rB   	  s    
zUserUnlockView.getr  rK   rK   rk   rL   r  		  s   r  c                   @   s   e Zd ZdZdZdd ZdS )UserBulkActionsViewz/
    View to handle bulk actions on users.
    r  c                 O   s   |j d}|j d}|r |s4t|d tdS tjj|d}|dkrn|j	dd t
||  d	 nd|d
kr|j	dd t
||  d n8|dkr| }|  t
|| d nt|d tdS )Nr   user_idsz"Please select an action and users.r   )Zid__inactivateTrU   z users have been activated.
deactivateFz users have been deactivated.rU  z users have been deleted.zInvalid action selected.)POSTrB   getlistr   r4  r   r(   rE   rd   r`   r   rh   rU  )rH   rC   rO  rA   r   r  r   rh   rK   rK   rL   post.	  s$    zUserBulkActionsView.postN)rn   ro   rp   rq   r   r  rK   rK   rK   rL   r  (	  s   r  )crq   loggingr   r   typingr   r   r   django.contribr   django.contrib.auth.mixinsr   r	   django.core.exceptionsr
   django.core.paginatorr   	django.dbr   django.db.modelsr   r   r   django.httpr   r   r   r   django.shortcutsr   r   django.urlsr   r   django.utilsr   django.utils.decoratorsr   django.views.decorators.cacher   django.views.decorators.csrfr   django.views.decorators.httpr   r   django.views.genericr   r   r    r!   r"   r#   r$   r%   r&   modelsr(   r)   r*   r+   r,   r-   formsr.   r/   r0   r1   r2   permissionsr3   apps.common.utilsr4   apps.activities.helpersr5   	getLoggerrn   r7  r6   rw   r   r   r   r
  r  r=  rL  rW  rX  rY  r_  re  rk  rl  rm  rv  rx  r  r  r  rK   rK   rK   rL   <module>   sh   1, 
_s | \  .  _sgAPYrqU