def get_permitted_objects_uuids(cls, user): if user.is_staff: customer_queryset = cls.objects.all() else: customer_queryset = cls.objects.filter( roles__permission_group__user=user, roles__role_type=CustomerRole.OWNER) return {'customer_uuid': filter_queryset_for_user(customer_queryset, user).values_list('uuid', flat=True)}
def filter(self, request, queryset, view): # Don't apply filter if aggregate is not specified if 'aggregate' not in request.query_params: return queryset serializer = serializers.AggregateSerializer(data=request.query_params) serializer.is_valid(raise_exception=True) aggregates = serializer.get_aggregates(request.user) projects = serializer.get_projects(request.user) querysets = [aggregates, projects] aggregates_ids = list(aggregates.values_list('id', flat=True)) query = {serializer.data['aggregate'] + '__in': aggregates_ids} all_models = models.Resource.get_all_models() + \ models.Service.get_all_models() + \ models.ServiceProjectLink.get_all_models() for model in all_models: qs = model.objects.filter(**query).all() querysets.append(filter_queryset_for_user(qs, request.user)) aggregate_query = Q() for qs in querysets: content_type = ContentType.objects.get_for_model(qs.model) ids = qs.values_list('id', flat=True) aggregate_query |= Q(content_type=content_type, object_id__in=ids) return queryset.filter(aggregate_query)
def get_permitted_objects_uuids(cls, user): """ Return query dictionary to search objects available to user. """ uuids = filter_queryset_for_user(cls.objects.all(), user).values_list('uuid', flat=True) key = core_utils.camel_case_to_underscore(cls.__name__) + '_uuid' return {key: uuids}
def initial(self, request, crm_uuid, *args, **kwargs): super(CRMUserViewSet, self).initial(request, crm_uuid, *args, **kwargs) queryset = filter_queryset_for_user(models.CRM.objects.all(), request.user) self.crm = get_object_or_404(queryset, uuid=crm_uuid) if self.crm.state != models.CRM.States.ONLINE: raise CRMNotOnline( 'Cannot execute user-related operations with CRM if it is not ONLINE' ) self.backend = self.crm.get_backend()
def filtered_for_user(self, user, queryset=None): if queryset is None: queryset = self.get_queryset() query = Q() for model in self.get_available_models(): user_object_ids = filter_queryset_for_user(model.objects.all(), user).values_list('id', flat=True) content_type_id = ContentType.objects.get_for_model(model).id query |= Q(object_id__in=user_object_ids, content_type_id=content_type_id) return queryset.filter(query)
def get_images(self, obj): try: user = self.context['request'].user except (KeyError, AttributeError): return None queryset = filter_queryset_for_user(obj.images.all(), user) images_serializer = TemplateImageSerializer( queryset, many=True, read_only=True, context=self.context) return images_serializer.data
def get_links(user=None, project=None): if user: return [ Link(spl) for model in ServiceProjectLink.get_all_models() for spl in filter_queryset_for_user(model.objects.all(), user) ] if project: return [ Link(spl) for model in ServiceProjectLink.get_all_models() for spl in model.objects.filter(project=project) ] return []
def instance_from_url(url, user=None): """ Restore instance from URL """ # XXX: This circular dependency will be removed then filter_queryset_for_user # will be moved to model manager method from nodeconductor.structure.managers import filter_queryset_for_user url = clear_url(url) match = resolve(url) model = get_model_from_resolve_match(match) queryset = model.objects.all() if user is not None: queryset = filter_queryset_for_user(model.objects.all(), user) return queryset.get(**match.kwargs)
def get_fields(self): fields = super(InstanceBackupRestorationSerializer, self).get_fields() try: request = self.context['view'].request user = request.user except (KeyError, AttributeError): return fields clouds = filter_queryset_for_user(models.Cloud.objects.all(), user) fields['template'].queryset = fields['template'].queryset.filter( images__cloud__in=clouds).distinct() return fields
def filter_alerts_by_aggregate(queryset, aggregate, user, uuid=None): valid_model_choices = { 'project': models.Project, 'customer': models.Customer, } error = '"%s" parameter is not found. Valid choices are: %s.' % ( aggregate, ', '.join(valid_model_choices.keys())) assert (aggregate in valid_model_choices), error aggregate_query = filter_queryset_for_user( valid_model_choices[aggregate].objects, user) if uuid: aggregate_query = aggregate_query.filter(uuid=uuid) aggregates_ids = aggregate_query.values_list('id', flat=True) query = {'%s__in' % aggregate: aggregates_ids} all_models = models.ResourceMixin.get_all_models( ) + models.ServiceProjectLink.get_all_models() if aggregate == 'customer': all_models += models.Service.get_all_models() all_models.append(models.Project) querysets = [aggregate_query] for model in all_models: qs = model.objects.filter(**query).all() querysets.append(filter_queryset_for_user(qs, user)) aggregate_query = Q() for qs in querysets: content_type = ContentType.objects.get_for_model(qs.model) ids = qs.values_list('id', flat=True) aggregate_query |= Q(content_type=content_type, object_id__in=ids) return queryset.filter(aggregate_query)
def filtered_for_user(self, user, queryset=None): from nodeconductor.logging import utils if queryset is None: queryset = self.get_queryset() # XXX: This circular dependency will be removed then filter_queryset_for_user # will be moved to model manager method from nodeconductor.structure.managers import filter_queryset_for_user query = Q() for model in utils.get_loggable_models(): user_object_ids = filter_queryset_for_user(model.objects.all(), user).values_list('id', flat=True) content_type_id = ct_models.ContentType.objects.get_for_model(model).id query |= Q(object_id__in=user_object_ids, content_type_id=content_type_id) return queryset.filter(query)
def filter_queryset(self, request, queryset, view): user_uuid = request.query_params.get('user_uuid') if not user_uuid: return queryset try: uuid.UUID(user_uuid) except ValueError: return queryset.none() try: user = User.objects.get(uuid=user_uuid) except User.DoesNotExist: return queryset.none() return filter_queryset_for_user(queryset, user)
def filter_clouds(clouds, request): related_clouds = clouds.all() try: user = request.user related_clouds = filter_queryset_for_user(related_clouds, user) except AttributeError: pass from nodeconductor.iaas.serializers import BasicCloudSerializer serializer_instance = BasicCloudSerializer(related_clouds, many=True, context={'request': request}) return serializer_instance.data
def get_fields(self): fields = super(InstanceCreateSerializer, self).get_fields() fields['system_volume_size'].required = False try: request = self.context['view'].request user = request.user except (KeyError, AttributeError): return fields fields['ssh_public_key'].queryset = fields['ssh_public_key'].queryset.filter(user=user) clouds = filter_queryset_for_user(models.Cloud.objects.all(), user) fields['template'].queryset = fields['template'].queryset.filter(images__cloud__in=clouds).distinct() return fields
def to_internal_value(self, data): """ Restores model instance from its url """ # XXX: This circular dependency will be removed then filter_queryset_for_user # will be moved to model manager method from nodeconductor.structure.managers import filter_queryset_for_user request = self._get_request() try: url = self._format_url(data) match = resolve(url) model = self._get_model_from_resolve_match(match) queryset = filter_queryset_for_user(model.objects.all(), request.user) obj = queryset.get(**match.kwargs) except (Resolver404, AttributeError, MultipleObjectsReturned, ObjectDoesNotExist): raise serializers.ValidationError("Can`t restore object from url: %s" % data) if model not in self.related_models: raise serializers.ValidationError('%s object does not support such relationship' % str(obj)) return obj
def _get_user_visible_model_instances_ids(self, user, model): queryset = filter_queryset_for_user(model.objects.all(), user) return queryset.values_list('pk', flat=True)
def get_permitted_objects_uuids(cls, user): return { 'project_group_uuid': filter_queryset_for_user(cls.objects.all(), user).values_list('uuid', flat=True) }
def filter_queryset(self, request, queryset, view): return filter_queryset_for_user(queryset, request.user)
def stats(self, request): queryset = filter_queryset_for_user(models.Instance.objects.all(), request.user) if 'customer' in self.request.query_params: queryset = queryset.filter( customer__uuid=self.request.query_params['customer']) ids = [instance.id for instance in queryset] tags = self.queryset.filter(taggit_taggeditem_items__object_id__in=ids) tags_map = { Types.PriceItems.LICENSE_OS: dict(Types.Os.CHOICES), Types.PriceItems.LICENSE_APPLICATION: dict(Types.Applications.CHOICES), } aggregates = self.request.query_params.getlist('aggregate', ['name']) filter_name = self.request.query_params.get('name') filter_type = self.request.query_params.get('type') valid_aggregates = 'name', 'type', 'customer', 'project', 'project_group' for arg in aggregates: if arg not in valid_aggregates: return response.Response( "Licenses statistics can not be aggregated by %s" % arg, status=status.HTTP_400_BAD_REQUEST) tags_aggregate = {} for tag in tags: opts = tag.name.split(':') if opts[0] not in tags_map: continue tag_dict = { 'type': opts[1], 'name': opts[2] if len(opts) == 3 else tags_map[opts[0]][opts[1]], } if filter_name and filter_name != tag_dict['name']: continue if filter_type and filter_type != tag_dict['type']: continue instance = tag.taggit_taggeditem_items.filter( tag=tag).first().content_object tag_dict.update({ 'customer_uuid': instance.customer.uuid.hex, 'customer_name': instance.customer.name, 'customer_abbreviation': instance.customer.abbreviation, 'project_uuid': instance.project.uuid.hex, 'project_name': instance.project.name, }) if instance.project.project_group is not None: tag_dict.update({ 'project_group_uuid': instance.project.project_group.uuid.hex, 'project_group_name': instance.project.project_group.name, }) key = '-'.join([ tag_dict.get(arg) or tag_dict.get('%s_uuid' % arg) for arg in aggregates ]) tags_aggregate.setdefault(key, []) tags_aggregate[key].append(tag_dict) results = [] for group in tags_aggregate.values(): tag = {'count': len(group)} for agr in aggregates: for opt, val in group[0].items(): if opt.startswith(agr): tag[opt] = val results.append(tag) return response.Response(results)
def get_queryset(self): user = self.request.user queryset = super(UserViewSet, self).get_queryset() # ?current current_user = self.request.query_params.get('current') if current_user is not None and not user.is_anonymous(): queryset = User.objects.filter(uuid=user.uuid) # TODO: refactor to a separate endpoint or structure # a special query for all users with assigned privileges that the current user can remove privileges from if (not django_settings.NODECONDUCTOR.get('SHOW_ALL_USERS', True) and not user.is_staff) or \ 'potential' in self.request.query_params: connected_customers_query = models.Customer.objects.all() # is user is not staff, allow only connected customers if not user.is_staff: # XXX: Let the DB cry... connected_customers_query = connected_customers_query.filter( Q(roles__permission_group__user=user) | Q(projects__roles__permission_group__user=user) | Q(project_groups__roles__permission_group__user=user) ).distinct() # check if we need to filter potential users by a customer potential_customer = self.request.query_params.get( 'potential_customer') if potential_customer: connected_customers_query = connected_customers_query.filter( uuid=potential_customer) connected_customers_query = filter_queryset_for_user( connected_customers_query, user) connected_customers = list(connected_customers_query.all()) potential_organization = self.request.query_params.get( 'potential_organization') if potential_organization is not None: potential_organizations = potential_organization.split(',') else: potential_organizations = [] queryset = queryset.filter(is_staff=False).filter( # customer users Q(groups__customerrole__customer__in=connected_customers, ) | Q(groups__projectrole__project__customer__in= connected_customers, ) | Q(groups__projectgrouprole__project_group__customer__in= connected_customers, ) | # users with no role Q( groups__customerrole=None, groups__projectrole=None, groups__projectgrouprole=None, organization_approved=True, organization__in=potential_organizations, )).distinct() organization_claimed = self.request.query_params.get( 'organization_claimed') if organization_claimed is not None: queryset = queryset.exclude(organization__isnull=True).exclude( organization__exact='') if not user.is_staff: queryset = queryset.filter(is_active=True) # non-staff users cannot see staff through rest queryset = queryset.filter(is_staff=False) return queryset