U
     5iZ                     @   sX  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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!dd Z"G dd de#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                 C   s   t tjd |  S )z
    Return a path to a builtin template.

    Avoid calling this function at the module level or in a class-definition
    because __file__ may not exist, e.g. in frozen environments.
    Z	templates)r   __file__parent)name r   6/tmp/pip-unpacked-wheel-gcyiijx6/django/views/debug.pybuiltin_template_path   s    r   c                   @   s   e Zd ZdS )ExceptionCycleWarningN)__name__
__module____qualname__r   r   r   r   r   (   s   r   c                   @   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_settingr   r   r   __init__3   s    zCallableSettingWrapper.__init__c                 C   s
   t | jS r   )reprr    r!   r   r   r   __repr__6   s    zCallableSettingWrapper.__repr__N)r   r   r   __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    
r5   c                   C   s   t tj S r   )r   r   Z!DEFAULT_EXCEPTION_REPORTER_FILTERr   r   r   r   %get_default_exception_reporter_filterH   s    r6   c                 C   s   t  }t| d|S )NZexception_reporter_filter)r6   getattr)r.   Zdefault_filterr   r   r   get_exception_reporter_filterN   s    r8   c                 C   s   t tj}t| d|S )NZexception_reporter_class)r   r   ZDEFAULT_EXCEPTION_REPORTERr7   )r.   Z default_exception_reporter_classr   r   r   r+   S   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 |}W n tk
r(   d}Y nX |r6 j}nft|trX fdd| D }nDt|trv fdd|D }n&t|trt fdd|D }n|}t	|rt
|}|S )z
        Cleanse an individual setting key/value of sensitive content. If the
        value is a dictionary, recursively cleanse the keys in that dictionary.
        Fc                    s   i | ]\}}|  ||qS r   cleanse_setting.0kvr$   r   r   
<dictcomp>m   s      z?SafeExceptionReporterFilter.cleanse_setting.<locals>.<dictcomp>c                    s   g | ]}  d |qS  r;   r>   r@   r$   r   r   
<listcomp>o   s     z?SafeExceptionReporterFilter.cleanse_setting.<locals>.<listcomp>c                    s   g | ]}  d |qS rB   r;   rD   r$   r   r   rE   q   s     )hidden_settingssearch	TypeErrorcleansed_substitute
isinstancedictitemslisttuplecallabler   )r!   keyvalueZis_sensitivecleansedr   r$   r   r<   `   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   isupperr<   r7   )r!   Zsettings_dictr?   r   r   r   get_safe_settingsz   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   r;   r=   r$   r   r   rA      s      zESafeExceptionReporterFilter.get_safe_request_meta.<locals>.<dictcomp>)hasattrrV   rL   r!   r.   r   r$   r   get_safe_request_meta   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   DEBUGrX   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)r7   r[   copyrI   )r!   r.   Zmultivaluedictr\   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 (*********).
        Nr\   __ALL__)r7   r[   POSTr]   rI   )r!   r.   r\   rR   r?   r^   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})rJ   r   	Exceptionformatr_   )r!   r.   rQ   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| ||}|||< qn$|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_localsr7   r[   rI   rL   rf   )	r!   r.   tb_framecurrent_framerg   wrapperrR   r   rQ   r   r   r   get_traceback_frame_variables   s8    



z9SafeExceptionReporterFilter.get_traceback_frame_variablesN)r   r   r   r&   rI   r   reIrF   r<   rU   rY   r[   r_   rb   rf   rp   r   r   r   r   r9   X   s   	r9   c                   @   s|   e Zd ZdZedd Zedd ZdddZd	d
 Zdd Z	dd Z
dd Zdd ZdddZdd Zdd Zdd ZdS )ExceptionReporterz0Organize and coordinate reporting on exceptions.c                 C   s   t dS )Nztechnical_500.htmlr   r$   r   r   r   html_template_path  s    z$ExceptionReporter.html_template_pathc                 C   s   t dS )Nztechnical_500.txtrt   r$   r   r   r   text_template_path  s    z$ExceptionReporter.text_template_pathFc                 C   sJ   || _ t| j | _|| _|| _|| _|| _t| jdd | _d| _	d | _
d S )NZtemplate_debugF)r.   r8   filterr/   r0   r1   is_emailr7   template_infotemplate_does_not_exist
postmortem)r!   r.   r/   r0   r1   rx   r   r   r   r"   	  s    zExceptionReporter.__init__c                 C   s    dj | jj| j | j dS )z
        Return an absolute URI from variables available in this request. Skip
        allowed hosts protection, so may return insecure URI.
        z{scheme}://{host}{path})schemehostpath)rd   r.   r|   Z_get_raw_hostZget_full_pathr$   r   r   r   _get_raw_insecure_uri  s
    z'ExceptionReporter._get_raw_insecure_uric                 C   sl  | j r*t| j tr*d| _| jjp&| jg| _|  }t|D ]p\}}d|krg }|d D ]B\}}t	|}t
|dkrd|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< | ) |d< | j r@| j j*|d< | jrVt| j|d< |rh|d |d< |S )z5Return a dictionary containing traceback information.Tvarsi   u   %s… <trimmed %d bytes string>r   rC   startNend      asciireplace)errors)get_versionz%[unable to retrieve the current user]z%d.%d.%d   )rx   unicode_hintframesr.   Zrequest_metauser_strZfiltered_POST_itemsr   Zsys_executableZsys_version_infoZserver_timeZdjango_version_infosys_pathry   rz   r{   Zrequest_GET_itemsZrequest_FILES_itemsZrequest_COOKIES_itemsZrequest_insecure_uriZexception_typeZexception_valueZ	lastframe)+r/   
issubclassr	   rz   r0   chainr{   get_traceback_frames	enumerater
   lenappendUnicodeErrorr7   argsr   maxmindjangor   r.   struserrc   rx   rw   rY   rM   rb   rL   rU   sys
executableversion_infor   nowr~   ry   GETZFILESZCOOKIESr   r   )r!   r   iframeZ
frame_varsr?   r@   r   r   r   Zunicode_strr   r   cr   r   r   get_traceback_data   sz    
" 
z$ExceptionReporter.get_traceback_datac              	   C   sB   | j jdd}t| }W 5 Q R X t|  dd}||S )z1Return HTML version of debug 500 HTTP error page.utf-8encodingF)use_l10n)ru   openDEBUG_ENGINEfrom_stringreadr   r   renderr!   fhtr   r   r   r   r,   j  s    z$ExceptionReporter.get_traceback_htmlc              	   C   sD   | j 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   r   F)Z
autoescaper   )rv   r   r   r   r   r   r   r   r   r   r   r   r-   q  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rz&t|d}|  }W 5 Q R X W n tk
r   Y nX |S )N
get_sourcerb)rW   r   ImportError
splitlinesr   r   OSError)r!   filenameloadermodule_namesourcefpr   r   r   _get_sourcex  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   r      s   coding[:=]\s*([-\w.]+)r   c                    s   g | ]}t | d qS )r   )r   )r>   sliner   r   r   rE     s     z:ExceptionReporter._get_lines_from_file.<locals>.<listcomp>)r   rJ   bytesrq   rG   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_file  s(    z&ExceptionReporter._get_lines_from_filec                 C   s4   t |dd }t |dd }t |dd }|p2|r0d S |S )N	__cause____suppress_context____context__)r7   )r!   r0   explicitZsuppress_contextZimplicitr   r   r   _get_explicit_or_implicit_cause  s    z1ExceptionReporter._get_explicit_or_implicit_causec                 C   s   g }| j }|r>|| | |}||kr
td| t q>q
g }|sJ|S | }|s\| jn|j}|	| 
|| z| }W n tk
r   Y qY nX |j}qb|S )NzHCycle in the exception chain detected: exception '%s' encountered again.)r0   r   r   warningswarnr   popr1   __traceback__extendget_exception_traceback_framesr   )r!   
exceptionsr0   r   r1   r   r   r   r     s2    


z&ExceptionReporter.get_traceback_framesc                 c   s  |  |}t|dd}|d kr.||d ddV  |d k	r|jjdrN|j}q.|jjj}|jjj}|j	d }|jj
d}|jj
dpd	}	| ||d
||	\}
}}}|
d kr|}
g }d}g }||||	drdnd|||d | j| j|jt|||||
d dV  |j}q.d S )Nr   Tr   )	exc_causeexc_cause_explicitr1   typeZ__traceback_hide__r   
__loader__r   rC      z<source code not available>zdjango.r   )r   r   r1   r   r   functionr   r   idr   r   r   pre_context_lineno)r   r7   rm   rl   gettb_nextrj   co_filenamerk   	tb_lineno	f_globalsr   
startswithrw   rp   r.   r   )r!   r0   r1   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     sX    




    z0ExceptionReporter.get_exception_traceback_frames)F)NN)r   r   r   r&   propertyru   rv   r"   r   r   r,   r-   r   r   r   r   r   r   r   r   r   rs      s   


J
"!rs   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 n0 tttfk
r~   d}| jrv| jjnd}Y npX d}|r| jdkrt|dkrt|d dkrt	|d d d	d
t	|d d dd
  krdkrn nt
| S t	| dtj}t|tjr|j}d
}zt| j}W n tk
r8   Y npX |j}t|drT|j}n6t|drh|j}n"t|drt|jdr|jj}t|dr|j}	d|	|f }t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~   r   NtriedTF/Zapp_namerC   	namespaceZadminurlconf
view_classr   	__class__r   z%s.%sztechnical_404.htmlr   r   )	r   Zroot_urlconfrequest_pathZurlpatternsresolvedreasonr.   r   Zraising_view_namer(   r*   )#r   r   rH   KeyErrorZ	path_inforesolver_matchr   r~   r   r7   default_urlconfr   ZROOT_URLCONFrJ   types
ModuleTyper   r   r   funcrW   r   r   r   r   r   r   r   r   r6   r   r   rU   r   r   )r.   	exceptionZ	error_urlr   r   r   Zcallerr   objmoduler   r   Zreporter_filterr   r   r   r   technical_404_response  sp    
 
r   c              	   C   sJ   t 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.zdefault_urlconf.htmlr   r   versionr(   r   )	r   r   r   r   r   r   r   r   r   )r.   r   r   r   r   r   r   r   ?  s     r   )r'   )/	functoolsrq   r   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   r   UserWarningr   r   r5   	lru_cacher6   r8   r+   r9   rs   r   r   r   r   r   r   <module>   sF   


 '  >