# Path: tutelary/engine.py
# class Object(EscapeSeparated):
#     """Objects are represented by slash-separated sequences of elements
#     (e.g. ``Cadasta/Batangas/parcel/123``, ``H4H/PaP/party/118``) with
#     wildcard elements indicated by ``*``
#     (e.g. ``Cadasta/*/parcel/*``).  Slashes can be backslash-escaped,
#     as can backslashes (e.g. ``Cadasta/Village-X\/Y/parcel/943``).
# 
#     """
#     separator = '/'
# 
# class Action(SimpleSeparated):
#     """Actions are represented by period-separated sequences of elements
#     (e.g. ``parcel.edit``, ``admin.assign-role``) with wildcard
#     elements indicated by ``*`` (e.g. ``party.*``).  A list of
#     *registered* actions is maintained to support permissions set
#     queries to find the set of actions that are permitted on a
#     specified object pattern.
# 
#     """
#     separator = '.'
# 
#     registered = set()
# 
#     def register(action):
#         """Action registration is used to support generating lists of
#         permitted actions from a permission set and an object pattern.
#         Only registered actions will be returned by such queries.
# 
#         """
#         if isinstance(action, str):
#             Action.register(Action(action))
#         elif isinstance(action, Action):
#             Action.registered.add(action)
#         else:
#             for a in action:
#                 Action.register(a)
# 
# Path: tutelary/models.py
# def check_perms(user, actions, objs, method=None):
#     ensure_permission_set_tree_cached(user)
#     if actions is False:
#         return False
#     if actions is not None:
#         for a in actions:
#             for o in objs:
#                 test_obj = None
#                 if o is not None:
#                     test_obj = o.get_permissions_object(a)
#                 if not user.has_perm(a, test_obj):
#                     return False
#     return True
# 
# Path: tutelary/exceptions.py
# class DecoratorException(TutelaryException):
#     """Exception raised if the ``permissioned_model`` decorator is used
#     without the required ``TutelaryMeta`` class member being included
#     in the model.
# 
#     """
#     def __init__(self, decorator, msg):
#         super().__init__(
#             "error expanding decorator '" + decorator + "': " + msg
#         )
# 
# class PermissionObjectException(TutelaryException):
#     """Exception raised by the ``permissioned_model`` decorator if a
#     ``permissions_object`` property in the ``actions`` list refers to
#     a non-existent model field, or to a field that is not a foreign
#     key or one-to-one relation field.
# 
#     """
#     def __init__(self, prop):
#         super().__init__(
#             "invalid permissions_object property '" + prop +
#             "' in permissioned_model"
#         )


from functools import reduce, wraps
from django.core.exceptions import PermissionDenied
from django.db import models
from django.utils.decorators import available_attrs
from .engine import Object, Action
from .models import check_perms
from .exceptions import DecoratorException, PermissionObjectException



def permission_required(*actions, obj=None, raise_exception=False):
    """Permission checking decorator -- works like the
    ``permission_required`` decorator in the default Django
    authentication system, except that it takes a sequence of actions
    to check, an object must be supplied, and the user must have
    permission to perform all of the actions on the given object for
    the permissions test to pass.  *Not actually sure how useful this
    is going to be: in any case where obj is not None, it's going to
    be tricky to get the object into the decorator.  Class-based views
    are definitely best here...*

    """
    def checker(user):
        ok = False

# Path: tutelary/engine.py
# class Object(EscapeSeparated):
#     """Objects are represented by slash-separated sequences of elements
#     (e.g. ``Cadasta/Batangas/parcel/123``, ``H4H/PaP/party/118``) with
#     wildcard elements indicated by ``*``
#     (e.g. ``Cadasta/*/parcel/*``).  Slashes can be backslash-escaped,
#     as can backslashes (e.g. ``Cadasta/Village-X\/Y/parcel/943``).
# 
#     """
#     separator = '/'
# 
# class Action(SimpleSeparated):
#     """Actions are represented by period-separated sequences of elements
#     (e.g. ``parcel.edit``, ``admin.assign-role``) with wildcard
#     elements indicated by ``*`` (e.g. ``party.*``).  A list of
#     *registered* actions is maintained to support permissions set
#     queries to find the set of actions that are permitted on a
#     specified object pattern.
# 
#     """
#     separator = '.'
# 
#     registered = set()
# 
#     def register(action):
#         """Action registration is used to support generating lists of
#         permitted actions from a permission set and an object pattern.
#         Only registered actions will be returned by such queries.
# 
#         """
#         if isinstance(action, str):
#             Action.register(Action(action))
#         elif isinstance(action, Action):
#             Action.registered.add(action)
#         else:
#             for a in action:
#                 Action.register(a)
# 
# Path: tutelary/models.py
# def check_perms(user, actions, objs, method=None):
#     ensure_permission_set_tree_cached(user)
#     if actions is False:
#         return False
#     if actions is not None:
#         for a in actions:
#             for o in objs:
#                 test_obj = None
#                 if o is not None:
#                     test_obj = o.get_permissions_object(a)
#                 if not user.has_perm(a, test_obj):
#                     return False
#     return True
# 
# Path: tutelary/exceptions.py
# class DecoratorException(TutelaryException):
#     """Exception raised if the ``permissioned_model`` decorator is used
#     without the required ``TutelaryMeta`` class member being included
#     in the model.
# 
#     """
#     def __init__(self, decorator, msg):
#         super().__init__(
#             "error expanding decorator '" + decorator + "': " + msg
#         )
# 
# class PermissionObjectException(TutelaryException):
#     """Exception raised by the ``permissioned_model`` decorator if a
#     ``permissions_object`` property in the ``actions`` list refers to
#     a non-existent model field, or to a field that is not a foreign
#     key or one-to-one relation field.
# 
#     """
#     def __init__(self, prop):
#         super().__init__(
#             "invalid permissions_object property '" + prop +
#             "' in permissioned_model"
#         )


# Path: tutelary/decorators.py
from functools import reduce, wraps
from django.core.exceptions import PermissionDenied
from django.db import models
from django.utils.decorators import available_attrs
from .engine import Object, Action
from .models import check_perms
from .exceptions import DecoratorException, PermissionObjectException




def permission_required(*actions, obj=None, raise_exception=False):
    """Permission checking decorator -- works like the
    ``permission_required`` decorator in the default Django
    authentication system, except that it takes a sequence of actions
    to check, an object must be supplied, and the user must have
    permission to perform all of the actions on the given object for
    the permissions test to pass.  *Not actually sure how useful this
    is going to be: in any case where obj is not None, it's going to
    be tricky to get the object into the decorator.  Class-based views
    are definitely best here...*

    """
    def checker(user):
        ok = False

        if user.is_authenticated() and check_perms(user, actions, [obj]):