def _bulk_assign_contributor_permission(content_type, pks, user): """Assign all available permissions on given objects to given user. Objects are determined by the combination of the content type and a list of primary keys. :param content_type: Content type of objects to process. :type content_type: `~django.contrib.auth.models.ContentType` :param list pks: List of primary keys of objects to process. :param user: A Django user to which permissions should be assigned. :type contributor: `~django.contrib.auth.models.User` """ permissions = Permission.objects.filter(content_type=content_type) new_permissions = [] for permission in permissions: for pk in pks: new_permissions.append( UserObjectPermission( content_type=content_type, object_pk=pk, permission=permission, user=user, )) UserObjectPermission.objects.bulk_create(new_permissions, ignore_conflicts=True)
def grant_permissions(self, request): user_id = request.data.get('user') or request.data.get('user_id') or '' content_type_id = request.data.get('content_type') or request.data.get( 'content_type_id') or '' permission_id = request.data.get('permission') or request.data.get( 'permission_id') or '' user = get_object_or_404(get_user_model(), id=user_id) content_type = get_object_or_404(ContentType, id=content_type_id) permission = get_object_or_404(Permission, id=permission_id) UserObjectPermission.objects.filter(user=user, content_type=content_type, permission=permission).delete() object_pks = request.data.get('object_pks') or [] objs = content_type.get_all_objects_for_this_type(id__in=object_pks) items = [] for obj in objs: items.append( UserObjectPermission(user=user, content_type=content_type, permission=permission, object_pk=obj.id)) UserObjectPermission.objects.bulk_create(items) return Response(status=status.HTTP_204_NO_CONTENT)
def save_model(self, request, obj, form, change): super(GlossaryAdmin, self).save_model(request, obj, form, change) if form.is_valid() and form.has_changed(): cleaned_data = form.cleaned_data permission_holders = form.get_collaborators() staff_ids = set() # Naive use of guardian shortcuts can cause O(n) queries, so we do # most of this ourselves. ctype = get_content_type(obj) for name, perm_name in [ ("specialists", "specialist"), ("terminologists", "terminologist"), ("owners", "owner"), ]: if name in form.changed_data: add_ids = set() remove_ids = set() perm = Permission.objects.get(content_type=ctype, codename=perm_name) old_terminologists = permission_holders[name] new_terminologists = set(cleaned_data[name]) for user in new_terminologists - old_terminologists: add_ids.add(user.pk) if name in ("terminologist", "owners"): # terminologists don't need staff status staff_ids.add(user.pk) for user in old_terminologists - new_terminologists: remove_ids.add(user.pk) UserObjectPermission.objects.bulk_create([ UserObjectPermission( content_type=ctype, object_pk=obj.pk, permission=perm, user_id=_id, ) for _id in add_ids ]) UserObjectPermission.objects.filter( content_type=ctype, object_pk=obj.pk, permission=perm, user_id__in=remove_ids, ).delete() User.objects.filter(id__in=staff_ids).update(is_staff=True)
def assign_applicable_kc_permissions(obj, user, kpi_codenames): r""" Assign the `user` the applicable KC permissions to `obj`, if any exists, given one KPI permission codename as a single string or many codenames as an iterable. If `obj` is not a :py:class:`Asset` or does not have a deployment, take no action. :param obj: Any Django model instance :type user: :py:class:`User` or :py:class:`AnonymousUser` :type kpi_codenames: str or list(str) """ if not obj._meta.model_name == 'asset': return permissions = _get_applicable_kc_permissions(obj, kpi_codenames) if not permissions: return xform_id = _get_xform_id_for_asset(obj) if not xform_id: return if user.is_anonymous() or user.pk == settings.ANONYMOUS_USER_ID: return set_kc_anonymous_permissions_xform_flags( obj, kpi_codenames, xform_id) xform_content_type = ContentType.objects.get(**obj.KC_CONTENT_TYPE_KWARGS) kc_permissions_already_assigned = UserObjectPermission.objects.filter( user=user, permission__in=permissions, object_pk=xform_id, ).values_list('permission__codename', flat=True) permissions_to_create = [] for permission in permissions: # Since `logger` isn't in `INSTALLED_APPS`, `get_or_create()` raises # `AttributeError: 'NoneType' object has no attribute '_base_manager'`. # We hack around this with `bulk_create()`, which bypasses # `UserObjectPermission.save()` if permission.codename in kc_permissions_already_assigned: continue permissions_to_create.append( UserObjectPermission(user=user, permission=permission, object_pk=xform_id, content_type=xform_content_type)) UserObjectPermission.objects.bulk_create(permissions_to_create)