U
    8ÄT_žS  ã                   @   sB  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
mZ d dlmZ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 d dlmZ d dlmZ edddid�Z ee!ƒj"Z#G dd„ dƒZ$d%dd„Z%e  &¡ dd„ ƒZ'dd„ Z(dd„ Z)G dd„ dƒZ*G dd „ d ƒZ+d!d"„ Z,d#d$„ Z-dS )&é    N)ÚPath)Úsettings)ÚHttp404ÚHttpResponseÚHttpResponseNotFound)ÚContextÚEngineÚTemplateDoesNotExist)Úpprint)Úresolve)Útimezone)ÚMultiValueDict)Ú	force_str)Úimport_string)Ú_lazy_re_compile)Úget_docs_versionTZi18nzdjango.templatetags.i18n)ÚdebugÚ	librariesc                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚCallableSettingWrapperzÅ
    Object to wrap callable appearing in settings.
    * Not to call in the debug page (#21345).
    * Not to break the debug page if the callable forbidding to set attributes
      (#23070).
    c                 C   s
   || _ d S ©N)Ú_wrapped)ÚselfZcallable_setting© r   ú6/tmp/pip-unpacked-wheel-dv63caxw/django/views/debug.pyÚ__init__&   s    zCallableSettingWrapper.__init__c                 C   s
   t | jƒS r   )Úreprr   ©r   r   r   r   Ú__repr__)   s    zCallableSettingWrapper.__repr__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r      s   r   éô  c                 C   sL   t | ƒ| |||ƒ}|  d¡r2| ¡ }t||dd�S | ¡ }t||dd�S dS )z‰
    Create a technical server error response. The last three arguments are
    the values returned from sys.exc_info() and friends.
    ú	text/html)ÚstatusÚcontent_typeztext/plain; charset=utf-8N)Úget_exception_reporter_classZacceptsÚget_traceback_htmlr   Úget_traceback_text)ÚrequestÚexc_typeÚ	exc_valueÚtbÚstatus_codeZreporterÚhtmlÚtextr   r   r   Útechnical_500_response-   s    
r0   c                   C   s   t tjƒƒ S r   )r   r   Z!DEFAULT_EXCEPTION_REPORTER_FILTERr   r   r   r   Ú%get_default_exception_reporter_filter;   s    r1   c                 C   s   t ƒ }t| d|ƒS )NZexception_reporter_filter)r1   Úgetattr)r)   Zdefault_filterr   r   r   Úget_exception_reporter_filterA   s    r3   c                 C   s   t tjƒ}t| d|ƒS )NZexception_reporter_class)r   r   ZDEFAULT_EXCEPTION_REPORTERr2   )r)   Z default_exception_reporter_classr   r   r   r&   F   s    
r&   c                   @   sb   e Zd ZdZdZedej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 )ÚSafeExceptionReporterFilterz‹
    Use annotations made by the sensitive_post_parameters and
    sensitive_variables decorators to filter out sensitive information.
    z********************z#API|TOKEN|KEY|SECRET|PASS|SIGNATURE)Úflagsc                    s¬   z~ˆ j  |¡rˆ j}nft|tƒr8‡ fdd„| ¡ D ƒ}nDt|tƒrV‡ fdd„|D ƒ}n&t|tƒrxt‡ fdd„|D ƒƒ}n|}W n tk
r–   |}Y nX t	|ƒr¨t
|ƒ}|S )z¦
        Cleanse an individual setting key/value of sensitive content. If the
        value is a dictionary, recursively cleanse the keys in that dictionary.
        c                    s   i | ]\}}|ˆ   ||¡“qS r   ©Úcleanse_setting©Ú.0ÚkÚvr   r   r   Ú
<dictcomp>\   s      z?SafeExceptionReporterFilter.cleanse_setting.<locals>.<dictcomp>c                    s   g | ]}ˆ   d |¡‘qS ©Ú r6   ©r9   r;   r   r   r   Ú
<listcomp>^   s     z?SafeExceptionReporterFilter.cleanse_setting.<locals>.<listcomp>c                    s   g | ]}ˆ   d |¡‘qS r=   r6   r?   r   r   r   r@   `   s     )Úhidden_settingsÚsearchÚcleansed_substituteÚ
isinstanceÚdictÚitemsÚlistÚtupleÚ	TypeErrorÚcallabler   )r   ÚkeyÚvalueÚcleansedr   r   r   r7   S   s    



z+SafeExceptionReporterFilter.cleanse_settingc                 C   s4   i }t tƒD ]"}| ¡ r|  |tt|ƒ¡||< q|S )z‡
        Return a dictionary of the settings module with values of sensitive
        settings replaced with stars (*********).
        )Údirr   Úisupperr7   r2   )r   Zsettings_dictr:   r   r   r   Úget_safe_settingsl   s
    z-SafeExceptionReporterFilter.get_safe_settingsc                    s&   t |dƒsi S ‡ fdd„|j ¡ D ƒS )zU
        Return a dictionary of request.META with sensitive values redacted.
        ÚMETAc                    s   i | ]\}}|ˆ   ||¡“qS r   r6   r8   r   r   r   r<   }   s      zESafeExceptionReporterFilter.get_safe_request_meta.<locals>.<dictcomp>)ÚhasattrrQ   rF   ©r   r)   r   r   r   Úget_safe_request_metaw   s    
z1SafeExceptionReporterFilter.get_safe_request_metac                 C   s
   t jdkS )a  
        This filter is to add safety in production environments (i.e. DEBUG
        is False). If DEBUG is True then your site is not safe anyway.
        This hook is provided as a convenience to easily activate or
        deactivate the filter on a per request basis.
        F)r   ÚDEBUGrS   r   r   r   Ú	is_active   s    z%SafeExceptionReporterFilter.is_activec                 C   sB   t |dg ƒ}|  |¡r>|r>| ¡ }|D ]}||kr&| j||< q&|S )zç
        Replace the keys in a MultiValueDict marked as sensitive with stars.
        This mitigates leaking sensitive POST parameters if something like
        request.POST['nonexistent_key'] throws an exception (#21098).
        Úsensitive_post_parameters)r2   rV   ÚcopyrC   )r   r)   ZmultivaluedictrW   Úparamr   r   r   Úget_cleansed_multivaluedictˆ   s    z7SafeExceptionReporterFilter.get_cleansed_multivaluedictc                 C   s|   |dkri S t |dg ƒ}|  |¡rr|rr|j ¡ }|dkrP|D ]}| j||< q<|S |D ]}||krT| j||< qT|S n|jS dS )zk
        Replace the values of POST parameters marked as sensitive with
        stars (*********).
        NrW   Ú__ALL__)r2   rV   ÚPOSTrX   rC   )r   r)   rW   rM   r:   rY   r   r   r   Úget_post_parameters–   s    
z/SafeExceptionReporterFilter.get_post_parametersc              
   C   sV   zt |tƒ}W n2 tk
r@ } zd ||¡ W Y ¢S d }~X Y nX |rR|  ||¡}|S )Nz{!r} while evaluating {!r})rD   r   Ú	ExceptionÚformatrZ   )r   r)   rL   Zis_multivalue_dictÚer   r   r   Úcleanse_special_types¯   s    "z1SafeExceptionReporterFilter.cleanse_special_typesc           	      C   s  |j }d}|dk	rH|jjdkr@d|jkr@|jd }t|ddƒ}qH|j }q
i }|  |¡r´|r´|dkrz|jD ]}| j||< qhqØ|j ¡ D ],\}}||krœ| j}n|  ||¡}|||< q„n$|j ¡ D ]\}}|  ||¡||< q¾|jjdk�rd|jk�r| j|d< | j|d< | ¡ S )ze
        Replace the values of variables marked as sensitive with
        stars (*********).
        NZsensitive_variables_wrapperÚsensitive_variablesr[   Ú	func_argsZfunc_kwargs)	Úf_backÚf_codeÚco_nameÚf_localsr2   rV   rC   rF   ra   )	r   r)   Útb_frameÚcurrent_framerb   ÚwrapperrM   ÚnamerL   r   r   r   Úget_traceback_frame_variables½   s8    ÿ

ÿ

z9SafeExceptionReporterFilter.get_traceback_frame_variablesN)r   r   r    r!   rC   r   ÚreÚIrA   r7   rP   rT   rV   rZ   r]   ra   rl   r   r   r   r   r4   K   s   	r4   c                   @   sL   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ Zddd„Z	dd„ Z
dS )ÚExceptionReporterz0Organize and coordinate reporting on exceptions.Fc                 C   sJ   || _ t| j ƒ| _|| _|| _|| _|| _t| jdd ƒ| _d| _	d | _
d S )NZtemplate_debugF)r)   r3   Úfilterr*   r+   r,   Úis_emailr2   Útemplate_infoÚtemplate_does_not_existÚ
postmortem)r   r)   r*   r+   r,   rq   r   r   r   r   ò   s    zExceptionReporter.__init__c                 C   s`  | j r*t| j tƒr*d| _| jjp&| jg| _|  ¡ }t|ƒD ]p\}}d|kr¢g }|d D ]B\}}t	|ƒ}t
|ƒdkrŠd|dd… t
|ƒf }| ||f¡ qV||d< |||< q:d}| j �r0t| j tƒ�r0t| jddƒ}t| jd	dƒ}	|dk	�r0|	dk	�r0| jjd
 }
t|
t|d dƒt|	d t
|
ƒƒ… ddd�}ddlm} | jdk�rNd}n,zt| jjƒ}W n tk
�rx   d}Y nX | j||| j| j | j¡|t| j | j¡ ¡ ƒ| j ¡ tj dtj!dd…  t" #¡ |ƒ tj$| j%| j| jdœ}| jdk	�r | jj& ¡ |d< | jj' ¡ |d< | jj( ¡ |d< | j �r4| j j)|d< | j�rJt| jƒ|d< |�r\|d |d< |S )z5Return a dictionary containing traceback information.TÚvarsi   u   %sâ€¦ <trimmed %d bytes string>r   r>   ÚstartNÚendé   é   ÚasciiÚreplace)Úerrors)Úget_versionz%[unable to retrieve the current user]z%d.%d.%dé   )rq   Úunicode_hintÚframesr)   Zrequest_metaÚuser_strZfiltered_POST_itemsr   Zsys_executableZsys_version_infoZserver_timeZdjango_version_infoÚsys_pathrr   rs   rt   Zrequest_GET_itemsZrequest_FILES_itemsZrequest_COOKIES_itemsZexception_typeZexception_valueéÿÿÿÿZ	lastframe)*r*   Ú
issubclassr	   rs   r+   Úchainrt   Úget_traceback_framesÚ	enumerater
   ÚlenÚappendÚUnicodeErrorr2   Úargsr   ÚmaxÚminÚdjangor}   r)   ÚstrÚuserr^   rq   rp   rT   rG   r]   rF   rP   ÚsysÚ
executableÚversion_infor   ÚnowÚpathrr   ÚGETZFILESZCOOKIESr   )r   r€   ÚiÚframeZ
frame_varsr:   r;   r   rv   rw   Zunicode_strr}   r�   Úcr   r   r   Úget_traceback_dataþ   sx    
" þ
ðz$ExceptionReporter.get_traceback_datac              	   C   sH   t tddƒjdd��}t | ¡ ¡}W 5 Q R X t|  ¡ dd�}| |¡S )z1Return HTML version of debug 500 HTTP error page.Ú	templatesztechnical_500.htmlúutf-8©ÚencodingF)Úuse_l10n©	r   ÚCURRENT_DIRÚopenÚDEBUG_ENGINEÚfrom_stringÚreadr   rš   Úrender©r   ÚfhÚtr™   r   r   r   r'   F  s    z$ExceptionReporter.get_traceback_htmlc              	   C   sJ   t tddƒjdd��}t | ¡ ¡}W 5 Q R X t|  ¡ ddd�}| |¡S )z7Return plain text version of debug 500 HTTP error page.r›   ztechnical_500.txtrœ   r�   F)Z
autoescaperŸ   r    r§   r   r   r   r(   M  s    z$ExceptionReporter.get_traceback_textc              	   C   sŠ   d }t |dƒrBz| |¡}W n tk
r0   Y nX |d k	rB| ¡ }|d kr†z&t|dƒ�}| ¡  ¡ }W 5 Q R X W n tk
r„   Y nX |S )NÚ
get_sourceÚrb)rR   rª   ÚImportErrorÚ
splitlinesr¢   r¥   ÚOSError)r   ÚfilenameÚloaderÚmodule_nameÚsourceÚfpr   r   r   Ú_get_sourceT  s    
zExceptionReporter._get_sourceNc                    sæ   |   |||¡}|dkr"dg dg fS t|d tƒrzd‰ |dd… D ]&}t d|¡}|r@|d  d¡‰  qhq@‡ fdd„|D ƒ}td|| ƒ}	|| }
z(||	|… }|| }||d |
… }W n  tk
rØ   dg dg f Y S X |	|||fS )	z—
        Return context_lines before and after lineno from file.
        Return (pre_context_lineno, pre_context, context_line, post_context).
        Nr   rz   é   s   coding[:=]\s*([-\w.]+)rx   c                    s   g | ]}t |ˆ d ƒ‘qS )r{   )r�   )r9   Úsliner�   r   r   r@   z  s     z:ExceptionReporter._get_lines_from_file.<locals>.<listcomp>)r´   rD   Úbytesrm   rB   ÚdecoderŒ   Ú
IndexError)r   r¯   ÚlinenoZcontext_linesr°   r±   r²   ÚlineÚmatchZlower_boundZupper_boundÚpre_contextÚcontext_lineÚpost_contextr   r�   r   Ú_get_lines_from_filee  s(    z&ExceptionReporter._get_lines_from_filec                 C   sn  dd„ }g }| j }|r4| |¡ ||ƒ}||krq4qg }|s@|S | ¡ }|sR| jn|j}|d k	�rj|jj d¡rx|j}qX|jj	j
}|jj	j}|jd }|jj d¡}	|jj d¡p´d}
|  ||d|	|
¡\}}}}|d krè|}g }d	}g }| ||ƒt|d
dƒ||
 d¡�rdnd|||d | j | j|j¡t|ƒ||||d dœ¡ |j�sb|�rb| ¡ }|j}qX|j}qX|S )Nc                 S   s    t | dd ƒ}t | dd ƒ}|p|S )NÚ	__cause__Ú__context__)r2   )r+   ÚexplicitZimplicitr   r   r   Úexplicit_or_implicit_causeˆ  s    zJExceptionReporter.get_traceback_frames.<locals>.explicit_or_implicit_causeZ__traceback_hide__rx   Ú
__loader__r   r>   é   z<source code not available>rÁ   Tzdjango.rŽ   r�   )Z	exc_causeZexc_cause_explicitr,   Útyper¯   Úfunctionrº   ru   Úidr½   r¾   r¿   Úpre_context_lineno)r+   r‰   Úpopr,   Ú__traceback__rh   rg   ÚgetÚtb_nextre   Úco_filenamerf   Ú	tb_linenoÚ	f_globalsrÀ   r2   Ú
startswithrp   rl   r)   rÉ   )r   rÄ   Ú
exceptionsr+   r€   r,   r¯   rÈ   rº   r°   r±   rÊ   r½   r¾   r¿   r   r   r   r†   ‡  sl    




    ÿ
óz&ExceptionReporter.get_traceback_frames)F)NN)r   r   r    r!   r   rš   r'   r(   r´   rÀ   r†   r   r   r   r   ro   ð   s   
H
"ro   c              
   C   sæ  z|j d d }W n( tttfk
r:   | jdd… }Y nX z|j d d }W n tttfk
rl   g }Y nlX |rÐ| jdkrØt|ƒdkrØt|d ƒdkrØt|d d ddƒt|d d d	dƒ  krÌd
krØn nt| ƒS t| dt	j
ƒ}t|tjƒrø|j}d}zt| jƒ}W n tk
�r    Y n\X |j}t|dƒ�r<|j}n"t|dƒ�r^t|jdƒ�r^|jj}t|dƒ�r||j}d||f }ttddƒjdd��}	t |	 ¡ ¡}
W 5 Q R X tƒ }t|t	j
||t|ƒ| | ¡ |dœƒ}t|
  |¡dd�S )zBCreate a technical 404 error response. `exception` is the Http404.r   r•   rx   NÚtriedú/Zapp_namer>   Ú	namespaceZadminÚurlconfr   Ú	__class__r   z%s.%sr›   ztechnical_404.htmlrœ   r�   )r×   Zroot_urlconfÚrequest_pathZurlpatternsÚreasonr)   r   Zraising_view_namer#   ©r%   )!r‹   r¹   rI   ÚKeyErrorZ	path_infor•   rˆ   r2   Údefault_urlconfr   ZROOT_URLCONFrD   ÚtypesÚ
ModuleTyper   r   r   ÚfuncrR   rØ   r   r   r¡   r¢   r£   r¤   r¥   r1   r   r�   rP   r   r¦   )r)   Ú	exceptionZ	error_urlrÔ   r×   ZcallerZresolver_matchÚobjÚmoduler¨   r©   Zreporter_filterr™   r   r   r   Útechnical_404_responseÎ  sf    
ÿ
þý üü
ø
rä   c              	   C   sN   t tddƒjdd��}t | ¡ ¡}W 5 Q R X tdtƒ iƒ}t| 	|¡dd�S )z+Create an empty URLconf 404 error response.r›   zdefault_urlconf.htmlrœ   r�   Úversionr#   rÛ   )
r   r¡   r¢   r£   r¤   r¥   r   r   r   r¦   )r)   r¨   r©   r™   r   r   r   rÝ     s     ÿrÝ   )r"   ).Ú	functoolsrm   r‘   rÞ   Úpathlibr   Zdjango.confr   Zdjango.httpr   r   r   Zdjango.templater   r   r	   Zdjango.template.defaultfiltersr
   Zdjango.urlsr   Zdjango.utilsr   Zdjango.utils.datastructuresr   Zdjango.utils.encodingr   Zdjango.utils.module_loadingr   Zdjango.utils.regex_helperr   Zdjango.utils.versionr   r£   Ú__file__Úparentr¡   r   r0   Ú	lru_cacher1   r3   r&   r4   ro   rä   rÝ   r   r   r   r   Ú<module>   s@   þ


 & _9