o
    'h=.                     @   s   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 d dlmZmZ d d	lmZ d
dlmZmZmZ d dlZeeZG dd dZG dd dZG dd dZG dd dZdS )    )settings)logout)timezone)	timedelta)redirect)messages)reverse)Http404HttpResponseForbidden)PermissionDenied   )has_financial_accesscan_assign_ticketscan_delete_customersNc                   @       e Zd ZdZdd Zdd ZdS )CustomerOnlyMiddlewarez6Middleware to restrict certain views to customers onlyc                 C   
   || _ d S Nget_responseselfr    r   3/var/www/html/optinet_system/accounts/middleware.py__init__      
zCustomerOnlyMiddleware.__init__c                 C      |  |}|S r   r   r   requestresponser   r   r   __call__      
zCustomerOnlyMiddleware.__call__N__name__
__module____qualname____doc__r   r    r   r   r   r   r          r   c                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )DepartmentPermissionMiddlewarez2Middleware to enforce department-based permissionsc                 C   s0   || _ g dg dg dddgg dd| _d S )N)	/billing/z
/payments/z/customers/invoices/z/customers/payments/z/customers/balance//expenditure/)z/hr/employees/z/hr/payslip/z/hr/deduction/z
/hr/bonus/z/hr/department/z/hr/generate-payslips/)z/settings/system/z/settings/dashboard//admin/z/tickets/assign/z/tickets/schedule/)z/customers/add/z/customers/create/z/customers/.*/edit/z/customers/.*/delete/)	financialhrr   ticket_assignmentcustomer_management)r   protected_urlsr   r   r   r   r      s   z'DepartmentPermissionMiddleware.__init__c                 C   r   r   r   r   r   r   r   r    4   r!   z'DepartmentPermissionMiddleware.__call__c              
   C   s^   z|j jr| |}|r|W S W dS  ty. } ztdt|  W Y d}~dS d}~ww )zProcess view before it's calledNzMiddleware process_view error: )useris_authenticated_check_url_permissions	Exceptionloggererrorstr)r   r   	view_func	view_argsview_kwargsresulter   r   r   process_view8   s   
z+DepartmentPermissionMiddleware.process_viewc              
   C   s   z4g d}|j }|D ]}||r W dS q
|jjrW dS t|jdr/| |j|s2tdW S W dS W dS  tyQ } zt	dt
|  W Y d}~dS d}~ww )z6Check if user has permission to access the current URL)r+   z/accounts/login/z/accounts/logout/z/accounts/employee-login/z/accounts/customer-login//static//media/z/api/Nemployee_profilez.You don't have permission to access this page.zPermission check error: )	path_info
startswithr1   is_superuserhasattr_has_url_permissionr
   r4   r5   r6   r7   )r   r   	skip_urlscurrent_pathskip_urlr<   r   r   r   r3   H   s&   

z5DepartmentPermissionMiddleware._check_url_permissionsc                    sr  ddl m} ||}dd | jd D }t fdd|D r+d|vr+d	|vr+td
d v rCd|vrCd|vrCd|vrCd	|vrCtdt fdd| jd D r]d|vr]d|vr]tdt fdd| jd D rr|jsrtdt fdd| jd D rd|vrtdt fdd| jd D r drd|vrtdd  v sd! v rd"|vrd#|vrtd$d%S )&z5Helper to check permissions for a given user and pathr   )get_user_permissionsc                 S   s   g | ]	}| d s|qS )r*   )rB   .0urlr   r   r   
<listcomp>t   s    zFDepartmentPermissionMiddleware._has_url_permission.<locals>.<listcomp>r,   c                 3       | ]}| v V  qd S r   r   rJ   pathr   r   	<genexpr>u       zEDepartmentPermissionMiddleware._has_url_permission.<locals>.<genexpr>view_billingmanage_billingzZAccess to financial modules requires billing permissions. Contact your department manager.r*   view_expenseadd_expensezIAccess to expense management requires appropriate department permissions.c                 3   rN   r   r   rJ   rO   r   r   rQ      rR   r-   view_employeesmanage_employeesz\Access to HR modules requires employee management permissions. Contact system administrator.c                 3   rN   r   r   rJ   rO   r   r   rQ      rR   r   z6System settings are restricted to administrators only.c                 3   rN   r   r   rJ   rO   r   r   rQ      rR   r.   assign_ticketsz?Ticket assignment requires technician or management privileges.c                 3   rN   r   r   rJ   rO   r   r   rQ      rR   r/   z/delete/delete_customersz/Customer deletion requires management approval.z/add/z/create/add_customersadd_customerz=Adding customers requires appropriate department permissions.T)permissionsrI   r0   anyr   rC   endswith)r   r1   rP   rI   user_permissionsfinancial_urlsr   rO   r   rE   m   s4   z2DepartmentPermissionMiddleware._has_url_permissionc                    8   |j  t fdd| jD rt|jstddS dS )z*Check if user has access to financial URLsc                 3   rN   r   r   rJ   rO   r   r   rQ      rR   zIDepartmentPermissionMiddleware._check_financial_access.<locals>.<genexpr>zFinancial access requiredN)rP   r^   ra   r   r1   r   r   r   r   rO   r   _check_financial_access      
z6DepartmentPermissionMiddleware._check_financial_accessc                    rb   )z Check if user can assign ticketsc                 3   rN   r   r   rJ   rO   r   r   rQ      rR   zQDepartmentPermissionMiddleware._check_ticket_assignment_access.<locals>.<genexpr>z!Ticket assignment access requiredN)rP   r^   ticket_assignment_urlsr   r1   r   rc   r   rO   r   _check_ticket_assignment_access   re   z>DepartmentPermissionMiddleware._check_ticket_assignment_accessc                    sF   |j  t fdd| jD r|jdv rt|js!tddS dS dS )z"Check if user can delete customersc                 3   rN   r   r   rJ   rO   r   r   rQ      rR   zODepartmentPermissionMiddleware._check_customer_delete_access.<locals>.<genexpr>)POSTDELETEz!Customer deletion access requiredN)rP   r^   customer_delete_urlsmethodr   r1   r   rc   r   rO   r   _check_customer_delete_access   s   "
z<DepartmentPermissionMiddleware._check_customer_delete_accessN)r#   r$   r%   r&   r   r    r=   r3   rE   rd   rg   rl   r   r   r   r   r(      s    %+r(   c                   @   r   )SessionTimeoutMiddlewarezHMiddleware to handle different session timeouts for different user typesc                 C   r   r   r   r   r   r   r   r      r   z!SessionTimeoutMiddleware.__init__c                 C   s  |j jrt|j dr|j jrttdd}n&t|j dr&|j jr&ttdd}n|j js.|j jr5ttdd}nttd	d
}|j	
ds|j	
ds|jd}|rt  | }||krt|j drk|j jrkd|jd< nd|jd< t| t|d | |S t  |jd< | |}|S )Nr@   EMPLOYEE_SESSION_TIMEOUTip  customer_profileCUSTOMER_SESSION_TIMEOUTi   ADMIN_SESSION_TIMEOUTi@8  SESSION_COOKIE_AGEi  z/logoutz/accounts/logoutlast_activitycustomerlogout_user_typeemployeez.Your session has expired. Please log in again.)r1   r2   rD   r@   getattrr   ro   rC   is_staffrP   rB   sessiongetr   now	timestampr   r   infor   )r   r   timeoutrs   elapsedr   r   r   r   r       s,   


z!SessionTimeoutMiddleware.__call__Nr"   r   r   r   r   rm      r'   rm   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )ActivityLoggingMiddlewarez?Middleware to log user activity for security and audit purposesc                 C   s   || _ g d| _d S )N)r+   z
/accounts/z/customers/r)   z/hr/z
/settings/)r   sensitive_pathsr   r   r   r   r      s   z"ActivityLoggingMiddleware.__init__c                 C   s*   |j jr| |r| | | |}|S r   )r1   r2   
should_loglog_activityr   r   r   r   r   r       s   

z"ActivityLoggingMiddleware.__call__c                    sH   t  fdd| jD rdS  jdv rdS t  fdddD r"dS dS )z*Determine if this request should be loggedc                 3       | ]	} j |V  qd S r   rP   rB   rK   rP   r   r   r   rQ          z7ActivityLoggingMiddleware.should_log.<locals>.<genexpr>T)rh   PUTri   c                 3   r   r   r   r   r   r   r   rQ      r   )r>   r?   z/api/heartbeat/F)r^   r   rk   rc   r   r   r   r      s   
z$ActivityLoggingMiddleware.should_logc              
   C   sr   z.t jj|j|j d|j | ||jdddd |j|jt	|j
|jjdd W dS  ty8   Y dS w )zLog user activity HTTP_USER_AGENT Ni  )rk   rP   query_paramssession_key)r1   action
ip_address
user_agentadditional_data)UserActivityLogobjectscreater1   rk   rP   get_client_ipMETArz   dictGETry   r   r4   rc   r   r   r   r      s   z&ActivityLoggingMiddleware.log_activityc                 C   s2   |j d}|r|dd }|S |j d}|S )NHTTP_X_FORWARDED_FOR,r   REMOTE_ADDR)r   rz   split)r   r   x_forwarded_foripr   r   r   r     s   z'ActivityLoggingMiddleware.get_client_ipN)	r#   r$   r%   r&   r   r    r   r   r   r   r   r   r   r      s    r   )django.confr   django.contrib.authr   django.utilsr   datetimer   django.shortcutsr   django.contribr   django.urlsr   django.httpr	   r
   django.core.exceptionsr   r]   r   r   r   logging	getLoggerr#   r5   r   r(   rm   r   r   r   r   r   <module>   s"    

 )