# Path: chemtrails/contrib/permissions/models.py
# class AccessRule(models.Model):
# 
#     DIRECTION_CHOICES = (
#         (INCOMING, _('INCOMING')),
#         (EITHER, _('EITHER')),
#         (OUTGOING, _('OUTGOING'))
#     )
# 
#     ctype_source = models.ForeignKey(ContentType, verbose_name=_('source content type'),
#                                      related_name='accessrule_ctype_source_set')
#     ctype_target = models.ForeignKey(ContentType, verbose_name=_('target content type'),
#                                      related_name='accessrule_ctype_target_set')
#     description = models.TextField(_('description'), default='')
#     permissions = models.ManyToManyField(Permission, verbose_name=_('access rule permissions'), blank=True,
#                                          help_text=_('Required permissions for target node.'),
#                                          related_name='accessrule_permissions', related_query_name='accessrule')
#     relation_types = ArrayField(verbose_name=_('relation types'), base_field=JSONField(), default=list,
#                                 help_text=_('List of relation type rule definitions, optionally with a map '
#                                             'of properties for matching the relation type node. '
#                                             'Example: {"USER": {"is_superuser": true}}, {"GROUP": null}'))
#     direction = models.SmallIntegerField(verbose_name=_('direction'), choices=DIRECTION_CHOICES,
#                                          blank=True, null=True, default=None,
#                                          help_text=_('Override calculated direction for relationships.<br/> '
#                                                      'Use with caution, this will affect *all* directional '
#                                                      'relationships for evaluation of this rule!'))
#     is_active = models.BooleanField(default=True, help_text=_('Uncheck to disable evaluation of the rule '
#                                                               'in the rule chain.'))
#     requires_staff = models.BooleanField(default=False, help_text=_('Requires user which should have '
#                                                                     'permissions evaluated to be a staff user.'))
#     created = models.DateTimeField(verbose_name=_('created'), auto_now_add=True)
#     updated = models.DateTimeField(verbose_name=_('updated'), auto_now=True)
# 
#     class Meta:
#         ordering = ('ctype_target', '-created',)
# 
#     def __repr__(self):
#         return '<%(class)s: [%(source)s]-[*]-[%(target)s]>' % {
#             'class': self.__class__.__name__,
#             'source': '%s.%s' % (self.ctype_source.app_label, self.ctype_source.model),
#             'target': '%s.%s' % (self.ctype_target.app_label, self.ctype_target.model),
#         }
# 
#     def __str__(self):
#         return '[%(source)s]-[*]-[%(target)s]' % {
#             'source': self.ctype_source,
#             'target': self.ctype_target
#         }
# 
#     @property
#     def relation_types_obj(self):
#         """
#         Return the relation types JSON string as an OrderedDict.
#         """
#         if self.relation_types:
#             return [json.loads(rule, object_pairs_hook=OrderedDict) for rule in self.relation_types]
#         else:
#             return OrderedDict()
# 
# Path: chemtrails/contrib/permissions/rest_framework/filters.py
# class ChemoPermissionsFilter(BaseFilterBackend):
#     """
#     A filter backend that limits results to those where the 
#     requesting user has read object level permissions based on a
#     calculated graph path.
#     """
#     perm_format = '%(app_label)s.view_%(model_name)s'
# 
#     def __init__(self):
#         assert 'chemtrails.contrib.permissions' in settings.INSTALLED_APPS, (
#             'Using %(class)s, but "chemtrails.contrib.permissions" not found in '
#             'INSTALLED_APPS.' % {'class': self.__class__.__name__}
#         )
# 
#     def filter_queryset(self, request, queryset, view):
#         from chemtrails.contrib.permissions.utils import get_objects_for_user
# 
#         permission = self.perm_format % {
#             'app_label': queryset.model._meta.app_label,
#             'model_name': queryset.model._meta.model_name
#         }
#         return get_objects_for_user(request.user, permissions=permission, klass=queryset)
# 
# Path: chemtrails/contrib/permissions/utils.py
# def get_content_type(obj):
#     """
#     Returns the content type for ``obj``.
#     """
#     return ContentType.objects.get_for_model(obj)
# 
# Path: tests/utils.py
# class flush_nodes(ContextDecorator):
#     """
#     Context decorator which will wipe out the all
#     ``ModelNode`` nodes on enter and exit.
#     """
# 
#     def __enter__(self):
#         clear_neo4j_model_nodes()
# 
#     def __exit__(self, *exc):
#         clear_neo4j_model_nodes()


from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group, Permission
from django.test import TestCase, modify_settings
from rest_framework import status
from rest_framework.permissions import DjangoObjectPermissions
from rest_framework.serializers import ModelSerializer
from rest_framework.test import APIRequestFactory, force_authenticate
from rest_framework.viewsets import ModelViewSet
from chemtrails.contrib.permissions.models import AccessRule
from chemtrails.contrib.permissions.rest_framework.filters import ChemoPermissionsFilter
from chemtrails.contrib.permissions.utils import get_content_type
from tests.utils import flush_nodes
# -*- coding: utf-8 -*-




User = get_user_model()
factory = APIRequestFactory()


class ChemoPermissionsFilterTestCase(TestCase):

    backend = 'chemtrails.contrib.permissions.backends.ChemoPermissionsBackend'

    def setUp(self):
        Group.objects.bulk_create([Group(name=name) for name in ['group1', 'group2', 'group3']])

        class GroupSerializer(ModelSerializer):
            class Meta:
                model = Group
                fields = '__all__'

        class GroupViewSet(ModelViewSet):
            queryset = Group.objects.all()
            serializer_class = GroupSerializer
            permission_classes = [DjangoObjectPermissions]
            filter_backends = [ChemoPermissionsFilter]

        self.user = User.objects.create_user(username='testuser', password='test123.')
        self.perm = Permission.objects.create(content_type=get_content_type(Group),
                                              name='Can view group', codename='view_group')

# Path: chemtrails/contrib/permissions/models.py
# class AccessRule(models.Model):
# 
#     DIRECTION_CHOICES = (
#         (INCOMING, _('INCOMING')),
#         (EITHER, _('EITHER')),
#         (OUTGOING, _('OUTGOING'))
#     )
# 
#     ctype_source = models.ForeignKey(ContentType, verbose_name=_('source content type'),
#                                      related_name='accessrule_ctype_source_set')
#     ctype_target = models.ForeignKey(ContentType, verbose_name=_('target content type'),
#                                      related_name='accessrule_ctype_target_set')
#     description = models.TextField(_('description'), default='')
#     permissions = models.ManyToManyField(Permission, verbose_name=_('access rule permissions'), blank=True,
#                                          help_text=_('Required permissions for target node.'),
#                                          related_name='accessrule_permissions', related_query_name='accessrule')
#     relation_types = ArrayField(verbose_name=_('relation types'), base_field=JSONField(), default=list,
#                                 help_text=_('List of relation type rule definitions, optionally with a map '
#                                             'of properties for matching the relation type node. '
#                                             'Example: {"USER": {"is_superuser": true}}, {"GROUP": null}'))
#     direction = models.SmallIntegerField(verbose_name=_('direction'), choices=DIRECTION_CHOICES,
#                                          blank=True, null=True, default=None,
#                                          help_text=_('Override calculated direction for relationships.<br/> '
#                                                      'Use with caution, this will affect *all* directional '
#                                                      'relationships for evaluation of this rule!'))
#     is_active = models.BooleanField(default=True, help_text=_('Uncheck to disable evaluation of the rule '
#                                                               'in the rule chain.'))
#     requires_staff = models.BooleanField(default=False, help_text=_('Requires user which should have '
#                                                                     'permissions evaluated to be a staff user.'))
#     created = models.DateTimeField(verbose_name=_('created'), auto_now_add=True)
#     updated = models.DateTimeField(verbose_name=_('updated'), auto_now=True)
# 
#     class Meta:
#         ordering = ('ctype_target', '-created',)
# 
#     def __repr__(self):
#         return '<%(class)s: [%(source)s]-[*]-[%(target)s]>' % {
#             'class': self.__class__.__name__,
#             'source': '%s.%s' % (self.ctype_source.app_label, self.ctype_source.model),
#             'target': '%s.%s' % (self.ctype_target.app_label, self.ctype_target.model),
#         }
# 
#     def __str__(self):
#         return '[%(source)s]-[*]-[%(target)s]' % {
#             'source': self.ctype_source,
#             'target': self.ctype_target
#         }
# 
#     @property
#     def relation_types_obj(self):
#         """
#         Return the relation types JSON string as an OrderedDict.
#         """
#         if self.relation_types:
#             return [json.loads(rule, object_pairs_hook=OrderedDict) for rule in self.relation_types]
#         else:
#             return OrderedDict()
# 
# Path: chemtrails/contrib/permissions/rest_framework/filters.py
# class ChemoPermissionsFilter(BaseFilterBackend):
#     """
#     A filter backend that limits results to those where the 
#     requesting user has read object level permissions based on a
#     calculated graph path.
#     """
#     perm_format = '%(app_label)s.view_%(model_name)s'
# 
#     def __init__(self):
#         assert 'chemtrails.contrib.permissions' in settings.INSTALLED_APPS, (
#             'Using %(class)s, but "chemtrails.contrib.permissions" not found in '
#             'INSTALLED_APPS.' % {'class': self.__class__.__name__}
#         )
# 
#     def filter_queryset(self, request, queryset, view):
#         from chemtrails.contrib.permissions.utils import get_objects_for_user
# 
#         permission = self.perm_format % {
#             'app_label': queryset.model._meta.app_label,
#             'model_name': queryset.model._meta.model_name
#         }
#         return get_objects_for_user(request.user, permissions=permission, klass=queryset)
# 
# Path: chemtrails/contrib/permissions/utils.py
# def get_content_type(obj):
#     """
#     Returns the content type for ``obj``.
#     """
#     return ContentType.objects.get_for_model(obj)
# 
# Path: tests/utils.py
# class flush_nodes(ContextDecorator):
#     """
#     Context decorator which will wipe out the all
#     ``ModelNode`` nodes on enter and exit.
#     """
# 
#     def __enter__(self):
#         clear_neo4j_model_nodes()
# 
#     def __exit__(self, *exc):
#         clear_neo4j_model_nodes()


# Path: tests/contrib/permissions/test_filters.py
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group, Permission
from django.test import TestCase, modify_settings
from rest_framework import status
from rest_framework.permissions import DjangoObjectPermissions
from rest_framework.serializers import ModelSerializer
from rest_framework.test import APIRequestFactory, force_authenticate
from rest_framework.viewsets import ModelViewSet
from chemtrails.contrib.permissions.models import AccessRule
from chemtrails.contrib.permissions.rest_framework.filters import ChemoPermissionsFilter
from chemtrails.contrib.permissions.utils import get_content_type
from tests.utils import flush_nodes

# -*- coding: utf-8 -*-




User = get_user_model()
factory = APIRequestFactory()


class ChemoPermissionsFilterTestCase(TestCase):

    backend = 'chemtrails.contrib.permissions.backends.ChemoPermissionsBackend'

    def setUp(self):
        Group.objects.bulk_create([Group(name=name) for name in ['group1', 'group2', 'group3']])

        class GroupSerializer(ModelSerializer):
            class Meta:
                model = Group
                fields = '__all__'

        class GroupViewSet(ModelViewSet):
            queryset = Group.objects.all()
            serializer_class = GroupSerializer
            permission_classes = [DjangoObjectPermissions]
            filter_backends = [ChemoPermissionsFilter]

        self.user = User.objects.create_user(username='testuser', password='test123.')
        self.perm = Permission.objects.create(content_type=get_content_type(Group),
                                              name='Can view group', codename='view_group')

        self.access_rule = AccessRule.objects.create(ctype_source=get_content_type(User),