# Path: protector/exceptions.py
# class NoReasonSpecified(BaseException):
#     def __init__(self, message='You should point the reason for this action'):
#         super(NoReasonSpecified, self).__init__(message)
# 
# Path: protector/internals.py
# VIEW_PERMISSION_NAME = 'protector.{0}'.format(VIEW_RESTRICTED_OBJECTS)
# 
# def _get_restriction_filter(qset, user_id, perm_id):
#     if hasattr(qset, 'get_restriction_id_field'):
#         obj_id_field = qset.get_restriction_id_field()
#     else:
#         obj_id_field = "{table_name!s}.restriction_id".format(
#             table_name=qset.model._meta.db_table)
#     if hasattr(qset, 'get_restriction_ctype_id_field'):
#         ctype_id_field = qset.get_restriction_ctype_id_field()
#     else:
#         ctype_id_field = "{table_name!s}.restriction_content_type_id".format(
#             table_name=qset.model._meta.db_table
#         )
#     result = _get_filter_by_perm_condition(
#         qset, user_id, perm_id, obj_id_field, ctype_id_field)
#     return result
# 
# def get_user_ctype():
#     return ContentType.objects.get_for_model(get_user_model())
# 
# Path: protector/helpers.py
# def filter_queryset_by_permission(qset, user, permission):
#     perm_id = get_permission_id_by_name(permission)
#     if user.has_perm(permission):
#         return qset.all()
#     if user.id is None or perm_id is None:
#         return qset.none()
#     condition = _get_permission_filter(qset, user.id, perm_id)
#     result = qset.extra(where=[condition])
#     return result
# 
# def get_view_permission():
#     codename = VIEW_RESTRICTED_OBJECTS
#     global _view_perm
#     OwnerToPermission = apps.get_model('protector', 'OwnerToPermission')
#     if _view_perm is None:
#         ctype = ContentType.objects.get_for_model(OwnerToPermission)
#         _view_perm = Permission.objects.get(
#             codename=codename, content_type=ctype
#         )
#     return _view_perm
# 
# def check_responsible_reason(func):
#     @wraps(func)
#     def wrapper(*args, **kwargs):
#         responsible = kwargs.get('responsible')
#         reason = kwargs.get('reason') or (len(args) > 2 and args[2])
#         if responsible is not None and not isinstance(responsible, get_user_model()):
#             raise ImproperResponsibleInstancePassed
#         if not isinstance(reason, basestring) or not len(reason):
#             raise NoReasonSpecified
# 
#         return func(*args, **kwargs)
#     return wrapper
# 
# Path: protector/reserved_reasons.py
# GENERIC_GROUP_UPDATE_REASON = 'Groups were created due to foreign key links update'


from copy import deepcopy
from django.db.models.query import QuerySet
from django.db.models import F
from django.apps import apps
from django.contrib.contenttypes.models import ContentType
from protector.exceptions import NoReasonSpecified
from protector.internals import (
    VIEW_PERMISSION_NAME,
    _get_restriction_filter,
    get_user_ctype,
)
from protector.helpers import filter_queryset_by_permission, get_view_permission, check_responsible_reason
from protector.reserved_reasons import GENERIC_GROUP_UPDATE_REASON

        return super(OwnerToPermissionQuerySet, self).delete()

    @check_responsible_reason
    def create(self, **kwargs):
        history_kwargs = deepcopy(kwargs)
        try:
            del kwargs['reason']
        except KeyError:
            pass

        obj = self.model(**kwargs)
        self._for_write = True
        obj.save(
            reason=history_kwargs['reason'],
            force_insert=True,
            using=self.db
        )

        return obj

    @check_responsible_reason
    def get_or_create(self, defaults=None, **kwargs):
        get_kwargs = deepcopy(kwargs)
        try:
            del get_kwargs['reason']
        except KeyError:
            pass
        try:
            result = super(OwnerToPermissionQuerySet, self).get_or_create(defaults=defaults, **get_kwargs)

# Path: protector/exceptions.py
# class NoReasonSpecified(BaseException):
#     def __init__(self, message='You should point the reason for this action'):
#         super(NoReasonSpecified, self).__init__(message)
# 
# Path: protector/internals.py
# VIEW_PERMISSION_NAME = 'protector.{0}'.format(VIEW_RESTRICTED_OBJECTS)
# 
# def _get_restriction_filter(qset, user_id, perm_id):
#     if hasattr(qset, 'get_restriction_id_field'):
#         obj_id_field = qset.get_restriction_id_field()
#     else:
#         obj_id_field = "{table_name!s}.restriction_id".format(
#             table_name=qset.model._meta.db_table)
#     if hasattr(qset, 'get_restriction_ctype_id_field'):
#         ctype_id_field = qset.get_restriction_ctype_id_field()
#     else:
#         ctype_id_field = "{table_name!s}.restriction_content_type_id".format(
#             table_name=qset.model._meta.db_table
#         )
#     result = _get_filter_by_perm_condition(
#         qset, user_id, perm_id, obj_id_field, ctype_id_field)
#     return result
# 
# def get_user_ctype():
#     return ContentType.objects.get_for_model(get_user_model())
# 
# Path: protector/helpers.py
# def filter_queryset_by_permission(qset, user, permission):
#     perm_id = get_permission_id_by_name(permission)
#     if user.has_perm(permission):
#         return qset.all()
#     if user.id is None or perm_id is None:
#         return qset.none()
#     condition = _get_permission_filter(qset, user.id, perm_id)
#     result = qset.extra(where=[condition])
#     return result
# 
# def get_view_permission():
#     codename = VIEW_RESTRICTED_OBJECTS
#     global _view_perm
#     OwnerToPermission = apps.get_model('protector', 'OwnerToPermission')
#     if _view_perm is None:
#         ctype = ContentType.objects.get_for_model(OwnerToPermission)
#         _view_perm = Permission.objects.get(
#             codename=codename, content_type=ctype
#         )
#     return _view_perm
# 
# def check_responsible_reason(func):
#     @wraps(func)
#     def wrapper(*args, **kwargs):
#         responsible = kwargs.get('responsible')
#         reason = kwargs.get('reason') or (len(args) > 2 and args[2])
#         if responsible is not None and not isinstance(responsible, get_user_model()):
#             raise ImproperResponsibleInstancePassed
#         if not isinstance(reason, basestring) or not len(reason):
#             raise NoReasonSpecified
# 
#         return func(*args, **kwargs)
#     return wrapper
# 
# Path: protector/reserved_reasons.py
# GENERIC_GROUP_UPDATE_REASON = 'Groups were created due to foreign key links update'


# Path: protector/querysets.py
from copy import deepcopy
from django.db.models.query import QuerySet
from django.db.models import F
from django.apps import apps
from django.contrib.contenttypes.models import ContentType
from protector.exceptions import NoReasonSpecified
from protector.internals import (
    VIEW_PERMISSION_NAME,
    _get_restriction_filter,
    get_user_ctype,
)
from protector.helpers import filter_queryset_by_permission, get_view_permission, check_responsible_reason
from protector.reserved_reasons import GENERIC_GROUP_UPDATE_REASON


        return super(OwnerToPermissionQuerySet, self).delete()

    @check_responsible_reason
    def create(self, **kwargs):
        history_kwargs = deepcopy(kwargs)
        try:
            del kwargs['reason']
        except KeyError:
            pass

        obj = self.model(**kwargs)
        self._for_write = True
        obj.save(
            reason=history_kwargs['reason'],
            force_insert=True,
            using=self.db
        )

        return obj

    @check_responsible_reason
    def get_or_create(self, defaults=None, **kwargs):
        get_kwargs = deepcopy(kwargs)
        try:
            del get_kwargs['reason']
        except KeyError:
            pass
        try:
            result = super(OwnerToPermissionQuerySet, self).get_or_create(defaults=defaults, **get_kwargs)

        except NoReasonSpecified: