o
    ӷ6i                     @   s   d dl 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 d dlmZ i Ze Z	 G d	d
 d
ejZG dd dZdd ZdddZdS )    N)	b64decode	b64encode)checks)models)force_bytes)gettext_lazy)SignatureExpired)FernetBytesc                       s   e Zd ZdZedZddgZdZ fddZdd	 Z	d
d Z
 fddZdd Z fddZ fddZ fddZd fdd	Zdd Zdd Zdd Z  ZS ) PickledFieldz-
    A field for storing pickled objects
    zPickled dataN    )exactinisnullc                    s   d|d< t  j|i | d S )NFeditable)super__init__selfargskwargs	__class__ _/var/www/hoanhtaovolam_webdjango/env/lib/python3.10/site-packages/django_cryptography/fields.pyr      s   zPickledField.__init__c                 C   
   t |S N)pickledumpsr   valuer   r   r   _dump      
zPickledField._dumpc                 C   r   r   )r   loadsr   r   r   r   _load"   r!   zPickledField._loadc                    s$   t   \}}}}|d= ||||fS )Nr   )r   deconstructr   namepathr   r   r   r   r   r$   %   s   zPickledField.deconstructc                 C      dS NBinaryFieldr   r   r   r   r   get_internal_type*      zPickledField.get_internal_typec                    s   t   }|dkrdS |S )N r   )r   get_default)r   defaultr   r   r   r/   -   s   
zPickledField.get_defaultc                       || j vrd S t |S r   supported_lookupsr   
get_lookupr   lookup_namer   r   r   r4   3      
zPickledField.get_lookupc                    r1   r   r3   r   get_transformr5   r   r   r   r9   8   r7   zPickledField.get_transformFc                    s.   t  |||}|d ur|j| |S |S r   )r   get_db_prep_valueDatabaseBinaryr    r   r   
connectionpreparedr   r   r   r:   =   s   zPickledField.get_db_prep_valuec                 O      |d ur|  t|S |S r   r#   r   r   r   r   r   r   r   r   from_db_valueC      zPickledField.from_db_valuec                 C   s   |  |}t| |dS )z$Pickled data is serialized as base64ascii)value_from_objectr   r    decode)r   objr   r   r   r   value_to_stringH   s   
zPickledField.value_to_stringc                 C   s    t |tr| tt|S |S r   )
isinstancestrr#   r   r   r   r   r   r   	to_pythonM   s   
zPickledField.to_pythonF)__name__
__module____qualname____doc___descriptionempty_valuesr3   r   r    r#   r$   r,   r/   r4   r9   r:   rC   rI   rL   __classcell__r   r   r   r   r
      s"    r
   c                       s   e Zd ZdZdZ fddZe fddZdd Zd	d
 Z	 fddZ
 fddZ fddZ fddZ fddZdd ZdddZejjZdd Z  ZS )EncryptedMixina  
    A field mixin storing encrypted data

    :param bytes key: This is an optional argument.

        Allows for specifying an instance specific encryption key.
    :param int ttl: This is an optional argument.

        The amount of time in seconds that a value can be stored for. If the
        time to live of the data has passed, it will become unreadable.
        The expired value will return an :class:`Expired` object.
    )r   c                    s>   | dd | _| dd | _t| j| _t j|i | d S )Nkeyttl)poprW   rX   r	   _fernetr   r   r   r   r   r   r   d   s   zEncryptedMixin.__init__c                    s   t dt j S )NzEncrypted %s)rR   r   rS   r+   r   r   r   rS   k   s   zEncryptedMixin.descriptionc                 C   s   | j t|S r   )rZ   encryptr   r   r   r   r   r   r    o   s   zEncryptedMixin._dumpc                 C   s0   zt | j|| jW S  ty   t Y S w r   )r   r"   rZ   decryptrX   r   Expiredr   r   r   r   r#   r   s
   zEncryptedMixin._loadc                    s:   t  jdi |}t| dd r|tjdd | dd |S )Nremote_fieldz3Base field for encrypted cannot be a related field.zencrypted.E002)hintrH   idr   )r   checkgetattrappendr   Error)r   r   errorsr   r   r   ra   x   s   zEncryptedMixin.checkc                    sP   t   \}}}}| jjtdks t| j|i || j| j	S | j|i |S )N   )
r   r$   r   __mro__indexrV   r[   
base_classrW   rX   r%   r   r   r   clone   s   zEncryptedMixin.clonec                    sl   t   \}}}}| jjtdks0tj dtj }| j	|i |g}i }| j
d ur0| j
|d< ||||fS )Nrf   .rX   )r   r$   r   rg   rh   rV   r[   rO   rN   ri   rX   r%   r   r   r   r$      s   

zEncryptedMixin.deconstructc                    r1   r   r2   r5   r   r   r   r4      r7   zEncryptedMixin.get_lookupc                    r1   r   r8   r5   r   r   r   r9      r7   zEncryptedMixin.get_transformc                 C   r(   r)   r   r+   r   r   r   r,      r-   z EncryptedMixin.get_internal_typeFc                 C   s0   t j| |||}|d ur|j| |S |S r   )r   Fieldr:   r;   r<   r    r=   r   r   r   r:      s   z EncryptedMixin.get_db_prep_valuec                 O   r@   r   rA   rB   r   r   r   rC      rD   zEncryptedMixin.from_db_valuerM   )rN   rO   rP   rQ   r3   r   propertyrS   r    r#   ra   rj   r$   r4   r9   r,   r:   r   rl   get_db_prep_saverC   rU   r   r   r   r   rV   T   s"    
rV   c                 C   sB   t | tjrJ d| j }| tvrt|t| fd| it| < t|  S )a  
    A get or create method for encrypted fields, we cache the field in
    the module to avoid recreation. This also allows us to always return
    the same class reference for a field.

    :type base_class: models.Field[T]
    :rtype: models.Field[EncryptedMixin, T]
    	Encryptedri   )rJ   r   rl   rN   FIELD_CACHEtyperV   )ri   
field_namer   r   r   get_encrypted_field   s   	
rs   c                 C   sb   t | tjs|du sJ |du sJ t| S |  \}}}}|||d tt| |i |S )a  
    A decorator for creating encrypted model fields.

    :type base_field: models.Field[T]
    :param bytes key: This is an optional argument.

        Allows for specifying an instance specific encryption key.
    :param int ttl: This is an optional argument.

        The amount of time in seconds that a value can be stored for. If the
        time to live of the data has passed, it will become unreadable.
        The expired value will return an :class:`Expired` object.
    :rtype: models.Field[EncryptedMixin, T]
    N)rW   rX   )rJ   r   rl   rs   r$   updaterq   )
base_fieldrW   rX   r&   r'   r   r   r   r   r   r[      s   r[   )NN)r   base64r   r   django.corer   	django.dbr   django.utils.encodingr   django.utils.translationr   rR    django_cryptography.core.signingr    django_cryptography.utils.cryptor	   rp   objectr]   rl   r
   rV   rs   r[   r   r   r   r   <module>   s    B^