ó
¸9—^c           @   sÿ  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	 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 d  d l m Z d  d	 l m Z d  d
 l m Z d  d l m Z e d' k r d „  Z n	 d „  Z d e f d „  ƒ  YZ  d e  f d „  ƒ  YZ! d e f d „  ƒ  YZ" d e  f d „  ƒ  YZ# d e# f d „  ƒ  YZ$ d e  f d „  ƒ  YZ% d e  f d „  ƒ  YZ& d e  f d  „  ƒ  YZ' d! e  f d" „  ƒ  YZ( d# e f d$ „  ƒ  YZ) d% e! f d& „  ƒ  YZ* d S((   iÿÿÿÿN(   t   VERSION(   t   settings(   t   REDIRECT_FIELD_NAME(   t   redirect_to_logint   logout_then_login(   t   ImproperlyConfiguredt   PermissionDenied(   t   HttpResponseRedirectt   HttpResponsePermanentRedirectt   Http404t   HttpResponset   StreamingHttpResponse(   t   resolve_url(   t   six(   t
   force_text(   t   nowi   i
   i    c         C   s   |  j  S(   N(   t   is_authenticated(   t   user(    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyt   <lambda>   t    c         C   s
   |  j  ƒ  S(   N(   R   (   R   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR      R   t   AccessMixinc           B   sM   e  Z d  Z d Z e Z e Z e Z	 d „  Z
 d „  Z d „  Z d d „ Z RS(   s\   
    'Abstract' mixin that gives access mixins the same customizable
    functionality.
    c         C   s@   |  j  p t j } | s6 t d j |  j j ƒ ƒ ‚ n  t | ƒ S(   sB   
        Override this method to customize the login_url.
        sK   Define {0}.login_url or settings.LOGIN_URL or override {0}.get_login_url().(   t	   login_urlR   t	   LOGIN_URLR   t   formatt	   __class__t   __name__R   (   t   selfR   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyt   get_login_url#   s    c         C   s4   |  j  d k r- t d j |  j j ƒ ƒ ‚ n  |  j  S(   sL   
        Override this method to customize the redirect_field_name.
        sq   {0} is missing the redirect_field_name. Define {0}.redirect_field_name or override {0}.get_redirect_field_name().N(   t   redirect_field_namet   NoneR   R   R   R   (   R   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyt   get_redirect_field_name/   s
    c         C   s¯   |  j  r¢ |  j r/ t | j ƒ r/ |  j | ƒ St j |  j  ƒ r_ t |  j  t ƒ r_ |  j  ‚ n  t	 |  j  ƒ r™ |  j  | ƒ } t
 | t t f ƒ r™ | Sn  t ‚ n  |  j | ƒ S(   N(   t   raise_exceptiont   redirect_unauthenticated_userst   _is_authenticatedR   t   no_permissions_failt   inspectt   isclasst
   issubclasst	   Exceptiont   callablet
   isinstanceR
   R   R   (   R   t   requestt   ret(    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyt   handle_no_permission;   s    			c         C   s"   t  | j ƒ  |  j ƒ  |  j ƒ  ƒ S(   s·   
        Called when the user has no permissions and no exception was raised.
        This should only return a valid HTTP response.

        By default we redirect to login.
        (   R   t   get_full_pathR   R   (   R   R)   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR"   L   s    	N(   R   t
   __module__t   __doc__R   R   t   FalseR   R   R   R    R   R   R+   R"   (    (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR      s   			t   LoginRequiredMixinc           B   s   e  Z d  Z d „  Z RS(   sò   
    View mixin which verifies that the user is authenticated.

    NOTE:
        This should be the left-most mixin of a view, except when
        combined with CsrfExemptMixin - which in that case should
        be the left-most mixin.
    c         O   s8   t  | j ƒ s |  j | ƒ St t |  ƒ j | | | Ž S(   N(   R!   R   R+   t   superR0   t   dispatch(   R   R)   t   argst   kwargs(    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR2   a   s    (   R   R-   R.   R2   (    (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR0   X   s   t   AnonymousRequiredMixinc           B   s)   e  Z d  Z e j Z d „  Z d „  Z RS(   s±  
    View mixin which redirects to a specified URL if authenticated.
    Can be useful if you wanted to prevent authenticated users from
    accessing signup pages etc.

    NOTE:
        This should be the left-most mixin of a view.

    Example Usage

        class SomeView(AnonymousRequiredMixin, ListView):
            ...
            # required
            authenticated_redirect_url = "/accounts/profile/"
            ...
    c         O   s;   t  | j ƒ r t |  j ƒ  ƒ St t |  ƒ j | | | Ž S(   N(   R!   R   R   t   get_authenticated_redirect_urlR1   R5   R2   (   R   R)   R3   R4   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR2   |   s    c         C   s4   |  j  s' t d j |  j j ƒ ƒ ‚ n  t |  j  ƒ S(   s1    Return the reversed authenticated redirect url. s˜   {0} is missing an authenticated_redirect_url url to redirect to. Define {0}.authenticated_redirect_url or override {0}.get_authenticated_redirect_url().(   t   authenticated_redirect_urlR   R   R   R   R   (   R   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR6   ‚   s
    	(   R   R-   R.   R   t   LOGIN_REDIRECT_URLR7   R2   R6   (    (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR5   i   s   		t   PermissionRequiredMixinc           B   s8   e  Z d  Z d Z e Z d d „ Z d „  Z d „  Z	 RS(   s‹  
    View mixin which verifies that the logged in user has the specified
    permission.

    Class Settings
    `permission_required` - the permission to check for.
    `login_url` - the login url of site
    `redirect_field_name` - defaults to "next"
    `raise_exception` - defaults to False - raise 403 if set to True

    Example Usage

        class SomeView(PermissionRequiredMixin, ListView):
            ...
            # required
            permission_required = "app.permission"

            # optional
            login_url = "/signup/"
            redirect_field_name = "hollaback"
            raise_exception = True
            ...
    c         C   s4   |  j  d k r- t d j |  j j ƒ ƒ ‚ n  |  j  S(   s†   
        Get the required permissions and return them.

        Override this to allow for custom permission_required values.
        s;   {0} requires the "permission_required" attribute to be set.N(   t   permission_requiredR   R   R   R   R   (   R   R)   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyt   get_permission_required©   s
    c         C   sÇ   |  j  | ƒ } t } |  j r¨ t |  d ƒ r` |  j d k	 r` | j j |  j  | ƒ |  j ƒ } qÃ t |  d ƒ rÃ t |  j	 ƒ rÃ | j j |  j  | ƒ |  j	 ƒ  ƒ } qÃ n | j j |  j  | ƒ ƒ } | S(   sA   
        Returns whether or not the user has permissions
        t   objectt
   get_objectN(
   R;   R/   t   object_level_permissionst   hasattrR<   R   R   t   has_permR'   R=   (   R   R)   t   permst   has_permission(    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyt   check_permissions¸   s    	$*c         O   s>   |  j  | ƒ } | s" |  j | ƒ St t |  ƒ j | | | Ž S(   s^   
        Check to see if the user in the request has the required
        permission.
        (   RC   R+   R1   R9   R2   (   R   R)   R3   R4   RB   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR2   È   s
    N(
   R   R-   R.   R   R:   R/   R>   R;   RC   R2   (    (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR9   Ž   s   	t    MultiplePermissionsRequiredMixinc           B   sP   e  Z d  Z d Z d d „ Z d „  Z d „  Z d d d „ Z d d d „ Z	 RS(   s±  
    View mixin which allows you to specify two types of permission
    requirements. The `permissions` attribute must be a dict which
    specifies two keys, `all` and `any`. You can use either one on
    its own or combine them. The value of each key is required to be a
    list or tuple of permissions. The standard Django permissions
    style is not strictly enforced. If you have created your own
    permissions in a different format, they should still work.

    By specifying the `all` key, the user must have all of
    the permissions in the passed in list.

    By specifying The `any` key , the user must have ONE of the set
    permissions in the list.

    Class Settings
        `permissions` - This is required to be a dict with one or both
            keys of `all` and/or `any` containing a list or tuple of
            permissions.
        `login_url` - the login url of site
        `redirect_field_name` - defaults to "next"
        `raise_exception` - defaults to False - raise 403 if set to True

    Example Usage
        class SomeView(MultiplePermissionsRequiredMixin, ListView):
            ...
            #required
            permissions = {
                "all": ("blog.add_post", "blog.change_post"),
                "any": ("blog.delete_post", "user.change_user")
            }

            #optional
            login_url = "/signup/"
            redirect_field_name = "hollaback"
            raise_exception = True
    c         C   s   |  j  ƒ  |  j S(   N(   t   _check_permissions_attrt   permissions(   R   R)   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR;   þ   s    
c         C   sÒ   |  j  | ƒ } | j d ƒ p! d  } | j d ƒ p6 d  } |  j | | ƒ |  j d | ƒ |  j d | ƒ | rˆ | j j | ƒ sˆ t Sn  | rÎ t } x* | D]" } | j j | ƒ r› t	 } Pq› q› W| sÎ t Sn  t	 S(   Nt   allt   any(
   R;   t   getR   t   _check_permissions_keys_sett   _check_perms_keysR   t	   has_permsR/   R@   t   True(   R   R)   RF   t	   perms_allt	   perms_anyt   has_one_permt   perm(    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyRC     s$    c         C   sD   |  j  d k s" t |  j  t ƒ r@ t d j |  j j ƒ ƒ ‚ n  d S(   sK   
        Check permissions attribute is set and that it is a dict.
        s=   {0} requires the "permissions" attribute to be set as a dict.N(   RF   R   R(   t   dictR   R   R   R   (   R   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyRE     s    "c         C   s:   | d k r6 | d k r6 t d j |  j j ƒ ƒ ‚ n  d S(   sÚ   
        Check to make sure the keys `any` or `all` are not both blank.
        If both are blank either an empty dict came in or the wrong keys
        came in. Both are invalid and should raise an exception.
        sb   {0} requires the "permissions" attribute to be set to a dict and the "any" or "all" key to be set.N(   R   R   R   R   R   (   R   RN   RO   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyRJ   &  s    c         C   sA   | r= t  | t t f ƒ r= t d j |  j j | ƒ ƒ ‚ n  d S(   s‚   
        If the permissions list/tuple passed in is set, check to make
        sure that it is of the type list or tuple.
        sA   {0} requires the permisions dict {1} value to be a list or tuple.N(   R(   t   listt   tupleR   R   R   R   (   R   t   keyRA   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyRK   2  s    N(
   R   R-   R.   R   RF   R;   RC   RE   RJ   RK   (    (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyRD   Ö   s   %			t   GroupRequiredMixinc           B   s)   e  Z d Z d  „  Z d „  Z d „  Z RS(   c         C   s~   |  j  d  k s/ t |  j  t t f t j ƒ rM t d j |  j	 j
 ƒ ƒ ‚ n  t |  j  t t f ƒ sw |  j  f |  _  n  |  j  S(   Nsw   {0} requires the "group_required" attribute to be set and be one of the following types: string, unicode, list or tuple(   t   group_requiredR   R(   RS   RT   R   t   string_typesR   R   R   R   (   R   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyt   get_group_required@  s    	c         C   sJ   |  j  j j r t S|  j  j j j d d t ƒ} t | ƒ j t | ƒ ƒ S(   s    Check required group(s) t   namet   flat(   R)   R   t   is_superuserRM   t   groupst   values_listt   sett   intersection(   R   R]   t   user_groups(    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyt   check_membershipN  s    c         O   se   | |  _  t } t | j ƒ r6 |  j |  j ƒ  ƒ } n  | sI |  j | ƒ St t |  ƒ j	 | | | Ž S(   N(
   R)   R/   R!   R   Rb   RY   R+   R1   RV   R2   (   R   R)   R3   R4   t   in_group(    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR2   U  s    	N(   R   R-   R   RW   RY   Rb   R2   (    (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyRV   =  s   		t   UserPassesTestMixinc           B   s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   s±  
    CBV Mixin allows you to define test that every user should pass
    to get access into view.

    Class Settings
        `test_func` - This is required to be a method that takes user
            instance and return True or False after checking conditions.
        `login_url` - the login url of site
        `redirect_field_name` - defaults to "next"
        `raise_exception` - defaults to False - raise 403 if set to True
    c         C   s   t  d j |  j j ƒ ƒ ‚ d  S(   NsL   {0} is missing implementation of the test_func method. You should write one.(   t   NotImplementedErrorR   R   R   (   R   R   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyt	   test_funco  s    c         C   s   t  |  d ƒ S(   NRf   (   t   getattr(   R   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyt   get_test_funcu  s    c         O   sD   |  j  ƒ  | j ƒ } | s( |  j | ƒ St t |  ƒ j | | | Ž S(   N(   Rh   R   R+   R1   Rd   R2   (   R   R)   R3   R4   t   user_test_result(    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR2   x  s
    (   R   R-   R.   Rf   Rh   R2   (    (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyRd   b  s   		t   SuperuserRequiredMixinc           B   s   e  Z d  Z d „  Z RS(   sM   
    Mixin allows you to require a user with `is_superuser` set to True.
    c         O   s5   | j  j s |  j | ƒ St t |  ƒ j | | | Ž S(   N(   R   R\   R+   R1   Rj   R2   (   R   R)   R3   R4   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR2   †  s    (   R   R-   R.   R2   (    (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyRj   ‚  s   t   StaffuserRequiredMixinc           B   s   e  Z d  Z d „  Z RS(   sI   
    Mixin allows you to require a user with `is_staff` set to True.
    c         O   s5   | j  j s |  j | ƒ St t |  ƒ j | | | Ž S(   N(   R   t   is_staffR+   R1   Rk   R2   (   R   R)   R3   R4   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR2   ’  s    (   R   R-   R.   R2   (    (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyRk   Ž  s   t   SSLRequiredMixinc           B   s&   e  Z d  Z e Z d „  Z d „  Z RS(   sT   
    Simple mixin that allows you to force a view to be accessed
    via https.
    c         O   s{   t  t d t ƒ r. t t |  ƒ j | | | Ž S| j ƒ  s_ |  j rL t ‚ n  t	 |  j
 | ƒ ƒ St t |  ƒ j | | | Ž S(   Nt   DEBUG(   Rg   R   R/   R1   Rm   R2   t	   is_secureR   R	   R   t   _build_https_url(   R   R)   R3   R4   (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR2   ¡  s    		c         C   s(   | j  | j ƒ  ƒ } t j d d | ƒ S(   s+    Get the full url, replace http with https s   ^httpt   https(   t   build_absolute_uriR,   t   ret   sub(   R   R)   t   url(    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyRp   ¯  s    (   R   R-   R.   R/   R   R2   Rp   (    (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyRm   š  s   	t   RecentLoginRequiredMixinc           B   s   e  Z d  Z d Z d „  Z RS(   sO   
    Mixin allows you to require a login to be within a number of seconds.
    i  c         O   sy   t  t |  ƒ j | | | Ž } | j d k ru t j d |  j ƒ } t ƒ  | j j	 | k rn t
 | |  j ƒ  ƒ S| Sn  | S(   NiÈ   t   seconds(   R1   Rv   R2   t   status_codet   datetimet	   timedeltat   max_last_login_deltaR   R   t
   last_loginR   R   (   R   R)   R3   R4   t   respt   delta(    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyR2   »  s    (   R   R-   R.   R{   R2   (    (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyRv   µ  s   (   i   i
   i    (+   R#   Ry   Rs   t   djangoR    t   DJANGO_VERSIONt   django.confR   t   django.contrib.authR   t   django.contrib.auth.viewsR   R   t   django.core.exceptionsR   R   t   django.httpR   R   R	   R
   R   t   django.shortcutsR   t   django.utilsR   t   django.utils.encodingR   t   django.utils.timezoneR   R!   R<   R   R0   R5   R9   RD   RV   Rd   Rj   Rk   Rm   Rv   (    (    (    s6   /tmp/pip-unpacked-wheel-20cZHT/braces/views/_access.pyt   <module>   s4   (	?%Hg% 