a
    Dg/                     @   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 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 G dd dejZG dd dejZ G dd dej!Z"G dd de Z#G dd de"Z$dS )z
Base model definitions for audit logging. These may be subclassed to accommodate specific models
such as Page, but the definitions here should remain generic and not depend on the base
wagtail.models module or specific models such as Page.
    )defaultdict)settings)get_user_model)
Permission)ContentType)ValidationError)DjangoJSONEncoder)models)timezone)cached_property)gettext_lazy)registry)get_deleted_user_display_namec                   @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )LogEntryQuerySetc                 C   s   t |  jddd S )zZ
        Returns a set of actions used by at least one log entry in this QuerySet
        actionTZflatsetorder_byvalues_listdistinctself r   W/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/wagtail/models/audit_log.pyget_actions   s    zLogEntryQuerySet.get_actionsc                 C   s   t |  jddd S )zm
        Returns a set of user IDs of users who have created at least one log entry in this QuerySet
        user_idTr   r   r   r   r   r   get_user_ids   s    zLogEntryQuerySet.get_user_idsc                 C   s    t  }|jj|  d|jS )z
        Returns a QuerySet of Users who have created at least one log entry in this QuerySet.

        The returned queryset is ordered by the username.
        )Zpk__in)r   objectsfilterr   r   ZUSERNAME_FIELD)r   ZUserr   r   r   	get_users%   s    zLogEntryQuerySet.get_usersc                 C   s   t |  jddd S )z\
        Returns a set of IDs of content types with logged actions in this QuerySet
        content_type_idTr   r   r   r   r   r   get_content_type_ids0   s    z%LogEntryQuerySet.get_content_type_idsc                 C   s   | j |jdS )N)r!   )r   id)r   content_typer   r   r   filter_on_content_type6   s    z'LogEntryQuerySet.filter_on_content_typec              	   c   s   t | }tt }|D ]}||j |j qi }| D ]|\}}ztj|}|	 }W n tj
yp   d }Y n0 |r|j|}	ndd |D }	|	 D ]\}
}|||t|
f< qq8|D ]$}|jt|jf}|||fV  qd S )Nc                 S   s   i | ]
}|d qS Nr   ).0	object_idr   r   r   
<dictcomp>U       z3LogEntryQuerySet.with_instances.<locals>.<dictcomp>)listr   r!   appendr(   itemsr   r   
get_for_idmodel_classZDoesNotExistZin_bulkstrget)r   Zlog_entriesZids_by_content_typeZ	log_entryZinstances_by_idr!   Z
object_idsr$   modelZmodel_instancesr(   instanceZ
lookup_keyr   r   r   with_instances<   s&    
zLogEntryQuerySet.with_instancesN)	__name__
__module____qualname__r   r   r    r"   r%   r4   r   r   r   r   r      s   r   c                   @   sD   e 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S )BaseLogEntryManagerc                 C   s   t | j| jdS )N)Zusing)r   r2   _dbr   r   r   r   get_queryset`   s    z BaseLogEntryManager.get_querysetc                 C   s   t |S r&   )r0   r   r3   r   r   r   get_instance_titlec   s    z&BaseLogEntryManager.get_instance_titlec                 K   s~   |j du rtd|f |ddp&i }|dd}|sB| |}|dt }| jjjf t	jj
|dd||||d|S )	aA  
        :param instance: The model instance we are logging an action for
        :param action: The action. Should be namespaced to app (e.g. wagtail.create, wagtail.workflow.start)
        :param kwargs: Addition fields to for the model deriving from BaseLogEntry
            - user: The user performing the action
            - uuid: uuid shared between log entries from the same user action
            - title: the instance title
            - data: any additional metadata
            - content_changed, deleted - Boolean flags
        :return: The new log entry
        Nz?Attempted to log an action for object %r with empty primary keydatatitle	timestampFZfor_concrete_model)r$   labelr   r?   r=   )pk
ValueErrorpopr<   r
   nowr2   r   creater   get_for_model)r   r3   r   kwargsr=   r>   r?   r   r   r   
log_actionf   s,    


zBaseLogEntryManager.log_actionc                 C   s   |j r|  S t|ds| jddd }tjj|d}t }|D ]B}|j	|v rRqBt
j|j	}||j d|j rB||j	 qB||_| j|jdS )N_allowed_content_type_idsr!   Tr   )Zcontent_type_id__in.)Zis_superuserallhasattrr   r   r   r   r   r   r!   r   r.   Zhas_permZ	app_labelcodenameaddrJ   )r   userZused_content_type_idsZpermissionsZallowed_content_type_idsZ
permissionr$   r   r   r   viewable_by_user   s(    


z$BaseLogEntryManager.viewable_by_userc                 C   s,   t |tjs|  S tj|}| j|dS )N)r$   )
issubclassr	   Modelnoner   r   rG   r   )r   r2   ctr   r   r   rG      s    z!BaseLogEntryManager.get_for_modelc                 C   s   | j |dS )N)rP   )r   )r   r   r   r   r   get_for_user   s    z BaseLogEntryManager.get_for_userc                 C   s   t dS )zo
        Return a queryset of log entries from this log model that relate to the given object instance
        NNotImplementedErrorr;   r   r   r   for_instance   s    z BaseLogEntryManager.for_instanceN)
r5   r6   r7   r:   r<   rI   rQ   rG   rV   rY   r   r   r   r   r8   _   s   #	r8   c                       s<  e Zd ZejeejedddddZe	 Z
ejddddZejdeedZejeddd	Zejddd
ddZejejddejd
ddZejdddejd
ddZejd
ddZejd
dZe ZdZG dd dZ  fddZ!dd Z"dd Z#e$dd Z%e$dd Z&dd Z'e$dd  Z(e$d!d" Z)e$d#d$ Z*  Z+S )%BaseLogEntryzcontent typeT+)verbose_nameblanknullrelated_name   
max_lengthr]   db_index)r]   defaultencoderztimestamp (UTC))r\   rc   FzTLog entries that happened as part of the same user action are assigned the same UUID)r]   r^   editable	help_text)r^   r]   Z	on_deleteZdb_constraintr_   zwagtailcore.Revision)rd   rc   )rd   c                   @   s&   e Zd ZdZedZedZdgZdS )zBaseLogEntry.MetaTz	log entryzlog entries
-timestampN)r5   r6   r7   Zabstract_r\   verbose_name_pluralorderingr   r   r   r   Meta   s   rl   c                    s   |    t j|i |S r&   )Z
full_cleansupersave)r   argsrH   	__class__r   r   rn      s    zBaseLogEntry.savec                 C   s*   t | js&tdtdd| ji id S )Nr   z9The log action '%(action_name)s' has not been registered.action_name)log_action_registryZaction_existsr   r   ri   r   r   r   r   clean   s    zBaseLogEntry.cleanc                 C   s   d| j | j|  f S )NzLogEntry %d: '%s' on '%s')rB   r   object_verbose_namer   r   r   r   __str__   s
    zBaseLogEntry.__str__c                 C   s^   | j rR| j}|du rt| j S z|  }W n tyD   d}Y n0 |pP| S tdS dS )z
        Returns the display name of the associated user;
        get_full_name if available and non-empty, otherwise get_username.
        Defaults to 'system' when none is provided
        N system)r   rP   r   Zget_full_namestripAttributeErrorZget_usernameri   )r   rP   Z	full_namer   r   r   user_display_name  s    

zBaseLogEntry.user_display_namec                 C   s"   | j  }|d u r| jS |jjjS r&   )r$   r/   r!   Z_metar\   r>   )r   r/   r   r   r   ru     s    
z BaseLogEntry.object_verbose_namec                 C   s   t d S r&   rW   r   r   r   r   r(   $  s    zBaseLogEntry.object_idc                 C   s
   t | S r&   )rs   Zget_formatterr   r   r   r   	formatter'  s    zBaseLogEntry.formatterc                 C   s(   | j r| j | S tdd| ji S d S )NzUnknown %(action)sr   )r|   Zformat_messageri   r   r   r   r   r   message+  s    zBaseLogEntry.messagec                 C   s   | j r| j | S dS d S )Nrw   )r|   Zformat_commentr   r   r   r   comment2  s    zBaseLogEntry.comment),r5   r6   r7   r	   Z
ForeignKeyr   ZSET_NULLri   r$   Z	TextFieldrA   	CharFieldr   Z	JSONFielddictr   r=   ZDateTimeFieldr?   Z	UUIDFielduuidr   ZAUTH_USER_MODELZ
DO_NOTHINGrP   revisionZBooleanFieldZcontent_changedZdeletedr8   r   Zwagtail_reference_index_ignorerl   rn   rt   rv   r   r{   ru   r(   r|   r}   r~   __classcell__r   r   rp   r   rZ      sj   





rZ   c                       s$   e Zd Z fddZdd Z  ZS )ModelLogEntryManagerc                    s(   |j t|jd t j||fi |S )N)r(   )updater0   rB   rm   rI   )r   r3   r   rH   rp   r   r   rI   ;  s    zModelLogEntryManager.log_actionc                 C   s    | j tjj|ddt|jdS )NFr@   )r$   r(   )r   r   r   rG   r0   rB   r;   r   r   r   rY   ?  s    z!ModelLogEntryManager.for_instance)r5   r6   r7   rI   rY   r   r   r   rp   r   r   :  s   r   c                   @   s<   e Zd ZdZejddddZe ZG dd dZ	dd	 Z
d
S )ModelLogEntryz1
    Simple logger for generic Django models
    r`   FTra   c                   @   s$   e Zd ZddgZedZedZdS )zModelLogEntry.Metarh   z-idzmodel log entryzmodel log entriesN)r5   r6   r7   rk   ri   r\   rj   r   r   r   r   rl   Q  s   rl   c                 C   s   d| j | j|  | jf S )Nz)ModelLogEntry %d: '%s' on '%s' with id %s)rB   r   ru   r(   r   r   r   r   rv   V  s    zModelLogEntry.__str__N)r5   r6   r7   __doc__r	   r   r(   r   r   rl   rv   r   r   r   r   r   H  s
   r   N)%r   collectionsr   Zdjango.confr   Zdjango.contrib.authr   Zdjango.contrib.auth.modelsr   Z"django.contrib.contenttypes.modelsr   Zdjango.core.exceptionsr   Zdjango.core.serializers.jsonr   Z	django.dbr	   Zdjango.utilsr
   Zdjango.utils.functionalr   Zdjango.utils.translationr   ri   Zwagtail.log_actionsr   rs   Zwagtail.users.utilsr   ZQuerySetr   Managerr8   rS   rZ   r   r   r   r   r   r   <module>   s$   G\