def __init__(self, user_or_group=None): """ :param user_or_group: should be an ``User``, ``AnonymousUser`` or ``Group`` instance """ self.user, self.group = get_identity(user_or_group) self._obj_perms_cache = {}
def __init__(self, user_or_group=None): """ Constructor for ObjectPermissionChecker. :param user_or_group: should be an ``User``, ``AnonymousUser`` or ``Group`` instance """ self.user, self.group = get_identity(user_or_group) self._obj_perms_cache = {}
def get_user_group_perms(user_or_group, obj): """Get permissins for user groups. Based on guardian.core.ObjectPermissionChecker. """ user, group = get_identity(user_or_group) if user and not user.is_active: return [], [] user_model = get_user_model() ctype = ContentType.objects.get_for_model(obj) group_model = get_group_obj_perms_model(obj) group_rel_name = group_model.permission.field.related_query_name() if user: user_rel_name = user_model.groups.field.related_query_name() group_filters = {user_rel_name: user} else: group_filters = {'pk': group.pk} if group_model.objects.is_generic(): group_filters.update({ '{}__content_type'.format(group_rel_name): ctype, '{}__object_pk'.format(group_rel_name): obj.pk, }) else: group_filters['{}__content_object'.format(group_rel_name)] = obj user_perms, group_perms = [], [] if user: perms_qs = Permission.objects.filter(content_type=ctype) if user.is_superuser: user_perms = list(chain(perms_qs.values_list("codename", flat=True))) else: model = get_user_obj_perms_model(obj) related_name = model.permission.field.related_query_name() user_filters = {'{}__user'.format(related_name): user} if model.objects.is_generic(): user_filters.update({ '{}__content_type'.format(related_name): ctype, '{}__object_pk'.format(related_name): obj.pk, }) else: user_filters['{}__content_object'.format(related_name)] = obj user_perms_qs = perms_qs.filter(**user_filters) user_perms = list(chain(user_perms_qs.values_list("codename", flat=True))) group_perms_qs = Group.objects.filter(**group_filters) group_perms = list(chain(group_perms_qs.order_by("pk").values_list( "pk", "name", "{}__permission__codename".format(group_rel_name)))) group_perms = _group_groups(group_perms) return user_perms, group_perms
def get_user_group_perms(user_or_group, obj): user, group = get_identity(user_or_group) if user and not user.is_active: return [], [] User = get_user_model() ctype = ContentType.objects.get_for_model(obj) group_model = get_group_obj_perms_model(obj) group_rel_name = group_model.permission.field.related_query_name() if user: fieldname = '%s__group__%s' % ( group_rel_name, User.groups.field.related_query_name(), ) group_filters = {fieldname: user} else: group_filters = {'%s__group' % group_rel_name: group} if group_model.objects.is_generic(): group_filters.update({ '%s__content_type' % group_rel_name: ctype, '%s__object_pk' % group_rel_name: obj.pk, }) else: group_filters['%s__content_object' % group_rel_name] = obj user_perms = [] group_perms = [] if user and user.is_superuser: user_perms = list(chain(*Permission.objects .filter(content_type=ctype) .values_list("codename"))) elif user: model = get_user_obj_perms_model(obj) related_name = model.permission.field.related_query_name() user_filters = {'%s__user' % related_name: user} if model.objects.is_generic(): user_filters.update({ '%s__content_type' % related_name: ctype, '%s__object_pk' % related_name: obj.pk, }) else: user_filters['%s__content_object' % related_name] = obj perms_qs = Permission.objects.filter(content_type=ctype) user_perms_qs = perms_qs.filter(**user_filters) user_perms = user_perms_qs.values_list("codename", flat=True) group_perms_qs = perms_qs.filter(**group_filters) group_perms = group_perms_qs.values_list("codename", flat=True) else: user_perms = list(set(chain(*Permission.objects .filter(content_type=ctype) .filter(**group_filters) .values_list("codename")))) return user_perms, group_perms
def remove_perm(perm, user_or_group=None, obj=None): """ Removes permission from user/group and object pair. """ perm = perm.split('.')[-1] user, group = get_identity(user_or_group) if user: UserObjectPermission.objects.remove_perm(perm, user, obj) if group: GroupObjectPermission.objects.remove_perm(perm, group, obj)
def bulk_add_perms(perms, user_or_group, objects): """ Adds permissions in bulk. :param perms single Permission or list of Permissions :param user_or_group, django.contrib.auth.models User or Group object :param group single, list, tuple or queryset of objects (same type) NB!!! ONLY TESTED IN POSTGRESQL """ if not isinstance(perms, (types.ListType, types.TupleType)): perms = [perms] if not isinstance(objects, (types.ListType, types.TupleType)) and not isinstance(objects, QuerySet): objects = [objects] if len(objects) == 0: return user, group = get_identity(user_or_group) ctype = ContentType.objects.get_for_model(objects[0]) permissions = Permission.objects.filter(content_type = ctype, codename__in = perms) objects = [str(object.pk) for object in objects] permissions_ids = [perm.id for perm in permissions] sql_values_list = [] if user: dict = {'column':'user_id', 'table' : 'guardian_userobjectpermission' } target_id = str(user.id) if group: dict = {'column':'group_id', 'table' : 'guardian_groupobjectpermission' } target_id = str(group.id) for permission_id in permissions_ids: for obj_pk in objects: sql_values_list.append("SELECT %s, %s, '%s', %s " % (permission_id, str(ctype.id), obj_pk, target_id)) sql_values = 'UNION ALL '.join(sql_values_list) dict['sql_values'] = sql_values dict['str_permission_ids'] = str(permissions_ids).replace('[','').replace(']','') dict['str_object_pks'] = str(objects).replace('[','').replace(']','') dict['target_id'] = target_id sql = "INSERT INTO %(table)s (permission_id, content_type_id, object_pk, %(column)s)" % dict sql += " (%(sql_values)s" % dict sql += "EXCEPT SELECT permission_id,content_type_id, object_pk, %(column)s from %(table)s" % dict sql += " WHERE permission_id in (%(str_permission_ids)s) and object_pk in (%(str_object_pks)s) and %(column)s = %(target_id)s" % dict sql += ")" from django.db import connection, transaction with transaction.commit_on_success(): cursor = connection.cursor() cursor.execute(sql)
def __init__(self, user_or_group=None, direct_perms_only=False): """ :param user_or_group: should be an ``User``, ``AnonymousUser`` or ``Group`` instance :param direct_perms_only: If set to ``True`` and ``user_or_group`` is a ``User`` instance, only consider permissions assigned directly to the user, not those coming via user's superuser status or group memberships. """ self.user, self.group = get_identity(user_or_group) self._obj_perms_cache = {} self._direct_perms_only = direct_perms_only if self.user else False
def remove_perm(perm, user_or_group=None, obj=None): """ Removes permission from user/group and object pair. :param perm: proper permission for given ``obj``, as string (in format: ``app_label.codename`` or ``codename``). If ``obj`` is not given, must be in format ``app_label.codename``. :param user_or_group: instance of ``User``, ``AnonymousUser`` or ``Group``; passing any other object would raise ``guardian.exceptions.NotUserNorGroup`` exception :param obj: persisted Django's ``Model`` instance or QuerySet of Django ``Model`` instances or ``None`` if assigning global permission. Default is ``None``. """ user, group = get_identity(user_or_group) if obj is None: try: app_label, codename = perm.split('.', 1) except ValueError: raise ValueError("For global permissions, first argument must be in" " format: 'app_label.codename' (is %r)" % perm) perm = Permission.objects.get(content_type__app_label=app_label, codename=codename) if user: user.user_permissions.remove(perm) return elif group: group.permissions.remove(perm) return if not isinstance(perm, Permission): perm = perm.split('.')[-1] if isinstance(obj, QuerySet): if user: model = get_user_obj_perms_model(obj.model) return model.objects.bulk_remove_perm(perm, user, obj) if group: model = get_group_obj_perms_model(obj.model) return model.objects.bulk_remove_perm(perm, group, obj) if user: model = get_user_obj_perms_model(obj) return model.objects.remove_perm(perm, user, obj) if group: model = get_group_obj_perms_model(obj) return model.objects.remove_perm(perm, group, obj)
def assign(perm, user_or_group, obj): """ Assigns permission to user/group and object pair. :param perm: proper permission for given ``obj``, as string (*codename*) :param user_or_group: instance of ``User``, ``AnonymousUser`` or ``Group``; passing any other object would raise ``guardian.exceptions.NotUserNorGroup`` exception :param obj: persisted Django's ``Model`` instance We can assign permission for ``Model`` instance for specific user: >>> from django.contrib.sites.models import Site >>> from django.contrib.auth.models import User, Group >>> from guardian.shortcuts import assign >>> site = Site.objects.get_current() >>> user = User.objects.create(username='******') >>> assign("change_site", user, site) <UserObjectPermission: example.com | joe | change_site> >>> user.has_perm("change_site", site) True ... or we can assign permission for group: >>> group = Group.objects.create(name='joe-group') >>> user.groups.add(group) >>> assign("delete_site", group, site) <GroupObjectPermission: example.com | joe-group | delete_site> >>> user.has_perm("delete_site", site) True """ perm = perm.split('.')[-1] user, group = get_identity(user_or_group) if user: return UserObjectPermission.objects.assign(perm, user, obj) if group: return GroupObjectPermission.objects.assign(perm, group, obj)
def remove_perm(perm, user_or_group=None, obj=None): """ Removes permission from user/group and object pair. :param perm: proper permission for given ``obj``, as string (in format: ``app_label.codename`` or ``codename``). If ``obj`` is not given, must be in format ``app_label.codename``. :param user_or_group: instance of ``User``, ``AnonymousUser`` or ``Group``; passing any other object would raise ``guardian.exceptions.NotUserNorGroup`` exception :param obj: persisted Django's ``Model`` instance or ``None`` if assigning global permission. Default is ``None``. """ user, group = get_identity(user_or_group) if obj is None: try: app_label, codename = perm.split('.', 1) except ValueError: raise ValueError("For global permissions, first argument must be in" " format: 'app_label.codename' (is %r)" % perm) if user: user_perm_list = UserPermissionList.objects.get(user=user) user_perm_list.permission_list.remove(perm) user_perm_list.save() return elif group: group_perm_list = GroupPermissionList.objects.get(group=group) group_perm_list.permission_list.remove(perm) group_perm_list.save() return perm = perm.split('.')[-1] if user: UserObjectPermission.objects.remove_perm(perm, user, obj) if group: GroupObjectPermission.objects.remove_perm(perm, group, obj)
def remove_perm(perm, user_or_group=None, obj=None): """ Removes permission from user/group and object pair. :param perm: proper permission for given ``obj``, as string (in format: ``app_label.codename`` or ``codename``). If ``obj`` is not given, must be in format ``app_label.codename``. :param user_or_group: instance of ``User``, ``AnonymousUser`` or ``Group``; passing any other object would raise ``guardian.exceptions.NotUserNorGroup`` exception :param obj: persisted Django's ``Model`` instance or ``None`` if assigning global permission. Default is ``None``. """ user, group = get_identity(user_or_group) if obj is None: try: app_label, codename = perm.split('.', 1) except ValueError: raise ValueError("For global permissions, first argument must be in" " format: 'app_label.codename' (is %r)" % perm) perm = Permission.objects.get(content_type__app_label=app_label, codename=codename) if user: user.user_permissions.remove(perm) return elif group: group.permissions.remove(perm) return perm = perm.split('.')[-1] if user: model = get_user_obj_perms_model(obj) model.objects.remove_perm(perm, user, obj) if group: model = get_group_obj_perms_model(obj) model.objects.remove_perm(perm, group, obj)
def bulk_remove_perms(perms, user_or_group, objects): """ Deletes permissions in bulk. :param perms single Permission or list of Permissions :param user_or_group, django.contrib.auth.models User or Group object :param group single, list, tuple or queryset of objects (same type) """ if not isinstance(perms, (types.ListType, types.TupleType)): perms = list(perms) if not isinstance(objects, (types.ListType, types.TupleType)) and not isinstance(objects, QuerySet): objects = list(objects) if len(objects) == 0: return user, group = get_identity(user_or_group) ctype = ContentType.objects.get_for_model(objects[0]) objects = [object.pk for object in objects] if user: UserObjectPermission.objects.filter(permission__codename__in = perms, user = user, object_pk__in = objects, content_type = ctype).delete() if group: GroupObjectPermission.objects.filter(permission__codename__in = perms, group = group, object_pk__in = objects, content_type = ctype).delete()
def test_multiple_user_list(self): user, group = get_identity([self.user]) self.assertIsInstance(user, list) self.assertIsNone(group)
def get_user_group_perms(user_or_group, obj): """Get permissins for user groups. Based on guardian.core.ObjectPermissionChecker. """ user, group = get_identity(user_or_group) if user and not user.is_active: return [], [] user_model = get_user_model() ctype = ContentType.objects.get_for_model(obj) group_model = get_group_obj_perms_model(obj) group_rel_name = group_model.permission.field.related_query_name() # pylint: disable=no-member if user: user_rel_name = user_model.groups.field.related_query_name() # pylint: disable=no-member group_filters = {user_rel_name: user} else: group_filters = {'pk': group.pk} if group_model.objects.is_generic(): group_filters.update({ '{}__content_type'.format(group_rel_name): ctype, '{}__object_pk'.format(group_rel_name): obj.pk, }) else: group_filters['{}__content_object'.format(group_rel_name)] = obj user_perms, group_perms = [], [] if user: perms_qs = Permission.objects.filter(content_type=ctype) if user.is_superuser: user_perms = list( chain(perms_qs.values_list("codename", flat=True))) else: model = get_user_obj_perms_model(obj) related_name = model.permission.field.related_query_name() # pylint: disable=no-member user_filters = {'{}__user'.format(related_name): user} if model.objects.is_generic(): user_filters.update({ '{}__content_type'.format(related_name): ctype, '{}__object_pk'.format(related_name): obj.pk, }) else: user_filters['{}__content_object'.format(related_name)] = obj user_perms_qs = perms_qs.filter(**user_filters) user_perms = list( chain(user_perms_qs.values_list("codename", flat=True))) group_perms_qs = Group.objects.filter(**group_filters) group_perms = list( chain( group_perms_qs.order_by("pk").values_list( "pk", "name", "{}__permission__codename".format(group_rel_name)))) group_perms = _group_groups(group_perms) return user_perms, group_perms
def assign_perm(perm, user_or_group, obj=None): """ Assigns permission to user/group and object pair. :param perm: proper permission for given ``obj``, as string (in format: ``app_label.codename`` or ``codename``). If ``obj`` is not given, must be in format ``app_label.codename``. :param user_or_group: instance of ``User``, ``AnonymousUser`` or ``Group``; passing any other object would raise ``guardian.exceptions.NotUserNorGroup`` exception :param obj: persisted Django's ``Model`` instance or ``None`` if assigning global permission. Default is ``None``. We can assign permission for ``Model`` instance for specific user: >>> from django.contrib.sites.models import Site >>> from guardian.models import User >>> from guardian.shortcuts import assign_perm >>> site = Site.objects.get_current() >>> user = User.objects.create(username='******') >>> assign_perm("change_site", user, site) <UserObjectPermission: example.com | joe | change_site> >>> user.has_perm("change_site", site) True ... or we can assign permission for group: >>> group = Group.objects.create(name='joe-group') >>> user.groups.add(group) >>> assign_perm("delete_site", group, site) <GroupObjectPermission: example.com | joe-group | delete_site> >>> user.has_perm("delete_site", site) True **Global permissions** This function may also be used to assign standard, *global* permissions if ``obj`` parameter is omitted. Added Permission would be returned in that case: >>> assign_perm("sites.change_site", user) <Permission: sites | site | Can change site> """ user, group = get_identity(user_or_group) # If obj is None we try to operate on global permissions if obj is None: try: app_label, codename = perm.split('.', 1) except ValueError: raise ValueError("For global permissions, first argument must be in" " format: 'app_label.codename' (is %r)" % perm) perm = Permission.objects.get(content_type__app_label=app_label, codename=codename) if user: user.user_permissions.add(perm) return perm if group: group.permissions.add(perm) return perm perm = perm.split('.')[-1] if user: model = get_user_obj_perms_model(obj) return model.objects.assign_perm(perm, user, obj) if group: model = get_group_obj_perms_model(obj) return model.objects.assign_perm(perm, group, obj)
def test_user(self): user, group = get_identity(self.user) self.assertTrue(isinstance(user, User)) self.assertEqual(group, None)
def test_anonymous_user(self): anon = AnonymousUser() user, group = get_identity(anon) self.assertTrue(isinstance(user, User)) self.assertEqual(group, None)
def test_group(self): user, group = get_identity(self.group) self.assertTrue(isinstance(group, Group)) self.assertEqual(user, None)
def assign_perm(perm, user_or_group, obj=None): """ Assigns permission to user/group and object pair. :param perm: proper permission for given ``obj``, as string (in format: ``app_label.codename`` or ``codename``) or ``Permission`` instance. If ``obj`` is not given, must be in format ``app_label.codename`` or ``Permission`` instance. :param user_or_group: instance of ``User``, ``AnonymousUser`` or ``Group``; passing any other object would raise ``guardian.exceptions.NotUserNorGroup`` exception :param obj: persisted Django's ``Model`` instance or QuerySet of Django ``Model`` instances or ``None`` if assigning global permission. Default is ``None``. We can assign permission for ``Model`` instance for specific user: >>> from django.contrib.sites.models import Site >>> from guardian.models import User >>> from guardian.shortcuts import assign_perm >>> site = Site.objects.get_current() >>> user = User.objects.create(username='******') >>> assign_perm("change_site", user, site) <UserObjectPermission: example.com | joe | change_site> >>> user.has_perm("change_site", site) True ... or we can assign permission for group: >>> group = Group.objects.create(name='joe-group') >>> user.groups.add(group) >>> assign_perm("delete_site", group, site) <GroupObjectPermission: example.com | joe-group | delete_site> >>> user.has_perm("delete_site", site) True **Global permissions** This function may also be used to assign standard, *global* permissions if ``obj`` parameter is omitted. Added Permission would be returned in that case: >>> assign_perm("sites.change_site", user) <Permission: sites | site | Can change site> """ user, group = get_identity(user_or_group) # If obj is None we try to operate on global permissions if obj is None: if not isinstance(perm, Permission): try: app_label, codename = perm.split('.', 1) except ValueError: raise ValueError( "For global permissions, first argument must be in" " format: 'app_label.codename' (is %r)" % perm) perm = Permission.objects.get(content_type__app_label=app_label, codename=codename) if user: user.user_permissions.add(perm) return perm if group: group.permissions.add(perm) return perm if not isinstance(perm, Permission): perm = perm.split('.')[-1] if isinstance(obj, QuerySet): if user: model = get_user_obj_perms_model(obj.model) return model.objects.bulk_assign_perm(perm, user, obj) if group: model = get_group_obj_perms_model(obj.model) return model.objects.bulk_assign_perm(perm, group, obj) if user: model = get_user_obj_perms_model(obj) return model.objects.assign_perm(perm, user, obj) if group: model = get_group_obj_perms_model(obj) return model.objects.assign_perm(perm, group, obj)
def test_multiple_group_qs(self): user, group = get_identity(Group.objects.all()) self.assertIsInstance(group, models.QuerySet) self.assertIsNone(user)
def test_multiple_group_list(self): user, group = get_identity([self.group]) self.assertIsInstance(group, list) self.assertIsNone(user)