
    si                     :   d Z ddl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 dd
lmZ ddlmZ ddlmZ ddlmZ edefd       Z eede       dedefdZd Z G d dej@                        Z! G d d      Z" ejF                  e!d       y)aU  
models.py
=========

This module defines the abstract base model `HorillaModel` for the WorksolMS project.
The `HorillaModel` provides common fields and functionalities for other models within
the application, such as tracking creation and modification timestamps and user
information, audit logging, and active/inactive status management.
    N)uuid4)AuditlogHistoryField)auditlog)User)ValidationError)models)	FieldFile)reverse)slugify)gettext)_thread_localsselfc                     	 | j                          | j                  j	                  | j
                        S # t        $ r}t        d      cY d}~S d}~ww xY w)z'
    Custom url attribute/property
    404N)_require_file	Exceptionr
   storageurlname)r   es     2/var/www/python-projects/worksol/horilla/models.pyr   r      sJ    
 <<DII&&  u~s   7 	A 
A
AAr   valuereturnc                     t        | t              syg d}t        j                  dj	                  |      t        j
                  t        j                  z        }t        |j                  |             S )zNDetect common XSS attempts (scripts, event handlers, js URLs, active content).F)z#<\s*script.*?>.*?<\s*/\s*script\s*>zjavascript\s*:z	on\w+\s*=z0<\s*(embed|object|iframe|svg|math|link|meta).*?>zcon\w+\s*=\s*['\"]?\s*(eval|setTimeout|setInterval|new\s+Function|XMLHttpRequest|fetch|\$\s*\()[^>]*|)	
isinstancestrrecompilejoin
IGNORECASEDOTALLboolsearch)r   xss_patternscombineds      r   has_xssr'   *   sR    eS!L zz#((<0"--"))2KLH&''    c                    j                  d      d   }dj                  j                  d      dd       xs d}t        |       dt               j                  dd  d| }t        fd| j                  j                         D        d      }| j                  j                  }| j                  j                  }|r| d| d| d| S | d| d| S )	z
    Generates a unique file path for uploads in the format:
    app_label/model_name/field_name/originalfilename-uuid.ext
    .Nfile-   c              3   ^   K   | ]$  \  }}t        |d       r|j                  k(  r| & yw)r   N)hasattrr   ).0kvfilenames      r   	<genexpr>zupload_path.<locals>.<genexpr>F   s2      	
1q&!aff&8 	
s   *-/)splitr    r   r   hexnext__dict__items_meta	app_label
model_name)instancer4   ext	base_nameunique_name
field_namer=   r>   s    `      r   upload_pathrD   ;   s    
 ..
b
!C,Sb12<fIY'(%'++bq/):!C5AK 	
 ))//1	

 	J ((I**JAj\:,a}EE[*Q{m44r(   c            
           e Zd ZdZ ej
                  ddd ed            Z ej                  e	ej                  ddd ed            Z ej                  e	ej                  ddd ed      d	
      Z e       Z ej                         Z ej"                  d ed            Z G d d      Z fdZddZd Zd Zed        Zed        Zed        Z xZS )HorillaModelz
    An abstract base model that includes common fields and functionalities
    for models within the Worksol application.
    Tz
Created At)auto_now_addnullblankverbose_nameFz
Created By)	on_deleterH   rI   editablerJ   zModified Byz%(class)s_modified_by)rK   rH   rI   rL   rJ   related_namez	Is Active)defaultrJ   c                       e Zd ZdZdZy)HorillaModel.Metaz-
        Meta class for HorillaModel
        TN)__name__
__module____qualname____doc__abstract r(   r   MetarP   x   s    	 r(   rW   c                    t        t        dd      }|r|j                  }t        | d      rrt        | j                  j                  d      d      rM| j                  j                  d      j                  t        k(  r!|r| j                  s|j                  r|| _
        |r|j                  j                  s|| _        t        t        | >  |i | y)z
        Override the save method to automatically set the created_by and
        modified_by fields based on the current request user.
        requestN
created_byrelated_model)getattrr   userr0   r<   	get_fieldr[   r   pkis_authenticatedrZ   is_anonymousmodified_bysuperrF   save)r   argskwargsrY   r]   	__class__s        r   rd   zHorillaModel.save   s     .)T:<<D l+DJJ00>PJJ((6DDL477,,*.w||88#' lD&77r(   c                    i }t        |xs g       j                  t        | dg             }| j                  j	                         D ]z  }t        |t        j                  t        j                  f      s.|j                  |vs=t        | |j                  d       }|sWt        |      sct        d      ||j                  <   | |rt        |      y )Nxss_exempt_fieldszPotential XSS content detected.)setunionr\   r<   
get_fieldsr   r   	CharField	TextFieldr   r'   r   )r   excludeerrorstotal_excludefieldr   s         r   clean_fieldszHorillaModel.clean_fields   s     GMr*00?RTV1WXZZ**, 		E56#3#3V5E5E"FGJJm3ejj$7WU^)89*F5::&		 !&)) r(   c                 .    | j                   j                  S N)r<   rJ   r   s    r   get_verbose_namezHorillaModel.get_verbose_name   s    zz&&&r(   c                 .    | j                   j                  S ru   )r<   verbose_name_pluralrv   s    r   get_verbose_name_pluralz$HorillaModel.get_verbose_name_plural   s    zz---r(   c                     	 | j                   j                  |      j                         }|S # t        $ r
}Y d}~yd}~ww xY w)z9
        Find an object of this class by its ID.
        )idN)objectsfilterfirstr   )cls	object_idobjr   s       r   findzHorillaModel.find   s?    
	++$$	$288:CJ 		s   +. 	AAc                 p    | j                  |      }|r#|j                   |_        |j                          yy)zI
        Toggle the is_active status of an object of this class.
        N)r   	is_activerd   )r   r   r   s      r   activate_deactivatez HorillaModel.activate_deactivate   s1    
 hhy! #-CMHHJ r(   c                     |j                  d      }| }|dd D ]3  }|j                  j                  |      }|j                  j                  }5  |       j                  j                  |d         }|j
                  S )z
        Traverse related fields to get verbose_name using Django's _meta API.
        Example: "employee_id__employee_work_info__reporting_manager_id"
        __Nr+   )r7   r<   r^   remote_fieldmodelrJ   )r   
field_pathpartsinstance_modelpartrr   final_fields          r   get_verbose_name_related_fieldz+HorillaModel.get_verbose_name_related_field   s       &#2J 	6D"((2248E"//55N	6 %&,,66uRyA'''r(   ru   )rQ   rR   rS   rT   r   DateTimeField_
created_at
ForeignKeyr   SET_NULLrZ   rb   r   horilla_historyManagerr}   BooleanFieldr   rW   rd   rs   rw   rz   classmethodr   r   r   __classcell__)rg   s   @r   rF   rF   V   s   
 &%%|_	J #""//|_J $&##//}%,K +,OfnnG###Dq~NI 84*('. 	 	   ( (r(   rF   c                       e Zd ZdZy)NoPermissionModelTN)rQ   rR   rS   _no_permission_modelrV   r(   r   r   r      s    r(   r   T)serialize_data)$rT   r   uuidr   auditlog.modelsr   auditlog.registryr   django.contrib.auth.modelsr   django.core.exceptionsr   	django.dbr   django.db.models.fields.filesr	   django.urlsr
   django.utils.textr   django.utils.translationr   r   horilla.horilla_middlewaresr   propertyr   setattrr   r#   r'   rD   ModelrF   r   registerrV   r(   r   <module>r      s    
  0 & + 2  3  % 1 6 
'i ' 
' 	5# (3 (4 ("56A(6<< A(H      ,t 4r(   