B
    `2                 @   s   d dl m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mZmZmZmZ eeG d	d
 d
ZeeG dd dZeeG dd dZdd Zdd ZdddZddddddZdS )    )urlparseN)CookieProfile)implementer)BadCSRFOriginBadCSRFToken)ICSRFStoragePolicy)aslist)SimpleSerializerbytes_is_same_domainstrings_differtext_c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	LegacySessionCSRFStoragePolicya  A CSRF storage policy that defers control of CSRF storage to the
    session.

    This policy maintains compatibility with legacy ISession implementations
    that know how to manage CSRF tokens themselves via
    ``ISession.new_csrf_token`` and ``ISession.get_csrf_token``.

    Note that using this CSRF implementation requires that
    a :term:`session factory` is configured.

    .. versionadded:: 1.9

    c             C   s
   |j  S )z8 Sets a new CSRF token into the session and returns it. )sessionnew_csrf_token)selfrequest r   T/home/kop/projects/devel/pgwui/test_venv/lib/python3.7/site-packages/pyramid/csrf.pyr   "   s    z-LegacySessionCSRFStoragePolicy.new_csrf_tokenc             C   s
   |j  S )zaReturns the currently active CSRF token from the session,
        generating a new one if needed.)r   get_csrf_token)r   r   r   r   r   r   &   s    z-LegacySessionCSRFStoragePolicy.get_csrf_tokenc             C   s   |  |}tt|t| S )z5 Returns ``True`` if the ``supplied_token`` is valid.)r   r   r
   )r   r   supplied_tokenexpected_tokenr   r   r   check_csrf_token+   s    
z/LegacySessionCSRFStoragePolicy.check_csrf_tokenN)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r      s   r   c               @   s>   e Zd ZdZedd ZdddZdd Zd	d
 Zdd Z	dS )SessionCSRFStoragePolicya3  A CSRF storage policy that persists the CSRF token in the session.

    Note that using this CSRF implementation requires that
    a :term:`session factory` is configured.

    ``key``

        The session key where the CSRF token will be stored.
        Default: `_csrft_`.

    .. versionadded:: 1.9

    c               C   s   t t jS )N)r   uuiduuid4hexr   r   r   r   <lambda>C       z!SessionCSRFStoragePolicy.<lambda>_csrft_c             C   s
   || _ d S )N)key)r   r$   r   r   r   __init__E   s    z!SessionCSRFStoragePolicy.__init__c             C   s   |   }||j| j< |S )z8 Sets a new CSRF token into the session and returns it. )_token_factoryr   r$   )r   r   tokenr   r   r   r   H   s    z'SessionCSRFStoragePolicy.new_csrf_tokenc             C   s"   |j | jd}|s| |}|S )zaReturns the currently active CSRF token from the session,
        generating a new one if needed.N)r   getr$   r   )r   r   r'   r   r   r   r   N   s    
z'SessionCSRFStoragePolicy.get_csrf_tokenc             C   s   |  |}tt|t| S )z5 Returns ``True`` if the ``supplied_token`` is valid.)r   r   r
   )r   r   r   r   r   r   r   r   V   s    
z)SessionCSRFStoragePolicy.check_csrf_tokenN)r#   )
r   r   r   r   staticmethodr&   r%   r   r   r   r   r   r   r   r   3   s   
r   c               @   s>   e Zd ZdZedd Zdd	d
Zdd Zdd Zdd Z	dS )CookieCSRFStoragePolicyaA  An alternative CSRF implementation that stores its information in
    unauthenticated cookies, known as the 'Double Submit Cookie' method in the
    `OWASP CSRF guidelines
    <https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#double-submit-cookie>`_.
    This gives some additional flexibility with
    regards to scaling as the tokens can be generated and verified by a
    front-end server.

    .. versionadded:: 1.9

    .. versionchanged: 1.10

       Added the ``samesite`` option and made the default ``'Lax'``.

    c               C   s   t t jS )N)r   r   r   r    r   r   r   r   r!   p   r"   z CookieCSRFStoragePolicy.<lambda>
csrf_tokenFN/Laxc          
   C   s(   t ||||||gt |d| _|| _d S )N)cookie_namesecuremax_agehttponlypathdomains
serializersamesite)r   r	   cookie_profiler.   )r   r.   r/   r1   domainr0   r2   r5   r   r   r   r%   r   s    

z CookieCSRFStoragePolicy.__init__c                s0      |j j<  fdd}|| S )z8 Sets a new CSRF token into the request and returns it. c                s    j | d S )N)r6   Zset_cookies)r   response)r   r'   r   r   
set_cookie   s    z:CookieCSRFStoragePolicy.new_csrf_token.<locals>.set_cookie)r&   cookiesr.   Zadd_response_callback)r   r   r9   r   )r   r'   r   r      s
    
z&CookieCSRFStoragePolicy.new_csrf_tokenc             C   s&   | j |}| }|s"| |}|S )zfReturns the currently active CSRF token by checking the cookies
        sent with the current request.)r6   bind	get_valuer   )r   r   Zbound_cookiesr'   r   r   r   r      s
    
z&CookieCSRFStoragePolicy.get_csrf_tokenc             C   s   |  |}tt|t| S )z5 Returns ``True`` if the ``supplied_token`` is valid.)r   r   r
   )r   r   r   r   r   r   r   r      s    
z(CookieCSRFStoragePolicy.check_csrf_token)r+   FFNNr,   r-   )
r   r   r   r   r)   r&   r%   r   r   r   r   r   r   r   r*   ^   s         
	r*   c             C   s   | j }|t}|| S )a  Get the currently active CSRF token for the request passed, generating
    a new one using ``new_csrf_token(request)`` if one does not exist. This
    calls the equivalent method in the chosen CSRF protection implementation.

    .. versionadded :: 1.9

    )registry
getUtilityr   r   )r   r=   csrfr   r   r   r      s    
r   c             C   s   | j }|t}|| S )zGenerate a new CSRF token for the request passed and persist it in an
    implementation defined manner. This calls the equivalent method in the
    chosen CSRF protection implementation.

    .. versionadded :: 1.9

    )r=   r>   r   r   )r   r=   r?   r   r   r   r      s    
r   r+   X-CSRF-TokenTc             C   sh   d}|dk	r| j |d}|dkr8|dk	r8| j|d}| jt}|| t|sd|r`tddS dS )a  Check the CSRF token returned by the
    :class:`pyramid.interfaces.ICSRFStoragePolicy` implementation against the
    value in ``request.POST.get(token)`` (if a POST request) or
    ``request.headers.get(header)``. If a ``token`` keyword is not supplied to
    this function, the string ``csrf_token`` will be used to look up the token
    in ``request.POST``. If a ``header`` keyword is not supplied to this
    function, the string ``X-CSRF-Token`` will be used to look up the token in
    ``request.headers``.

    If the value supplied by post or by header cannot be verified by the
    :class:`pyramid.interfaces.ICSRFStoragePolicy`, and ``raises`` is
    ``True``, this function will raise an
    :exc:`pyramid.exceptions.BadCSRFToken` exception. If the values differ
    and ``raises`` is ``False``, this function will return ``False``.  If the
    CSRF check is successful, this function will return ``True``
    unconditionally.

    See :ref:`auto_csrf_checking` for information about how to secure your
    application automatically against CSRF attacks.

    .. versionadded:: 1.4a2

    .. versionchanged:: 1.7a1
       A CSRF token passed in the query string of the request is no longer
       considered valid. It must be passed in either the request body or
       a header.

    .. versionchanged:: 1.9
       Moved from :mod:`pyramid.session` to :mod:`pyramid.csrf` and updated
       to use the configured :class:`pyramid.interfaces.ICSRFStoragePolicy` to
       verify the CSRF token.

     Nz!check_csrf_token(): Invalid tokenFT)	headersr(   POSTr=   r>   r   r   r   r   )r   r'   headerraisesr   policyr   r   r   r      s    $r   F)trusted_originsallow_no_originrE   c               s  fdd}| j dkrdS | jd}d}|dkr>| j}d}n|dd	 }|s`|rXdS |d
S |dkr|t| jjdg }| jdkr|	d
|  n|	| j |s|dkr||krdS |dS t|  j dkr|dS t fdd|D s|d
|S dS )a9  
    Check the ``Origin`` of the request to see if it is a cross site request or
    not.

    If the value supplied by the ``Origin`` or ``Referer`` header isn't one of
    the trusted origins and ``raises`` is ``True``, this function will raise a
    :exc:`pyramid.exceptions.BadCSRFOrigin` exception, but if ``raises`` is
    ``False``, this function will return ``False`` instead. If the CSRF origin
    checks are successful this function will return ``True`` unconditionally.

    Additional trusted origins may be added by passing a list of domain (and
    ports if non-standard like ``['example.com', 'dev.example.com:8080']``) in
    with the ``trusted_origins`` parameter. If ``trusted_origins`` is ``None``
    (the default) this list of additional domains will be pulled from the
    ``pyramid.csrf_trusted_origins`` setting.

    ``allow_no_origin`` determines whether to return ``True`` when the
    origin cannot be determined via either the ``Referer`` or ``Origin``
    header. The default is ``False`` which will reject the check.

    Note that this function will do nothing if ``request.scheme`` is not
    ``https``.

    .. versionadded:: 1.7

    .. versionchanged:: 1.9
       Moved from :mod:`pyramid.session` to :mod:`pyramid.csrf`

    .. versionchanged:: 2.0
       Added the ``allow_no_origin`` option.

    c                s    rt d|  ndS d S )NzOrigin checking failed - F)r   )reason)rE   r   r   _fail  s    z check_csrf_origin.<locals>._failhttpsTZOriginFN zmissing Origin or Referer.zpyramid.csrf_trusted_origins>   44380z{0.domain}:{0.host_port}nullz(null does not match any trusted origins.z(Origin is insecure while host is secure.c             3   s   | ]}t  j|V  qd S )N)r   netloc).0host)originpr   r   	<genexpr>i  s    z$check_csrf_origin.<locals>.<genexpr>z&{} does not match any trusted origins.)schemerB   r(   Zreferrersplitr   r=   settings	host_portappendformatr7   r   any)r   rG   rH   rE   rJ   originZorigin_is_referrerr   )rT   rE   r   check_csrf_origin   s<    $


r^   )r+   r@   T)urllib.parser   r   Zwebob.cookiesr   Zzope.interfacer   Zpyramid.exceptionsr   r   Zpyramid.interfacesr   Zpyramid.settingsr   Zpyramid.utilr	   r
   r   r   r   r   r   r*   r   r   r   r^   r   r   r   r   <module>   s   	!+F
: