
    htf*                         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  e       Zd dl
mZmZ d dlmZ  G d d	      Z G d
 d      Z G d d      Z G d d      Zy)    )Iterable)settings)login_requiredREDIRECT_FIELD_NAME)ImproperlyConfiguredPermissionDenied)get_user_obj_perms_model)get_40x_or_Noneget_anonymous_user)get_objects_for_userc                   >     e Zd ZdZeZej                  Z fdZ	 xZ
S )LoginRequiredMixinay  
    A login required mixin for use with class based views. This Class is a
    light wrapper around the `login_required` decorator and hence function
    parameters are just attributes defined on the class.

    Due to parent class order traversal this mixin must be added as the left
    most mixin of a view.

    The mixin has exactly the same flow as `login_required` decorator:

        If the user isn't logged in, redirect to ``settings.LOGIN_URL``, passing
        the current absolute path in the query string. Example:
        ``/accounts/login/?next=/polls/3/``.

        If the user is logged in, execute the view normally. The view code is
        free to assume the user is logged in.

    **Class Settings**

    ``LoginRequiredMixin.redirect_field_name``

        *Default*: ``'next'``

    ``LoginRequiredMixin.login_url``

        *Default*: ``settings.LOGIN_URL``

    c                 v      t        | j                  | j                        t        |         |g|i |S )N)redirect_field_name	login_url)r   r   r   superdispatch)selfrequestargskwargs	__class__s       Y/var/www/html/software/conda/envs/higlass/lib/python3.12/site-packages/guardian/mixins.pyr   zLoginRequiredMixin.dispatch,   sS    
 8~$2J2J(,8G
 $ $ #$ 	$    )__name__
__module____qualname____doc__r   r   r   	LOGIN_URLr   r   __classcell__r   s   @r   r   r      s%    8 .""I$ $r   r   c                   r     e Zd ZdZej
                  ZdZeZ	dZ
dZdZdZdZd	dZd Zd Zd	dZ fdZ xZS )
PermissionRequiredMixina  
    A view mixin that verifies if the current logged in user has the specified
    permission by wrapping the ``request.user.has_perm(..)`` method.

    If a `get_object()` method is defined either manually or by including
    another mixin (for example ``SingleObjectMixin``) or ``self.object`` is
    defined then the permission will be tested against that specific instance,
    alternatively you can specify `get_permission_object()` method if ``self.object``
    or `get_object()` does not return the object against you want to test permission

    .. note:
       Testing of a permission against a specific object instance requires an
       authentication backend that supports. Please see ``django-guardian`` to
       add object level permissions to your project.

    The mixin does the following:

        If the user isn't logged in, redirect to settings.LOGIN_URL, passing
        the current absolute path in the query string. Example:
        /accounts/login/?next=/polls/3/.

        If the `raise_exception` is set to True than rather than redirect to
        login page a `PermissionDenied` (403) is raised.

        If the user is logged in, and passes the permission check than the view
        is executed normally.

    **Example Usage**::

        class SecureView(PermissionRequiredMixin, View):
            ...
            permission_required = 'auth.change_user'
            ...

    **Class Settings**

    ``PermissionRequiredMixin.permission_required``

        *Default*: ``None``, must be set to either a string or list of strings
        in format: *<app_label>.<permission_codename>*.

    ``PermissionRequiredMixin.login_url``

        *Default*: ``settings.LOGIN_URL``

    ``PermissionRequiredMixin.redirect_field_name``

        *Default*: ``'next'``

    ``PermissionRequiredMixin.return_403``

        *Default*: ``False``. Returns 403 error page instead of redirecting
        user.

    ``PermissionRequiredMixin.return_404``

        *Default*: ``False``. Returns 404 error page instead of redirecting
        user.

    ``PermissionRequiredMixin.raise_exception``

        *Default*: ``False``

        `permission_required` - the permission to check of form "<app_label>.<permission codename>"
                                i.e. 'polls.can_vote' for a permission on a model in the polls application.

    ``PermissionRequiredMixin.accept_global_perms``

        *Default*: ``False``,  If accept_global_perms would be set to True, then
         mixing would first check for global perms, if none found, then it will
         proceed to check object level permissions.

    ``PermissionRequiredMixin.permission_object``
         *Default*: ``(not set)``, object against which test the permission; if not set fallback
         to ``self.get_permission_object()`` which return ``self.get_object()``
         or ``self.object`` by default.

    ``PermissionRequiredMixin.any_perm``

        *Default*: ``False``. if True, any of permission in sequence is accepted.

    NFc                     t        | j                  t              r| j                  g}|S t        | j                  t              r| j                  D cg c]  }| }}|S t	        d| j                  z        c c}w a  
        Returns list of permissions in format *<app_label>.<codename>* that
        should be checked against *request.user* and *object*. By default, it
        returns list from ``permission_required`` attribute.

        :param request: Original request.
        z'PermissionRequiredMixin' requires 'permission_required' attribute to be set to '<app_label>.<permission codename>' but is set to '%s' instead
isinstancepermission_requiredstrr   r   r   r   permsps       r   get_required_permissionsz0PermissionRequiredMixin.get_required_permissions        d..4--.E  00(; $ 8 891Q9E9 	 ' (h *.)A)A(B C C :   	A7c                     t        | d      r| j                  S t        | d      xr | j                         xs t        | dd       S )Npermission_object
get_objectobject)hasattrr1   r2   getattr)r   s    r   get_permission_objectz-PermissionRequiredMixin.get_permission_object   sE    4,-)))l+A0A .h-	/r   c                 @   | j                         }t        || j                  |      || j                  | j                  | j
                  | j                  | j                  | j                  	      }|r| j                  |||       |r| j                  r
t               |S )z
        Checks if *request.user* has all permissions returned by
        *get_required_permissions* method.

        :param request: Original request.
        )r+   objr   r   
return_403
return_404accept_global_permsany_perm)r8   )r6   r
   r-   r   r   r9   r:   r;   r<   on_permission_check_failraise_exceptionr   )r   r   r8   	forbiddens       r   check_permissionsz)PermissionRequiredMixin.check_permissions   s     ((*#G*.*G*G(/+1(+.2nn8<8P8P/3/38<8P8P-1]]
&	 ))'9#)F--"$$r   c                      y)a  
        Method called upon permission check fail. By default it does nothing and
        should be overridden, if needed.

        :param request: Original request
        :param response: 403 response returned by *check_permissions* method.
        :param obj: Object that was fetched from the view (using ``get_object``
          method or ``object`` attribute, in that order).
        N )r   r   responser8   s       r   r=   z0PermissionRequiredMixin.on_permission_check_fail   s    r   c                 ~    || _         || _        || _        | j                  |      }|r|S t	        |   |g|i |S N)r   r   r   r@   r   r   )r   r   r   r   rC   r   s        r   r   z PermissionRequiredMixin.dispatch   sJ    	))'2Ow9$9&99r   rE   )r   r   r   r   r   r   r   r(   r   r   r9   r:   r>   r;   r<   r-   r6   r@   r=   r   r    r!   s   @r   r#   r#   3   s[    Qf ""I-JJOH&/4	: :r   r#   c                   (    e Zd Zed        Zd Zd Zy)GuardianUserMixinc                      t               S rE   )r   rB   r   r   get_anonymouszGuardianUserMixin.get_anonymous   s    !##r   c                 D    t         j                  j                  || |      S rE   )UserObjectPermissionobjectsassign_permr   permr8   s      r   add_obj_permzGuardianUserMixin.add_obj_perm       #++77dCHHr   c                 D    t         j                  j                  || |      S rE   )rK   rL   remove_permrN   s      r   del_obj_permzGuardianUserMixin.del_obj_perm   rQ   r   N)r   r   r   staticmethodrI   rP   rT   rB   r   r   rG   rG      s     $ $IIr   rG   c                   8     e Zd ZdZdZi ZddZd Z fdZ xZ	S )PermissionListMixinag  
    A view mixin that filter object in queryset for the current logged by required permission.

    **Example Usage**::

        class SecureView(PermissionListMixin, ListView):
            ...
            permission_required = 'articles.view_article'
            ...

    or::

        class SecureView(PermissionListMixin, ListView):
            ...
            permission_required = 'auth.change_user'
            get_objects_for_user_extra_kwargs = {'use_groups': False}
            ...

    **Class Settings**

    ``PermissionListMixin.permission_required``

        *Default*: ``None``, must be set to either a string or list of strings
        in format: *<app_label>.<permission_codename>*.

    ``PermissionListMixin.get_objects_for_user_extra_kwargs``

        *Default*: ``{}``,  A extra params to pass for ```guardian.shortcuts.get_objects_for_user```

    Nc                     t        | j                  t              r| j                  g}|S t        | j                  t              r| j                  D cg c]  }| }}|S t	        d| j                  z        c c}w r%   r&   r*   s       r   r-   z,PermissionListMixin.get_required_permissions  r.   r/   c                     t        d| j                  j                  | j                  | j                        |d| j                  S )z
        Returns dict of kwargs that should be pass to ```get_objects_for_user```.

        :param request: Queryset to filter
        )userr+   klassrB   )dictr   rZ   r-   !get_objects_for_user_extra_kwargs)r   querysets     r   get_get_objects_for_user_kwargsz3PermissionListMixin.get_get_objects_for_user_kwargs  sG      >**77E"> <<> 	>r   c                 V    t        |   |i |}t        di | j                  |      S )NrB   )r   get_querysetr   r_   )r   r   r   qsr   s       r   ra   z PermissionListMixin.get_queryset%  s0    W!4262#Od&J&J2&NOOr   rE   )
r   r   r   r   r(   r]   r-   r_   ra   r    r!   s   @r   rW   rW      s,    < (*%&	>P Pr   rW   N)collections.abcr   django.confr   django.contrib.auth.decoratorsr   r   django.core.exceptionsr   r   guardian.utilsr	   rK   r
   r   guardian.shortcutsr   r   r#   rG   rW   rB   r   r   <module>ri      sU    $   N I 3/1  > 3$$ $$Nb: b:J
I 
IBP BPr   