o
    "7h(                     @   s  d dl Z d dlmZ G dd deZG dd deZG dd deZG d	d
 d
e eeZ	G dd de eeZ
G dd de eeZG dd de eeZG dd de eeZG dd deZG dd deZG dd deZG dd deZG dd deZeeB ZdS )    N)SAFE_METHODSc                   @   s4   e Zd ZdZdZdd Zdd Zdd Zd	d
 ZdS )MetaOperanda  Metaclass that allows its instances (permission classes) to use logical
    using logical operators (AND, OR, ..) with the follwing syntax:

        FinalPermClass = (Perm1 | Perm2) & ~Perm3

    The `OPERATOR_NAME` class attribute is used to build a name for the resulting
    class of an unary/binary operation. For example:

        FinalPermClass = (Perm1 | Perm2) & ~Perm3
        FinalPermClass.__class__.__name__
        # ((Perm1_OR_Perm2)_And_(Not_Perm3))

    Nc                 C      t | |S N)ANDbuild_permission_fromfirst_classsecond_class r   l/var/www/epreuve.sigeris.cm/public_html/epreuve/venv/lib/python3.10/site-packages/django_rest/permissions.py__and__      zMetaOperand.__and__c                 C   r   r   )ORr   r   r   r   r   __or__   r   zMetaOperand.__or__c                 C   r   r   )XORr   r   r   r   r   __xor__!   r   zMetaOperand.__xor__c                 C   s
   t | S r   )NOTr   )r	   r   r   r   
__invert__%      
zMetaOperand.__invert__)	__name__
__module____qualname____doc__OPERATOR_NAMEr   r   r   r   r   r   r   r   r      s    r   c                   @   s@   e Zd ZdZedd Zedd Zedd Zedd	 Z	d
S )BinaryOperatora  Class that describes how to build a permission class as a result of a
    Binary operators only. The current class is intended to be inherited by operators
    like: `AND`, `OR`, `XOR`, etc.

    The method called during operations is `build_permission_class()`. It creates
    a new permission class (i.e. inheriting from `BasePermission`), for which
    the `has_permission()` method is built using the `calculate()` method on both
    `has_permission()` results of operand classes.

    A new binary operator can be created by inheriting both the current class, and
    defining `MetaOperand` as metaclass, then implementing the `calculate()`
    staticmethod.
    Example:

        class MyNewBinaryOperator(BinaryOperator, metaclass=MetaOperand):
            @staticmethod
            def calculae(value1, value2):
                # type:(bool, bool) -> bool
                return fn(value1, value2)

    Then, in order to make the new operator used (without having to always call
    `MyNewBinaryOperator.build_permission_from(class1, class2)`, it should be
    subscribed in the `MetaOperand`. For example, in order to use the new operator
    with the `+`, it should be assigned in the `__add__` method of `MetaOperand`
    c                 O      t dNz4`calculate()` method should be defined in subclassesNotImplementedErrorfirst_functionsecond_functionargskwargsr   r   r   	calculateH      zBinaryOperator.calculatec                 C      d |j| j|jS )Nz({}{}{}))formatr   r   clsclass_1class_2r   r   r   build_classnameO   s   zBinaryOperator.build_classnamec                 C   r'   )Nz	({})
	{}
	({}))r(   r   r   r)   r   r   r   build_docstringT   s   zBinaryOperator.build_docstringc                    sB     }t|tfi } |_ fdd}||_|S )Nc                    s     j } j } ||||S r   has_permissionr%   )selfrequestviewpermission_func_1permission_func_2r*   permission_class_1permission_class_2r   r   r0   d   s   z<BinaryOperator.build_permission_from.<locals>.has_permissionr-   r   BasePermissionr.   r   r0   )r*   r7   r8   result_classnameresult_classr0   r   r6   r   r   [   s   z$BinaryOperator.build_permission_fromN)
r   r   r   r   staticmethodr%   classmethodr-   r.   r   r   r   r   r   r   -   s    


r   c                   @   sD   e Zd ZdZdZedd Zedd Zedd Z	ed	d
 Z
dS )UnaryOperatoras  Class that describes how to build a permission class as a result of a
    Unary operators only. The current class is intended to be inherited by operators
    like: `NOT` and Identity operators.

    The method called during operations is `build_permission_class()`. It creates
    a new permission class (i.e. inheriting from `BasePermission`), for which
    the `has_permission()` method is built using the `calculate()` method on the
    `has_permission()` result of operand class.

    A new unary operator can be created by inheriting both the current class, and
    defining `MetaOperand` as metaclass, then implementing the `calculate()`
    staticmethod.
    Example:

        class MyNewUnaryOperator(UnaryOperator, metaclass=MetaOperand):
            @staticmethod
            def calculae(value):
                # type:(bool) -> bool
                return fn(value)
    Nc                 O   r   r   r   functionr#   r$   r   r   r   r%      r&   zUnaryOperator.calculatec                 C      d | j|jS )Nz({}{}))r(   r   r   r*   _classr   r   r   r-         zUnaryOperator.build_classnamec                 C   rB   )Nz	{}({}))r(   r   r   rC   r   r   r   r.      rE   zUnaryOperator.build_docstringc                    s<     }t|tfi } |_ fdd}||_|S )Nc                    s    j } |||S r   r/   )r1   r2   r3   permission_funcr*   permission_classr   r   r0      s   z;UnaryOperator.build_permission_from.<locals>.has_permissionr9   )r*   rH   r;   r<   r0   r   rG   r   r      s   
z#UnaryOperator.build_permission_from)r   r   r   r   r   r=   r%   r>   r-   r.   r   r   r   r   r   r?   n   s    


r?   c                   @       e Zd ZdZdZedd ZdS )r   zAND Logical operator class.

    Example of use:

        ResultPermClass = AND.build_permission_from(PermClass1, PermClass2)
        # Which is also equivalend to:
        ResultPermClass = PermClass1 & PermClass2
    _AND_c                 O   s   | |i |o||i |S r   r   r    r   r   r   r%         zAND.calculateNr   r   r   r   r   r=   r%   r   r   r   r   r      
    	r   c                   @   rI   )r   zOR Logical operator class.

    Example of use:

        ResultPermClass = OR.build_permission_from(PermClass1, PermClass2)
        # Which is also equivalend to:
        ResultPermClass = PermClass1 | PermClass2
    _OR_c                 O   s   | |i |p||i |S r   r   r    r   r   r   r%      rK   zOR.calculateNrL   r   r   r   r   r      rM   r   c                   @   rI   )r   zXOR (eXclusive OR) Logical operator class.

    Example of use:

        ResultPermClass = XOR.build_permission_from(PermClass1, PermClass2)
        # Which is also equivalend to:
        ResultPermClass = PermClass1 ^ PermClass2
    _XOR_c                 O   s   | |i |||i |A S r   r   r    r   r   r   r%      rK   zXOR.calculateNrL   r   r   r   r   r      rM   r   c                   @   rI   )r   zNOT Logical operator class.

    Example of use:

        ResultPermClass = NOT.build_permission_from(PermClass)
        # Which is also equivalend to:
        ResultPermClass = ~PermClass
    NOT_c                 O   s   | |i | S r   r   r@   r   r   r   r%      rE   zNOT.calculateNrL   r   r   r   r   r      rM   r   c                   @      e Zd ZdZdd ZdS )r:   a  
    The Mainclass of all existing permissions. It's created with `MetaOperand`,
    which allows it to use operators such as: `&`, `|` `^` and `~`.

    A new custom permission could be created by inheriting from the current class,
    and implementing the `has_permission()` method, as shown in the following example:

        class FooBarPermission(BasePermission):
            def has_permission(self, request, view):
                return request.user.name in ("foo", "bar")
    c                 C   r   )Nz9`has_permission()` method should be defined in subclassesr   r1   r2   r3   r   r   r   r0      s   zBasePermission.has_permissionNr   r   r   r   r0   r   r   r   r   r:      s    r:   c                   @   rQ   )AllowAnyz.
    Allows everybody to access the view.
    c                 C   s   dS )NTr   rR   r   r   r   r0     s   zAllowAny.has_permissionNrS   r   r   r   r   rT         rT   c                   @   rQ   )IsAuthenticatedz=
    Allows the view access to authenticated users only.
    c                 C      t |jo|jjS r   )booluseris_authenticatedrR   r   r   r   r0        zIsAuthenticated.has_permissionNrS   r   r   r   r   rV     rU   rV   c                   @   rQ   )IsStaffUserz5
    Allows the view access to staff users only.
    c                 C   rW   r   )rX   rY   is_staffrR   r   r   r   r0     r[   zIsStaffUser.has_permissionNrS   r   r   r   r   r\     rU   r\   c                   @   rQ   )IsAdminUserz5
    Allows the view access to admin users only.
    c                 C   rW   r   )rX   rY   is_superuserrR   r   r   r   r0   )  r[   zIsAdminUser.has_permissionNrS   r   r   r   r   r^   $  rU   r^   c                   @   rQ   )
IsReadOnlyzR
    Allows the view access to read-only http methods: GET, HEAD and OPTIONS.
    c                 C   s
   |j tv S r   )methodr   rR   r   r   r   r0   3  r   zIsReadOnly.has_permissionNrS   r   r   r   r   r`   .  rU   r`   )sixdjango_rest.http.methodsr   typer   objectr   r?   with_metaclassr   r   r   r   r:   rT   rV   r\   r^   r`   IsAuthenticatedOrReadOnlyr   r   r   r   <module>   s    %A<




