
    	^cl#                        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mZ ddlm	Z	mZm
Z
mZ ej        ZdZdZdZdZd	Zd
ZdZdZdZdZdZd Zd ZegZ G d de          Z G d d          Zd ZddZd Z d Z!d Z"d Z#d dZ$d Z%d Z&dS )!    N   )getattropen)encodingpycompat	templaterutil      i0  i  i  i  i  i  i  i  i  c                     |dgk    p||v S )zCheck if username is a member of userlist.

    If userlist has a single '*' member, all users are considered members.
    Can be overridden by extensions to provide more complex authorization
    schemes.
       * )uiusernameuserlists      8/usr/lib/python3/dist-packages/mercurial/hgweb/common.pyismemberr   *   s     v5X!55    c                    |j         }|                     dd          }|r2|rt          | j        j        ||          rt          t          d          |                     dd          }|r0t          | j        j        ||          st          t          d          |dk    r| j        st          t          d          |dk    s|dS |dk    r#|j        d	k    rd
}t          t          |          n"|j        dk    rd}t          t          |          | 
                    dd          r |j        dk    rt          t          d          |                     dd          }|r2|rt          | j        j        ||          rt          t          d          |                     dd          }|rt          | j        j        ||          st          t          d          dS )zCheck permission for operation based on request data (including
    authentication info). Return if op allowed, else raise an ErrorResponse
    exception.   webs	   deny_reads   read not authorizeds
   allow_reads   pulls   pull not authorizedNs   uploads   PUTs   upload requires PUT requests   POSTs   push requires POST requests   push_ssls   httpss   ssl requireds	   deny_pushs   push not authorizeds
   allow-push)
remoteuser
configlistr   repor   ErrorResponseHTTP_UNAUTHORIZED	allowpullmethodHTTP_METHOD_NOT_ALLOWED
configbool	urlschemeHTTP_FORBIDDEN)	hgwebreqopuser	deny_read
allow_readmsgdenyallows	            r   
checkauthzr+   4   s   
 >D  66I G$ G(5:=$	"J"J G-/EFFF!!&-88J G8EJM4DD G-/EFFF	W}}U_}-/EFFF	w"* 
Y:0C 7===   
w		+3S999 ,, =(1J1JNO<<<FL11D GT GXejmT4@@ G-/EFFFV]33E Ghuz}dE:: G-/EFFFG Gr   c                       e Zd ZddZdS )r   Nc                     |t          |          }t                              | t          j        |                     || _        |g }|| _        || _        d S N)_statusmessage	Exception__init__r   sysstrcodeheadersmessage)selfr3   r5   r4   s       r   r1   zErrorResponse.__init__k   sW    ?$T**G4!9!9:::	?Gr   )NN)__name__
__module____qualname__r1   r   r   r   r   r   j   s(             r   r   c                   &    e Zd ZdZd ZddZd ZdS )continuereadera.  File object wrapper to handle HTTP 100-continue.

    This is used by servers so they automatically handle Expect: 100-continue
    request headers. On first read of the request body, the 100 Continue
    response is sent. This should trigger the client into actually sending
    the request body.
    c                 0    || _         || _        d| _        d S )NF)f_write	continued)r6   r=   writes      r   r1   zcontinuereader.__init__   s    r   c                 |    | j         sd| _         |                     d           | j                            |          S )NTs   HTTP/1.1 100 Continue

)r?   r>   r=   read)r6   amts     r   rC   zcontinuereader.read   s:    ~ 	:!DNKK8999v{{3r   c                 B    |dv rt          | j        |          S t          )N)s   closes   readlines	   readliness   __iter__)r   r=   AttributeError)r6   attrs     r   __getattr__zcontinuereader.__getattr__   s&    EEE464(((r   N)rA   )r7   r8   r9   __doc__r1   rC   rH   r   r   r   r;   r;   v   sP           
           r   r;   c                     t           j        j        }t          j        |                    | d          d                   S )N)ErrorzUnknown errorr   )
httpserverbasehttprequesthandler	responsesr   bytesurlget)r3   rN   s     r   r/   r/      s2    1;IY]]41KLLQOPPPr   c                 .    d| |pt          |           fz  S )Ns   %d %s)r/   )r3   r5   s     r   statusmessagerR      s    tW<t(<(<===r   c                     t           j                            | |          }t           j                            |          rt          j        |          S t          j        |           S )z%stat fn if it exists, spath otherwise)ospathjoinexistsstat)spathfncl_paths      r   get_statr\      sK    gll5"%%G	w~~g wwwu~~r   c                 B    t          | d          t          j                 S )Ns   00changelog.i)r\   rX   ST_MTIME)rY   s    r   	get_mtimer_      s    E+,,T];;r   c                     |                      d          }|D ]H}|dt          j        t          j        fv s(t          j        |v st          j        t          j        |v r dS IdS )z9Determine if a path is safe to use for filesystem access.   /r   NFT)splitr   oscurdirospardirosseposaltsep)rU   partsparts      r   
ispathsaferi      sk    JJtE  S(+X->???~%% ,!T))554r   c                    t          |          sdS |s7| pt          j                    }| t          j                            |d          }t          j        j        |                    d           }t          j        t          j
        t          j        |                    d         pd          }t          j                            ||          }	 t          j        |           t          |d          5 }|                                }	ddd           n# 1 swxY w Y   n# t          $ r t!          t"          d          t$          $ rZ}
|
j        t&          j        k    rt!          t*                    t!          t"          t-          j        |
j                            d}
~
ww xY w||j        d<   |                    |	           |S )	a+  return a file inside directory with guessed Content-Type header

    fname always uses '/' as directory separator and isn't allowed to
    contain unusual path components.
    Content-Type is guessed using the mimetypes module.
    Return an empty string if fname is illegal or file not found.

    Ns   staticra   r   z
text/plains   rbs   illegal filenames   Content-Type)ri   r   templatedirrT   rU   rV   rb   r   sysbytes	mimetypes
guess_typefsdecoderX   r   rC   	TypeErrorr   HTTP_SERVER_ERROROSErrorerrnoENOENTHTTP_NOT_FOUNDr   
strtolocalstrerrorr4   setbodybytes)templatepath	directoryfnamerestpfpathctrU   fhdataerrs              r   
staticfiler      s    e  44Y244>R33IGL%++d++,E		X.u5566q9J]
 
B 7<<	5))D
$ 	"7799D	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 D D D-/BCCC   9$$///!8#6s|#D#D  	 $&CK TJs=   $D# 6DD# DD# DD# #(F%AF  F%c              #   r   K   | r|r| |z   | z  }| |z   | z  dz  }nd}d}	 |V  |dz  }| r|| k    rd|z
  }d})z5count parity of horizontal stripes for easier reading   r   r   )stripecountoffsetcountparitys       r   	paritygenr      s       v v%4&;6:
 	5K//ZFEr   c                 t     | dd          p, | dd          p t           j                            d          pdS )zReturn repo contact information or empty string.

    web.contact is the primary source, but if that is not set, try
    ui.username or $EMAIL as a fallback to display something useful.
    r   s   contacts   uis   usernames   EMAILr   )r   environrP   )configs    r   get_contactr      sO     	vz"" 	6%%%	))	 	r   c                     ddl }|                     ddd          }d}|rXd|v rTt          j        |                                j                                      d          }|                    d|          }||fS )	a  Obtain the Content-Security-Policy header and nonce value.

    Returns a 2-tuple of the CSP header value and the nonce value.

    First value is ``None`` if CSP isn't enabled. Second value is ``None``
    if CSP isn't enabled or if the CSP header doesn't need a nonce.
    r   Nr   s   cspF)	untrusteds   %nonce%   =)uuidr   base64urlsafe_b64encodeuuid4bytesrstripreplace)r   r   cspnonces       r   	cspvaluesr      s    . KKK ))FFe)
4
4CE
 -zS  ();<<CCDIIkk*e,,:r   r.   )r   )'r   rs   rm   rT   rX   r   r   r    r   r   r	   rL   HTTP_OKHTTP_CREATEDHTTP_NOT_MODIFIEDHTTP_BAD_REQUESTr   r!   ru   r   HTTP_NOT_ACCEPTABLEHTTP_UNSUPPORTED_MEDIA_TYPErq   r   r+   	permhooksr0   r   r;   r/   rR   r\   r_   ri   r   r   r   r   r   r   r   <module>r      s         				                    _

     !  6 6 6)G )G )Gf L		 	 	 	 	I 	 	 	       4Q Q Q
> > > >  < < <  & & &R   "  " " " " "r   