B
    `E                 @   s  d dl Z d dlZd dlmZmZ d dlmZ d dlZd dlZd dl	Z
d dlmZ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mZ d d	lmZmZmZmZmZ ed
Z G dd dZ!eeG dd de!Z"eeG dd de!Z#eeG dd de!Z$dd Z%dd Z&G dd dZ'G dd de(Z)d/ddZ*d0ddZ+d d! Z,G d"d# d#Z-eeG d$d% d%e!Z.G d&d' d'Z/eeG d(d) d)e!Z0ed*d+d,gZ1d-d. Z2dS )1    N)utf_8_decodeutf_8_encode)
namedtuple)quoteunquote)CookieProfile)implementer)AuthenticatedEveryone)IAuthenticationPolicyIDebugLogger)SimpleSerializerascii_bytes_strings_differtext_z^[A-Za-z][A-Za-z0-9+_-]*$c               @   s8   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dS )CallbackAuthenticationPolicyz Abstract class FNc             C   sH   |j t}|rD| j}|jd |j }|d | }||d |  d S )N.z: )registryZqueryUtilityr   	__class__
__module____name__debug)selfmsg
methodnamerequestloggercls	classname r    ^/home/kop/projects/devel/pgwui/test_venv/lib/python3.7/site-packages/pyramid/authentication.py_log    s    z!CallbackAuthenticationPolicy._logc             C   s   |t tfkrd }|S )N)r	   r
   )r   Zprincidr    r    r!   _clean_principal(   s    z-CallbackAuthenticationPolicy._clean_principalc             C   s   | j }| |}|dkr.|o(| dd| dS | |dkrV|oP| d| d| dS | jdkr||ov| d|f d| |S | ||}|dk	r|o| d||f d| |S |o| dd| dS )a*  Return the authenticated userid or ``None``.

        If no callback is registered, this will be the same as
        ``unauthenticated_userid``.

        If a ``callback`` is registered, this will return the userid if
        and only if the callback returns a value that is not ``None``.

        Nz<call to unauthenticated_userid returned None; returning Noneauthenticated_useridzVuse of userid %r is disallowed by any built-in Pyramid security policy, returning Nonez/there was no groupfinder callback; returning %rz.groupfinder callback returned %r; returning %rz2groupfinder callback returned None; returning None)r   unauthenticated_useridr"   r#   callback)r   r   r   useridZcallback_okr    r    r!   r$   -   sB    


z1CallbackAuthenticationPolicy.authenticated_useridc             C   s  | j }tg}| |}|dkr<|o6| d||f d| |S | |dkrh|ob| d||f d| |S | jdkr|o| dd| g }n$| ||}|o| d|f d| |dkr|o| d|f d| |S |t || || |o| d|f d| |S )a/  A list of effective principals derived from request.

        This will return a list of principals including, at least,
        :data:`pyramid.authorization.Everyone`. If there is no authenticated
        userid, or the ``callback`` returns ``None``, this will be the
        only principal:

        .. code-block:: python

            return [Everyone]

        If the ``callback`` does not return ``None`` and an authenticated
        userid is found, then the principals will include
        :data:`pyramid.authorization.Authenticated`, the
        ``authenticated_userid`` and the list of principals returned by the
        ``callback``:

        .. code-block:: python

            extra_principals = callback(userid, request)
            return [Everyone, Authenticated, userid] + extra_principals

        Nz0unauthenticated_userid returned %r; returning %reffective_principalszMunauthenticated_userid returned disallowed %r; returning %r as if it was Nonez-groupfinder callback is None, so groups is []z*groupfinder callback returned %r as groupsz"returning effective principals: %r)	r   r
   r%   r"   r#   r&   appendr	   extend)r   r   r   r(   r'   groupsr    r    r!   r(   a   sT    





z1CallbackAuthenticationPolicy.effective_principals)
r   r   __qualname____doc__r   r&   r"   r#   r$   r(   r    r    r    r!   r      s   4r   c               @   sR   e Zd ZdZd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 )RepozeWho1AuthenticationPolicya  A :app:`Pyramid` :term:`authentication policy` which
    obtains data from the :mod:`repoze.who` 1.X WSGI 'API' (the
    ``repoze.who.identity`` key in the WSGI environment).

    Constructor Arguments

    ``identifier_name``

       Default: ``auth_tkt``.  The :mod:`repoze.who` plugin name that
       performs remember/forget.  Optional.

    ``callback``

        Default: ``None``.  A callback passed the :mod:`repoze.who` identity
        and the :term:`request`, expected to return ``None`` if the user
        represented by the identity doesn't exist or a sequence of principal
        identifiers (possibly empty) representing groups if the user does
        exist.  If ``callback`` is None, the userid will be assumed to exist
        with no group principals.

    Objects of this class implement the interface described by
    :class:`pyramid.interfaces.IAuthenticationPolicy`.
    auth_tktNc             C   s   || _ || _d S )N)identifier_namer&   )r   r0   r&   r    r    r!   __init__   s    z'RepozeWho1AuthenticationPolicy.__init__c             C   s   |j dS )Nzrepoze.who.identity)environget)r   r   r    r    r!   _get_identity   s    z,RepozeWho1AuthenticationPolicy._get_identityc             C   s&   |j d}|d krd S || j }|S )Nzrepoze.who.plugins)r2   r3   r0   )r   r   Zplugins
identifierr    r    r!   _get_identifier   s
    
z.RepozeWho1AuthenticationPolicy._get_identifierc             C   s   |  |}|dkr*| jo$| dd| dS |d }|dkrV| joP| d| d| dS | |dkr| joz| d| d| dS | jdkr|S | ||dk	r|S dS )a*  Return the authenticated userid or ``None``.

        If no callback is registered, this will be the same as
        ``unauthenticated_userid``.

        If a ``callback`` is registered, this will return the userid if
        and only if the callback returns a value that is not ``None``.

        Nz+repoze.who identity is None, returning Noner$   zrepoze.who.useridz)repoze.who.userid is None, returning NonezVuse of userid %r is disallowed by any built-in Pyramid security policy, returning None)r4   r   r"   r#   r&   )r   r   identityr'   r    r    r!   r$      s2    





z3RepozeWho1AuthenticationPolicy.authenticated_useridc             C   s   |  |}|dkrdS |d S )zA Return the ``repoze.who.userid`` key from the detected identity.Nzrepoze.who.userid)r4   )r   r   r7   r    r    r!   r%     s    
z5RepozeWho1AuthenticationPolicy.unauthenticated_useridc             C   s   t g}| |}|dkr4| jo.| d| d| |S | jdkrDg }n| ||}|dkrt| jon| d| d| |S |d }|dkr| jo| d| d| |S | |dkr| jo| d||f d| |S |t || || |S )a3  A list of effective principals derived from the identity.

        This will return a list of principals including, at least,
        :data:`pyramid.authorization.Everyone`. If there is no identity, or
        the ``callback`` returns ``None``, this will be the only principal.

        If the ``callback`` does not return ``None`` and an identity is
        found, then the principals will include
        :data:`pyramid.authorization.Authenticated`, the
        ``authenticated_userid`` and the list of principals returned by the
        ``callback``.

        Nz*repoze.who identity was None; returning %rr(   z;security policy groups callback returned None; returning %rzrepoze.who.useridz(repoze.who.userid was None; returning %rzMunauthenticated_userid returned disallowed %r; returning %r as if it was None)	r
   r4   r   r"   r&   r#   r)   r	   r*   )r   r   r(   r7   r+   r'   r    r    r!   r(     sL    








z3RepozeWho1AuthenticationPolicy.effective_principalsc             K   s4   |  |}|dkrg S |j}|}||d< |||S )a)  Store the ``userid`` as ``repoze.who.userid``.

        The identity to authenticated to :mod:`repoze.who`
        will contain the given userid as ``userid``, and
        provide all keyword arguments as additional identity
        keys. Useful keys could be ``max_age`` or ``userdata``.
        Nzrepoze.who.userid)r6   r2   remember)r   r   r'   kwr5   r2   r7   r    r    r!   r8   [  s    
z'RepozeWho1AuthenticationPolicy.rememberc             C   s.   |  |}|dkrg S | |}||j|S )zForget the current authenticated user.

        Return headers that, if included in a response, will delete the
        cookie responsible for tracking the current user.

        N)r6   r4   forgetr2   )r   r   r5   r7   r    r    r!   r:   k  s
    

z%RepozeWho1AuthenticationPolicy.forget)r/   N)r   r   r,   r-   r1   r4   r6   r$   r%   r(   r8   r:   r    r    r    r!   r.      s   
/Ir.   c               @   s2   e Zd ZdZdddZdd Zd	d
 Zdd ZdS )RemoteUserAuthenticationPolicya  A :app:`Pyramid` :term:`authentication policy` which
    obtains data from the ``REMOTE_USER`` WSGI environment variable.

    Constructor Arguments

    ``environ_key``

        Default: ``REMOTE_USER``.  The key in the WSGI environ which
        provides the userid.

    ``callback``

        Default: ``None``.  A callback passed the userid and the request,
        expected to return None if the userid doesn't exist or a sequence of
        principal identifiers (possibly empty) representing groups if the
        user does exist.  If ``callback`` is None, the userid will be assumed
        to exist with no group principals.

    ``debug``

        Default: ``False``.  If ``debug`` is ``True``, log messages to the
        Pyramid debug logger about the results of various authentication
        steps.  The output from debugging is useful for reporting to maillist
        or IRC channels when asking for support.

    Objects of this class implement the interface described by
    :class:`pyramid.interfaces.IAuthenticationPolicy`.
    REMOTE_USERNFc             C   s   || _ || _|| _d S )N)environ_keyr&   r   )r   r=   r&   r   r    r    r!   r1     s    z'RemoteUserAuthenticationPolicy.__init__c             C   s   |j | jS )z8 The ``REMOTE_USER`` value found within the ``environ``.)r2   r3   r=   )r   r   r    r    r!   r%     s    z5RemoteUserAuthenticationPolicy.unauthenticated_useridc             K   s   g S )zA no-op. The ``REMOTE_USER`` does not provide a protocol for
        remembering the user. This will be application-specific and can
        be done somewhere else or in a subclass.r    )r   r   r'   r9   r    r    r!   r8     s    z'RemoteUserAuthenticationPolicy.rememberc             C   s   g S )zA no-op. The ``REMOTE_USER`` does not provide a protocol for
        forgetting the user. This will be application-specific and can
        be done somewhere else or in a subclass.r    )r   r   r    r    r!   r:     s    z%RemoteUserAuthenticationPolicy.forget)r<   NF)r   r   r,   r-   r1   r%   r8   r:   r    r    r    r!   r;   y  s
   
r;   c               @   s2   e Zd ZdZdd	d
Zdd Zdd Zdd ZdS )AuthTktAuthenticationPolicya@  A :app:`Pyramid` :term:`authentication policy` which
    obtains data from a Pyramid "auth ticket" cookie.

    Constructor Arguments

    ``secret``

       The secret (a string) used for auth_tkt cookie signing.  This value
       should be unique across all values provided to Pyramid for various
       subsystem secrets (see :ref:`admonishment_against_secret_sharing`).
       Required.

    ``callback``

       Default: ``None``.  A callback passed the userid and the
       request, expected to return ``None`` if the userid doesn't
       exist or a sequence of principal identifiers (possibly empty) if
       the user does exist.  If ``callback`` is ``None``, the userid
       will be assumed to exist with no principals.  Optional.

    ``cookie_name``

       Default: ``auth_tkt``.  The cookie name used
       (string).  Optional.

    ``secure``

       Default: ``False``.  Only send the cookie back over a secure
       conn.  Optional.

    ``include_ip``

       Default: ``False``.  Make the requesting IP address part of
       the authentication data in the cookie.  Optional.

       For IPv6 this option is not recommended. The ``mod_auth_tkt``
       specification does not specify how to handle IPv6 addresses, so using
       this option in combination with IPv6 addresses may cause an
       incompatible cookie. It ties the authentication ticket to that
       individual's IPv6 address.

    ``timeout``

       Default: ``None``.  Maximum number of seconds which a newly
       issued ticket will be considered valid.  After this amount of
       time, the ticket will expire (effectively logging the user
       out).  If this value is ``None``, the ticket never expires.
       Optional.

    ``reissue_time``

       Default: ``None``.  If this parameter is set, it represents the number
       of seconds that must pass before an authentication token cookie is
       automatically reissued as the result of a request which requires
       authentication.  The duration is measured as the number of seconds
       since the last auth_tkt cookie was issued and 'now'.  If this value is
       ``0``, a new ticket cookie will be reissued on every request which
       requires authentication.

       A good rule of thumb: if you want auto-expired cookies based on
       inactivity: set the ``timeout`` value to 1200 (20 mins) and set the
       ``reissue_time`` value to perhaps a tenth of the ``timeout`` value
       (120 or 2 mins).  It's nonsensical to set the ``timeout`` value lower
       than the ``reissue_time`` value, as the ticket will never be reissued
       if so.  However, such a configuration is not explicitly prevented.

       Optional.

    ``max_age``

       Default: ``None``.  The max age of the auth_tkt cookie, in
       seconds.  This differs from ``timeout`` inasmuch as ``timeout``
       represents the lifetime of the ticket contained in the cookie,
       while this value represents the lifetime of the cookie itself.
       When this value is set, the cookie's ``Max-Age`` and
       ``Expires`` settings will be set, allowing the auth_tkt cookie
       to last between browser sessions.  It is typically nonsensical
       to set this to a value that is lower than ``timeout`` or
       ``reissue_time``, although it is not explicitly prevented.
       Optional.

    ``path``

       Default: ``/``. The path for which the auth_tkt cookie is valid.
       May be desirable if the application only serves part of a domain.
       Optional.

    ``http_only``

       Default: ``False``. Hide cookie from JavaScript by setting the
       HttpOnly flag. Not honored by all browsers.
       Optional.

    ``wild_domain``

       Default: ``True``. An auth_tkt cookie will be generated for the
       wildcard domain. If your site is hosted as ``example.com`` this
       will make the cookie available for sites underneath ``example.com``
       such as ``www.example.com``.
       Optional.

    ``parent_domain``

       Default: ``False``. An auth_tkt cookie will be generated for the
       parent domain of the current site. For example if your site is
       hosted under ``www.example.com`` a cookie will be generated for
       ``.example.com``. This can be useful if you have multiple sites
       sharing the same domain. This option supercedes the ``wild_domain``
       option.
       Optional.

    ``domain``

       Default: ``None``. If provided the auth_tkt cookie will only be
       set for this domain. This option is not compatible with ``wild_domain``
       and ``parent_domain``.
       Optional.

    ``hashalg``

       Default: ``sha512`` (the literal string).

       Any hash algorithm supported by Python's ``hashlib.new()`` function
       can be used as the ``hashalg``.

       Cookies generated by different instances of AuthTktAuthenticationPolicy
       using different ``hashalg`` options are not compatible. Switching the
       ``hashalg`` will imply that all existing users with a valid cookie will
       be required to re-login.

       Optional.

    ``debug``

        Default: ``False``.  If ``debug`` is ``True``, log messages to the
        Pyramid debug logger about the results of various authentication
        steps.  The output from debugging is useful for reporting to maillist
        or IRC channels when asking for support.

    ``samesite``

        Default: ``'Lax'``.  The 'samesite' option of the session cookie. Set
        the value to the string ``'None'`` to turn off the samesite option.

    .. versionchanged:: 1.4

       Added the ``hashalg`` option, defaulting to ``sha512``.

    .. versionchanged:: 1.5

       Added the ``domain`` option.

       Added the ``parent_domain`` option.

    .. versionchanged:: 1.10

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

    Objects of this class implement the interface described by
    :class:`pyramid.interfaces.IAuthenticationPolicy`.

    Nr/   F/Tsha512Laxc             C   s6   t ||||||||
|	|||||d| _|| _|| _d S )N)cookie_namesecure
include_iptimeoutreissue_timemax_age	http_onlypathwild_domainhashalgparent_domaindomainsamesite)AuthTktCookieHelpercookier&   r   )r   secretr&   rB   rC   rD   rE   rF   rG   rI   rH   rJ   r   rK   rL   rM   rN   r    r    r!   r1   S  s"    
z$AuthTktAuthenticationPolicy.__init__c             C   s   | j |}|r|d S dS )z+ The userid key within the auth_tkt cookie.r'   N)rP   identify)r   r   resultr    r    r!   r%   y  s    z2AuthTktAuthenticationPolicy.unauthenticated_useridc             K   s   | j j||f|S )zAccepts the following kw args: ``max_age=<int-seconds>,
        ``tokens=<sequence-of-ascii-strings>``.

        Return a list of headers which will set appropriate cookies on
        the response.

        )rP   r8   )r   r   r'   r9   r    r    r!   r8     s    z$AuthTktAuthenticationPolicy.rememberc             C   s   | j |S )z9 A list of headers which will delete appropriate cookies.)rP   r:   )r   r   r    r    r!   r:     s    z"AuthTktAuthenticationPolicy.forget)Nr/   FFNNNr?   FTFr@   FNrA   )r   r   r,   r-   r1   r%   r8   r:   r    r    r    r!   r>     s(    $              

r>   c             C   s   t t|  ddS )N   
    )base64	b64encoder   stripreplace)vr    r    r!   rW     s    rW   c             C   s   t t| S )N)rV   	b64decoder   )rZ   r    r    r!   r[     s    r[   c               @   s*   e Zd ZdZddd	Zd
d Zdd ZdS )
AuthTicketa  
    This class represents an authentication token.  You must pass in
    the shared secret, the userid, and the IP address.  Optionally you
    can include tokens (a list of strings, representing role names),
    'user_data', which is arbitrary data available for your own use in
    later scripts.  Lastly, you can override the cookie name and
    timestamp.

    Once you provide all the arguments, use .cookie_value() to
    generate the appropriate authentication ticket.

    Usage::

        token = AuthTicket('sharedsecret', 'username',
            os.environ['REMOTE_ADDR'], tokens=['admin'])
        val = token.cookie_value()

    r     Nr/   Fmd5c
       
      C   sT   || _ || _|| _d|| _|| _|d kr8t | _n|| _|| _|| _	|	| _
d S )N,)rQ   r'   ipjointokens	user_datatime_modtimerB   rC   rK   )
r   rQ   r'   r`   rb   rc   re   rB   rC   rK   r    r    r!   r1     s    zAuthTicket.__init__c             C   s"   t | j| j| j| j| j| j| jS )N)calculate_digestr`   re   rQ   r'   rb   rc   rK   )r   r    r    r!   digest  s    zAuthTicket.digestc             C   s@   d|   t| jt| jf }| jr2|| jd 7 }|| j7 }|S )Nz	%s%08x%s!!)rg   intre   r   r'   rb   rc   )r   rZ   r    r    r!   cookie_value  s
    
zAuthTicket.cookie_value)r    r]   Nr/   Fr^   )r   r   r,   r-   r1   rg   rj   r    r    r    r!   r\     s        
r\   c               @   s   e Zd ZdZdddZdS )	BadTicketz
    Exception raised when a ticket can't be parsed.  If we get far enough to
    determine what the expected digest should have been, expected is set.
    This should not be shown by default, but can be useful for debugging.
    Nc             C   s   || _ t| | d S )N)expected	Exceptionr1   )r   r   rl   r    r    r!   r1     s    zBadTicket.__init__)N)r   r   r,   r-   r1   r    r    r    r!   rk     s   rk   r^   c          
   C   s"  t |d}t|jd }|d| }yt|||d  d}W n. tk
rr } ztd| W dd}~X Y nX y ||d d dd\}}	W n tk
r   td	Y nX t	|}d|	kr|	dd\}
}nd
}
|	}t
||| ||
||}t||rtd||fd|
d}
|||
|fS )z
    Parse the ticket, returning (timestamp, userid, tokens, user_data).

    If the ticket cannot be parsed, a ``BadTicket`` exception will be raised
    with an explanation.
    "   N      z"Timestamp is not a hex integer: %srh      zuserid is not followed by !r]   zDigest signature is not correct)rl   r_   )r   rX   hashlibnewdigest_sizeri   
ValueErrorrk   splitr   rf   r   )rQ   ticketr`   rK   ru   rg   	timestamper'   datarb   rc   rl   r    r    r!   parse_ticket  s.     
r|   c             C   s   t |d}t |d}t |d}t |d}t|}d| krT| tt| }t |}n
t| |}||| | d | d |  | }	t|}
|
t |	|  |
 S )Nzutf-8:    )r   rs   rt   strri   encode_ip_timestampupdate	hexdigest)r`   ry   rQ   r'   rb   rc   rK   Zhash_objZip_timestamprg   Z	hash_obj2r    r    r!   rf     s    







rf   c          	   C   sh   d tttt| d}t|}|d@ d? |d@ d? |d@ d? |d	@ f}d tt|}t|| S )
Nr]   r   l      ~    i   rq   i   rp      )ra   mapchrri   rw   r   )r`   ry   Zip_charsttsZts_charsr    r    r!   r   +  s    



r   c               @   s   e Zd ZdZeeZeZeZdZe	dd dd dd dZ
e	defed	d
d feddd fiZdddZdddZdd Zdd Zd ddZdS )!rO   a  
    A helper class for security policies that obtains data from an "auth
    ticket" cookie.

    Constructor Arguments

    ``secret``

       The secret (a string) used for auth_tkt cookie signing.  This value
       should be unique across all values provided to Pyramid for various
       subsystem secrets (see :ref:`admonishment_against_secret_sharing`).
       Required.

    ``cookie_name``

       Default: ``auth_tkt``.  The cookie name used
       (string).  Optional.

    ``secure``

       Default: ``False``.  Only send the cookie back over a secure
       conn.  Optional.

    ``include_ip``

       Default: ``False``.  Make the requesting IP address part of
       the authentication data in the cookie.  Optional.

       For IPv6 this option is not recommended. The ``mod_auth_tkt``
       specification does not specify how to handle IPv6 addresses, so using
       this option in combination with IPv6 addresses may cause an
       incompatible cookie. It ties the authentication ticket to that
       individual's IPv6 address.

    ``timeout``

       Default: ``None``.  Maximum number of seconds which a newly
       issued ticket will be considered valid.  After this amount of
       time, the ticket will expire (effectively logging the user
       out).  If this value is ``None``, the ticket never expires.
       Optional.

    ``reissue_time``

       Default: ``None``.  If this parameter is set, it represents the number
       of seconds that must pass before an authentication token cookie is
       automatically reissued as the result of a request which requires
       authentication.  The duration is measured as the number of seconds
       since the last auth_tkt cookie was issued and 'now'.  If this value is
       ``0``, a new ticket cookie will be reissued on every request which
       requires authentication.

       A good rule of thumb: if you want auto-expired cookies based on
       inactivity: set the ``timeout`` value to 1200 (20 mins) and set the
       ``reissue_time`` value to perhaps a tenth of the ``timeout`` value
       (120 or 2 mins).  It's nonsensical to set the ``timeout`` value lower
       than the ``reissue_time`` value, as the ticket will never be reissued
       if so.  However, such a configuration is not explicitly prevented.

       Optional.

    ``max_age``

       Default: ``None``.  The max age of the auth_tkt cookie, in
       seconds.  This differs from ``timeout`` inasmuch as ``timeout``
       represents the lifetime of the ticket contained in the cookie,
       while this value represents the lifetime of the cookie itself.
       When this value is set, the cookie's ``Max-Age`` and
       ``Expires`` settings will be set, allowing the auth_tkt cookie
       to last between browser sessions.  It is typically nonsensical
       to set this to a value that is lower than ``timeout`` or
       ``reissue_time``, although it is not explicitly prevented.
       Optional.

    ``path``

       Default: ``/``. The path for which the auth_tkt cookie is valid.
       May be desirable if the application only serves part of a domain.
       Optional.

    ``http_only``

       Default: ``False``. Hide cookie from JavaScript by setting the
       HttpOnly flag. Not honored by all browsers.
       Optional.

    ``wild_domain``

       Default: ``True``. An auth_tkt cookie will be generated for the
       wildcard domain. If your site is hosted as ``example.com`` this
       will make the cookie available for sites underneath ``example.com``
       such as ``www.example.com``.
       Optional.

    ``parent_domain``

       Default: ``False``. An auth_tkt cookie will be generated for the
       parent domain of the current site. For example if your site is
       hosted under ``www.example.com`` a cookie will be generated for
       ``.example.com``. This can be useful if you have multiple sites
       sharing the same domain. This option supercedes the ``wild_domain``
       option.
       Optional.

    ``domain``

       Default: ``None``. If provided the auth_tkt cookie will only be
       set for this domain. This option is not compatible with ``wild_domain``
       and ``parent_domain``.
       Optional.

    ``hashalg``

       Default: ``sha512`` (the literal string).

       Any hash algorithm supported by Python's ``hashlib.new()`` function
       can be used as the ``hashalg``.

       Cookies generated by different instances of AuthTktAuthenticationPolicy
       using different ``hashalg`` options are not compatible. Switching the
       ``hashalg`` will imply that all existing users with a valid cookie will
       be required to re-login.

       Optional.

    ``debug``

        Default: ``False``.  If ``debug`` is ``True``, log messages to the
        Pyramid debug logger about the results of various authentication
        steps.  The output from debugging is useful for reporting to maillist
        or IRC channels when asking for support. Optional.

    ``samesite``

        Default: ``'Lax'``.  The 'samesite' option of the session cookie. Set
        the value to ``None`` to turn off the samesite option. Optional.

    .. versionchanged:: 2.0

        The default ``hashalg`` was changed from ``md5`` to ``sha512``.

    Nc             C   s   t | d S )Nr   )r   )xr    r    r!   <lambda>  rU   zAuthTktCookieHelper.<lambda>c             C   s   t t| d S )Nr   )r   r[   )r   r    r    r!   r     rU   c             C   s   t | S )N)r[   )r   r    r    r!   r     rU   )ri   unicode
b64unicodeb64strri   r   c             C   s   t t| d S )Nr   )rW   r   )r   r    r    r!   r     rU   r   c             C   s   t | S )N)rW   )r   r    r    r!   r     rU   r/   Fr?   Tr@   rA   c          	   C   s   t |||||	t |d| _|| _|| _|| _|| _|d kr>|nt|| _|d krT|nt|| _	|d krj|nt|| _
|
| _|| _|| _|| _d S )N)rB   rC   rG   httponlyrI   
serializerrN   )r   r   cookie_profilerQ   rB   rC   rD   ri   rE   rF   rG   rJ   rL   rM   rK   )r   rQ   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   r    r    r!   r1     s&    
zAuthTktCookieHelper.__init__c       	      C   s   | j r| j }n<|j }| jr:|ddkr:|ddd }n| jrF|}nd }| |}d|gi}|d k	rn||d< |j|f|}|S )Nr   rr   domainsrG   )rM   rL   countrw   rJ   r   Zget_headers)	r   r   valuerG   rM   Z
cur_domainZprofiler9   headersr    r    r!   _get_cookies  s    

z AuthTktCookieHelper._get_cookiesc                s  |j }|j| j}|dkr dS | jr0|d }nd}y | | j||| j\}}}}W n | jk
rj   dS X | j	}	|	dkrt
 }	| jr|| j |	k rdS d}
|d}xDtd|D ]6}||
r|t|
d }| j|}|r||}qW | jdk	}|rXt|dsX|	| | jkrXttd|}| j||| j|d  fdd	}|| d
|_||d< ||d< d|d< i }||d< ||d< ||d< ||d< |S )zxReturn a dictionary with authentication information, or ``None``
        if no valid auth_tkt is attached to ``request``NREMOTE_ADDRz0.0.0.0zuserid_type:|_authtkt_reissued)rG   rb   c                s0   t | ds,x  D ]\}}|j||f qW d S )N_authtkt_reissue_revoked)hasattrZ
headerlistr)   )r   responsekrZ   )r   r    r!   reissue_authtktI  s    
z5AuthTktCookieHelper.identify.<locals>.reissue_authtktTZREMOTE_USER_TOKENSZREMOTE_USER_DATArP   Z	AUTH_TYPEry   r'   rb   Zuserdata)r2   cookiesr3   rB   rD   r|   rQ   rK   rk   nowrd   re   rE   rw   filter
startswithlenuserid_type_decodersrF   r   listr8   rG   Zadd_response_callbackr   )r   r   r2   rP   remote_addrry   r'   rb   rc   r   Zuserid_typenameZuser_data_infoZdatumZuserid_typedecoderZreissuer   r7   r    )r   r!   rR     sV    




zAuthTktCookieHelper.identifyc             C   s   d|_ | |dS )zReturn a set of expires Set-Cookie headers, which will destroy
        any existing auth_tkt cookie when attached to a responseTN)r   r   )r   r   r    r    r!   r:   \  s    zAuthTktCookieHelper.forgetr    c          
   C   sZ  |dkr| j nt|}|j}| jr,|d }nd}d}| jt|}|rR|\}	}
n.td	t|t
 | jt\}	}
t|}|
|}d|	 }g }xr|D ]j}t|tryt|}W n" tk
r   td|f Y nX t|trt|std|f || qW t|}t|dr"d	|_| j| j||||| j| j| jd
}| }| |||S )a  Return a set of Set-Cookie headers; when set into a response,
        these headers will represent a valid authentication ticket.

        ``max_age``
          The max age of the auth_tkt cookie, in seconds.  When this value is
          set, the cookie's ``Max-Age`` and ``Expires`` settings will be set,
          allowing the auth_tkt cookie to last between browser sessions.  If
          this value is ``None``, the ``max_age`` value provided to the
          helper itself will be used as the ``max_age`` value.  Default:
          ``None``.

        ``tokens``
          A sequence of strings that will be placed into the auth_tkt tokens
          field.  Each string in the sequence must be of the Python ``str``
          type and must match the regex ``^[A-Za-z][A-Za-z0-9+_-]*$``.
          Tokens are available in the returned identity when an auth_tkt is
          found in the request and unpacked.  Default: ``()``.
        Nr   z0.0.0.0r]   zuserid is of type {}, and is not supported by the AuthTktAuthenticationPolicy. Explicitly converting to string and storing as base64. Subsequent requests will receive a string as the userid, it will not be decoded back to the type provided.zuserid_type:%szInvalid token %rr   T)rb   rc   rB   rC   rK   )rG   ri   r2   rD   userid_type_encodersr3   typewarningswarnformatRuntimeWarningr   
isinstancer   UnicodeEncodeErrorrv   VALID_TOKENmatchr)   tupler   r   r\   rQ   rB   rC   rK   rj   r   )r   r   r'   rG   rb   r2   r   rc   Zencoding_dataencodingencoderZ
new_tokenstokenrx   rj   r    r    r!   r8   b  sR    




zAuthTktCookieHelper.remember)r/   FFNNNFr?   Tr@   FNrA   )N)Nr    )r   r   r,   r-   staticmethodr|   r\   rk   r   ri   r   r   bytesr   r1   r   rR   r:   r8   r    r    r    r!   rO   8  s<                

DrO   c               @   s2   e Zd ZdZdddZdd Zd	d
 Zdd ZdS )SessionAuthenticationPolicya0  A :app:`Pyramid` authentication policy which gets its data from the
    configured :term:`session`.  For this authentication policy to work, you
    will have to follow the instructions in the :ref:`sessions_chapter` to
    configure a :term:`session factory`.

    Constructor Arguments

    ``prefix``

       A prefix used when storing the authentication parameters in the
       session. Defaults to 'auth.'. Optional.

    ``callback``

       Default: ``None``.  A callback passed the userid and the
       request, expected to return ``None`` if the userid doesn't
       exist or a sequence of principal identifiers (possibly empty) if
       the user does exist.  If ``callback`` is ``None``, the userid
       will be assumed to exist with no principals.  Optional.

    ``debug``

        Default: ``False``.  If ``debug`` is ``True``, log messages to the
        Pyramid debug logger about the results of various authentication
        steps.  The output from debugging is useful for reporting to maillist
        or IRC channels when asking for support.

    auth.NFc             C   s   || _ || _t|| _d S )N)r&   r   SessionAuthenticationHelperhelper)r   prefixr&   r   r    r    r!   r1     s    z$SessionAuthenticationPolicy.__init__c             K   s   | j j||f|S )z Store a userid in the session.)r   r8   )r   r   r'   r9   r    r    r!   r8     s    z$SessionAuthenticationPolicy.rememberc             C   s   | j |S )z+ Remove the stored userid from the session.)r   r:   )r   r   r    r    r!   r:     s    z"SessionAuthenticationPolicy.forgetc             C   s   | j |S )N)r   r$   )r   r   r    r    r!   r%     s    z2SessionAuthenticationPolicy.unauthenticated_userid)r   NF)r   r   r,   r-   r1   r8   r:   r%   r    r    r    r!   r     s
   
r   c               @   s2   e Zd ZdZdddZdd Zdd Zd	d
 ZdS )r   a  A helper for use with a :term:`security policy` which stores user data
    in the configured :term:`session`.

    Constructor Arguments

    ``prefix``

       A prefix used when storing the authentication parameters in the
       session. Defaults to 'auth.'. Optional.

    auth.c             C   s   |d | _ d S )Nr'   )
userid_key)r   r   r    r    r!   r1     s    z$SessionAuthenticationHelper.__init__c             K   s   ||j | j< g S )z Store a userid in the session.)sessionr   )r   r   r'   r9   r    r    r!   r8     s    z$SessionAuthenticationHelper.rememberc             K   s   | j |jkr|j| j = g S )z+ Remove the stored userid from the session.)r   r   )r   r   r9   r    r    r!   r:     s    
z"SessionAuthenticationHelper.forgetc             C   s   |j | jS )z Return the stored userid.)r   r3   r   )r   r   r    r    r!   r$     s    z0SessionAuthenticationHelper.authenticated_useridN)r   )r   r   r,   r-   r1   r8   r:   r$   r    r    r    r!   r     s
   
r   c               @   s:   e Zd ZdZdddZdd Zdd	 Zd
d Zdd ZdS )BasicAuthAuthenticationPolicya  A :app:`Pyramid` authentication policy which uses HTTP standard basic
    authentication protocol to authenticate users.  To use this policy you will
    need to provide a callback which checks the supplied user credentials
    against your source of login data.

    Constructor Arguments

    ``check``

       A callback function passed a username, password and request, in that
       order as positional arguments.  Expected to return ``None`` if the
       userid doesn't exist or a sequence of principal identifiers (possibly
       empty) if the user does exist.

    ``realm``

       Default: ``"Realm"``.  The Basic Auth Realm string.  Usually displayed
       to the user by the browser in the login dialog.

    ``debug``

        Default: ``False``.  If ``debug`` is ``True``, log messages to the
        Pyramid debug logger about the results of various authentication
        steps.  The output from debugging is useful for reporting to maillist
        or IRC channels when asking for support.

    **Issuing a challenge**

    Regular browsers will not send username/password credentials unless they
    first receive a challenge from the server.  The following recipe will
    register a view that will send a Basic Auth challenge to the user whenever
    there is an attempt to call a view which results in a Forbidden response::

        from pyramid.httpexceptions import HTTPUnauthorized
        from pyramid.security import forget
        from pyramid.view import forbidden_view_config

        @forbidden_view_config()
        def forbidden_view(request):
            if request.authenticated_userid is None:
                response = HTTPUnauthorized()
                response.headers.update(forget(request))
                return response
            return HTTPForbidden()
    RealmFc             C   s   || _ || _|| _d S )N)checkrealmr   )r   r   r   r   r    r    r!   r1   1  s    z&BasicAuthAuthenticationPolicy.__init__c             C   s   t |}|r|jS dS )z= The userid parsed from the ``Authorization`` request header.N)extract_http_basic_credentialsusername)r   r   credentialsr    r    r!   r%   6  s    z4BasicAuthAuthenticationPolicy.unauthenticated_useridc             K   s   g S )zA no-op. Basic authentication does not provide a protocol for
        remembering the user. Credentials are sent on every request.

        r    )r   r   r'   r9   r    r    r!   r8   <  s    z&BasicAuthAuthenticationPolicy.rememberc             C   s   dd| j  fgS )zsReturns challenge headers. This should be attached to a response
        to indicate that credentials are required.zWWW-AuthenticatezBasic realm="%s")r   )r   r   r    r    r!   r:   C  s    z$BasicAuthAuthenticationPolicy.forgetc             C   s&   t |}|r"|\}}| |||S d S )N)r   r   )r   r   r   r   passwordr    r    r!   r&   H  s    z&BasicAuthAuthenticationPolicy.callbackN)r   F)	r   r   r,   r-   r1   r%   r8   r:   r&   r    r    r    r!   r     s   .
r   HTTPBasicCredentialsr   r   c          	   C   s   | j d}|sdS y|dd\}}W n tk
r<   dS X | dkrNdS yt| }W n ttj	fk
rx   dS X y|
d}W n tk
r   |
d}Y nX y|dd\}}W n tk
r   dS X t||S )	zA helper function for extraction of HTTP Basic credentials
    from a given :term:`request`.

    Returns a :class:`.HTTPBasicCredentials` 2-tuple with ``username`` and
    ``password`` attributes or ``None`` if no credentials could be found.

    AuthorizationN rr   basiczutf-8zlatin-1r}   )r   r3   rw   rv   lowerr[   rX   	TypeErrorbinasciiErrordecodeUnicodeDecodeErrorr   )r   authorizationZauthmethauthZ	authbytesr   r   r    r    r!   r   X  s,    r   )r^   )r^   )3rV   r   codecsr   r   collectionsr   rs   rere   rd   urllib.parser   r   r   Zwebob.cookiesr   Zzope.interfacer   Zpyramid.authorizationr	   r
   Zpyramid.interfacesr   r   Zpyramid.utilr   r   r   r   r   compiler   r   r.   r;   r>   rW   r[   r\   rm   rk   r|   rf   r   rO   r   r   r   r   r   r    r    r    r!   <module>   sT   
  E4 `A
,
  {/ Q