o
    PDi}0                     @   s   d dl Z d dlZd dlZd dlZd dlZd dl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 d dlmZ edZg d	Zd
ZedgZdgZdgZG dd dejZdd ZG dd dZG dd dZdS )    N)UUID)RequestDataTooBig)Resolver404resolve)models)DataCollector)SilkyConfigzsilk.model_factory)zapplication/jsonzapplication/x-javascriptztext/javascriptztext/x-javascriptztext/x-jsonzmultipart/form-dataz!application/x-www-form-urlencodedz	text/htmlztext/cssc                   @   s   e Zd Zdd ZdS )DefaultEncoderc                 C   s   t |tr	t|S d S N)
isinstancer   str)selfo r   K/var/www/Datamplify/venv/lib/python3.10/site-packages/silk/model_factory.pydefault   s   
zDefaultEncoder.defaultN)__name__
__module____qualname__r   r   r   r   r   r	      s    r	   c              	   C   s~   d}|   r;| d}|d } z|d   }|d\}}|dkr(d}W | |fS W | |fS  ttfy:   Y | |fS w | |fS )zRbest efforts on pulling out the content type and encoding from content-type headerN;r      =charset)stripsplit
IndexError
ValueError)content_typechar_setspltraw_char_setkeyr   r   r   _parse_content_type$   s"   
r"   c                       sd   e Zd ZdZdZ f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d Z  ZS )RequestModelFactoryz2Produce Request models from Django request objectsz********************c                    s   t    || _d S r
   )super__init__request)r   r&   	__class__r   r   r%   9   s   

zRequestModelFactory.__init__c                 C   s   | j jdd}t|S )Ncontent-type )r&   headersgetr"   )r   r   r   r   r   r   =   s   z RequestModelFactory.content_typec                 C   s|   t ttjt j}|d t jr|d i }| jj	
 D ]\}}| }||v r/tj}|||< q tj|tt jdS )zu
        From Django docs (https://docs.djangoproject.com/en/2.0/ref/request-response/#httprequest-objects):
        authorizationcookie)clsensure_ascii)setmapr   lowerr   SILKY_SENSITIVE_KEYSaddSILKY_HIDE_COOKIESr&   r+   itemsr#   CLEANSED_SUBSTITUTEjsondumpsr	   SILKY_JSON_ENSURE_ASCII)r   sensitive_headersr+   kvr   r   r   encoded_headersA   s   


z#RequestModelFactory.encoded_headersc                    s   t  j}d|  fddzt|}W nQ tyh } zE rOtd  dtjtj	B }zt
|dtj d|}W n tyN   tt|  Y nw W Y d}~|S W Y d}~|S W Y d}~|S d}~ww tj|t  jd	}|S )
zU
        Mask credentials of potentially sensitive info before saving to db.
        |c                    s   t  t j}t| tr*|  D ]} r||rtj| |< q| | | |< q| S t| t	r@t
| D ]
\}}|| |< q3| S  rL|t| rLtjS | S r
   )recompileIr   dictkeyssearchr#   r8   list	enumerater   )objpatternr!   indexitem
key_stringreplace_pattern_valuesr   r   rO   Z   s   

zERequestModelFactory._mask_credentials.<locals>.replace_pattern_valuesz((z)[^=]*)=(.*?)(&|$)z\1=z\4Nr0   )r   r4   joinr9   loads	ExceptionrA   rB   MrC   subr#   r8   Loggerdebugr   r:   r;   )r   bodysensitive_keys	json_bodyerJ   r   rM   r   _mask_credentialsS   s.   

	

z%RequestModelFactory._mask_credentialsc                 C   sz   d}|t v r| jj}tjt|ddt jd}|S |tv r;ztjt	|ddt jd}W |S  t
y:   |}Y |S w |S )z
        Encode body as JSON if possible so can be used as a dictionary in generation
        of curl/django test client code
        r*   T   	sort_keysindentr0   )content_type_formr&   POSTr9   r:   rD   r   r;   content_types_jsonrR   rS   )r   raw_bodyr   rX   r   r   r   _bodyx   s$   zRequestModelFactory._bodyc                 C   s  |   \}}|tkrd}d}||fS z| jj}W n& ty>   d}| jj }| jj D ]
\}}|	|| q-||f Y S w |rz|
|}W ne tyQ   Y n] tyt   z|
d}W n tyg   Y n tyq   d}Y nw Y n: ty } ztd||f  t  W Y d }~n d }~ww z|
d}W n ty   Y n ty   d}Y nw t j}d}|r|dkrtd tj|d d}	| jj}
|	std	|
 n-|	|krtd
|
|	|f  | ||}ntd|
|	|f  d }ntd | ||}| |}| |}||fS )NsQ   Raw body not available for multipart_form data, Silk is not showing file uploads.r*   sO   Raw body exceeds DATA_UPLOAD_MAX_MEMORY_SIZE, Silk is not showing file uploads.zUTF-8zZUnable to decode request body using char_set %s due to error: %s. Will ignore. Stacktrace:z*A max request size is set so checking size)r   zBNo way in which to get size of request body for %s, will ignore itzJRequest %s has body of size %d which is less than %d so will save the bodyzKRequest %s has body of size %d which is greater than %d, therefore ignoringz0No maximum request body size is set, continuing.)r   multipart_formr&   rX   r   rb   copyFILESr7   
appendlistdecodeAttributeErrorLookupErrorUnicodeDecodeErrorrS   rV   error	traceback	print_excr   SILKY_MAX_REQUEST_BODY_SIZErW   sys	getsizeofpathre   r\   )r   r   r   rd   rX   r=   r>   r[   max_sizesizerequest_identifierr   r   r   rX      s   



zRequestModelFactory.bodyc                 C   s<   | j j}d}|rtt| | }tj|t j	d}|S )Nr*   rP   )
r&   GETrD   ziprE   valuesr9   r:   r   r;   )r   query_paramsencoded_query_paramsquery_params_dictr   r   r   r|      s   z RequestModelFactory.query_paramsc                 C   s*   z
t | jj}W |jS  ty   Y d S w r
   )r   r&   	path_infor   	view_name)r   resolvedr   r   r   r      s   zRequestModelFactory.view_namec                 C   s   |   \}}|  }| jj}|  }tjjj|| 	 | jj
|||d}z||_W n ty6   td Y nw td|j  |S )N)ru   r?   methodr|   r   rX   zNYI: Binary request bodiesz$Created new request model with pk %s)rX   r|   r&   ru   r   r   Requestobjectscreater?   r   rd   rn   rV   rW   pk)r   rX   rd   r|   ru   r   request_modelr   r   r   construct_request_model   s&   	
z+RequestModelFactory.construct_request_model)r   r   r   __doc__r8   r%   r   r?   r\   re   rX   r|   r   r   __classcell__r   r   r'   r   r#   4   s    %Gr#   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )ResponseModelFactoryz6given a response object, craft the silk response modelc                    s   t    || _t j| _d S r
   )r$   r%   responser   r&   )r   r   r'   r   r   r%      s   
zResponseModelFactory.__init__c              	   C   s  d}t | jdd\}}t| jdd}|rt j}|dkrRtd t	|d }|s3t
d d}n||krFd}td|| jj|f  ntd|| jj|f  |r|tv rztjt|d	d
t jd}W ||fS  ttfy   td| jj|f  Y ||fS w ||fS )Nr*   r)   contentrf   z-Max size of response body defined so checkingz-Could not get size of response body. Ignoringz=Size of %d for %s is bigger than %d so ignoring response bodyz9Size of %d for %s is less than %d so saving response bodyTr]   r^   zMResponse to request with pk %s has content type %s but was unable to parse it)r"   r   r,   getattrr   SILKY_MAX_RESPONSE_BODY_SIZErV   rW   rs   rt   ro   r&   ru   rc   r9   r:   rR   r;   	TypeErrorr   warningr   )r   rX   r   r   r   max_body_sizerw   r   r   r   rX      sL   


zResponseModelFactory.bodyc           
   
   C   s   | j sJ dtd| j j  |  \}}i }| jj D ]$\}}zz|\}}W n ty7   ||}}Y nw W |||< q|||< w t	j
| j j| jjtj|t jd|d}zt|}	W n tyo   t|d}	Y nw |	d|_|  |S )Nz<Cant construct a response model if there is no request modelz4Creating response model for request model with pk %srP   )
request_idstatus_coder?   rX   zutf-8ascii)r&   rV   rW   r   rX   r   r+   r7   r   r   Responseidr   r9   r:   r   r;   base64	b64encoder   encoderk   rd   save)
r   br   r+   r=   r>   headervalsilky_responserd   r   r   r   construct_response_model$  s<   z-ResponseModelFactory.construct_response_model)r   r   r   r   r%   rX   r   r   r   r   r'   r   r      s
    $r   )r   r9   loggingrA   rs   rp   uuidr   django.core.exceptionsr   django.urlsr   r   silkr   silk.collectorr   silk.configr   	getLoggerrV   rc   rg   ra   content_type_htmlcontent_type_cssJSONEncoderr	   r"   r#   r   r   r   r   r   <module>   s2    
 E