Beispiel #1
0
    def filter_queryset(self, request, queryset, view):
        event_types = request.query_params.getlist('event_type')
        if event_types:
            queryset = queryset.filter(event_type__in=event_types)

        features = request.query_params.getlist('feature')
        if features:
            queryset = queryset.filter(
                event_type__in=expand_event_groups(features))

        if 'scope' in request.query_params:
            field = core_serializers.GenericRelatedField(
                related_models=utils.get_loggable_models())
            field._context = {'request': request}
            scope = field.to_internal_value(request.query_params['scope'])

            # Check permissions
            visible = scope._meta.model.get_permitted_objects(request.user)
            if not visible.filter(pk=scope.pk).exists():
                return queryset.none()

            content_type = ContentType.objects.get_for_model(scope._meta.model)
            events = models.Feed.objects.filter(
                content_type=content_type,
                object_id=scope.id,
            ).values_list('event_id', flat=True)
            queryset = queryset.filter(id__in=events)

        elif not request.user.is_staff and not request.user.is_support:
            # If user is not staff nor support, he is allowed to see
            # events related to particular scope only.
            queryset = queryset.none()

        return queryset
Beispiel #2
0
    def test_author_can_update_event_groups(self, hook):
        event_groups = self.valid_event_groups
        event_types = loggers.expand_event_groups(event_groups)

        self.client.force_authenticate(user=self.author)
        response = self.update_hook(hook, {'event_groups': event_groups})
        self.assertEqual(response.data['event_groups'], set(event_groups))
        self.assertEqual(response.data['event_types'], set(event_types))
Beispiel #3
0
    def test_user_can_subscribe_to_event_groups(self):
        event_groups = self.valid_event_groups
        event_types = loggers.expand_event_groups(event_groups)

        self.client.force_authenticate(user=self.author)
        response = self.client.post(WebHookFactory.get_list_url(), data={
            'event_groups': event_groups,
            'destination_url': 'http://example.com/'
        })
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data['event_groups'], set(event_groups))
        self.assertEqual(response.data['event_types'], set(event_types))
Beispiel #4
0
    def all_event_types(self):
        from waldur_core.logging import loggers

        self_types = set(self.event_types)
        try:
            hook_ct = ct_models.ContentType.objects.get_for_model(self)
            base_types = SystemNotification.objects.get(
                hook_content_type=hook_ct)
        except SystemNotification.DoesNotExist:
            return self_types
        else:
            return (self_types
                    | set(loggers.expand_event_groups(base_types.event_groups))
                    | set(base_types.event_types))
Beispiel #5
0
    def validate(self, attrs):
        if not self.instance and 'event_types' not in attrs and 'event_groups' not in attrs:
            raise serializers.ValidationError(_('Please specify list of event_types or event_groups.'))

        if 'event_groups' in attrs:
            events = list(attrs.get('event_types', []))
            groups = list(attrs.get('event_groups', []))
            events = sorted(set(loggers.expand_event_groups(groups)) | set(events))

            attrs['event_types'] = events
            attrs['event_groups'] = groups

        elif 'event_types' in attrs:
            attrs['event_types'] = list(attrs['event_types'])

        return attrs
Beispiel #6
0
    def filter_queryset(self, request, queryset, view):
        search_text = request.query_params.get(
            settings.api_settings.SEARCH_PARAM, '')
        must_terms = {}
        must_not_terms = {}
        should_terms = {}
        excluded_event_types = set()

        if 'event_type' in request.query_params:
            must_terms['event_type'] = request.query_params.getlist(
                'event_type')

        if 'feature' in request.query_params:
            features = request.query_params.getlist('feature')
            must_terms['event_type'] = expand_event_groups(features)

        # Group events by features in order to prevent large HTTP GET request
        if 'exclude_features' in request.query_params:
            features = request.query_params.getlist('exclude_features')
            excluded_event_types.update(expand_event_groups(features))

        if 'exclude_extra' in request.query_params:
            excluded_event_types.update(expand_event_groups(['update']))

        if not django_settings.DEBUG:
            excluded_event_types.update(expand_event_groups(['debug_only']))

        if excluded_event_types:
            must_not_terms['event_type'] = list(excluded_event_types)

        if 'user_username' in request.query_params:
            must_terms['user_username'] = [
                request.query_params.get('user_username')
            ]

        if 'scope' in request.query_params:
            field = core_serializers.GenericRelatedField(
                related_models=utils.get_loggable_models())
            field._context = {'request': request}
            obj = field.to_internal_value(request.query_params['scope'])

            # XXX: Ilja - disabling this hack and re-opening a ticket. Additional analysis is required for
            # a proper resolution
            # # XXX: hack to prevent leaking customer events
            # permitted_uuids = [uuid.hex for uuids in
            #                    obj.get_permitted_objects_uuids(request.user).values() for uuid in uuids]
            # if obj.uuid.hex not in permitted_uuids:
            #     raise ValidationError('You do not have permission to view events for scope %s'
            #                           % request.query_params['scope'])

            for key, val in obj.filter_by_logged_object().items():
                must_terms[format_raw_field(key)] = [val]

        elif 'scope_type' in request.query_params:
            choices = utils.get_scope_types_mapping()
            try:
                scope_type = choices[request.query_params['scope_type']]
            except KeyError:
                raise ValidationError(
                    _('Scope type "%(value)s" is not valid. Has to be one from list: %(items)s.'
                      ) % dict(value=request.query_params['scope_type'],
                               items=', '.join(choices.keys())))
            else:
                permitted_items = scope_type.get_permitted_objects_uuids(
                    request.user).items()
                if not permitted_items:
                    return EmptyQueryset()
                for field, uuids in permitted_items:
                    must_terms[field] = [uuid.hex for uuid in uuids]

        elif 'resource_type' in request.query_params and 'resource_uuid' in request.query_params:
            # Filter events by resource type and uuid.
            # Please note, that permission checks are skipped,
            # because we can't check permission for deleted resources.
            # Also note, that resource type validation is skipped as well,
            # because resource type name formatting is defined in structure application,
            # but we don't want to create circular dependency between logging and structure apps.
            # This issue could be fixed by switching resource type name formatting to str(model._meta)
            # as it is done for scope_type parameter validation.
            must_terms[format_raw_field('resource_type')] = [
                request.query_params['resource_type']
            ]
            must_terms[format_raw_field('resource_uuid')] = [
                request.query_params['resource_uuid']
            ]

        else:
            should_terms.update(
                event_logger.get_permitted_objects_uuids(request.user))

        mapped = {
            'start': request.query_params.get('from'),
            'end': request.query_params.get('to'),
        }
        timestamp_interval_serializer = core_serializers.TimestampIntervalSerializer(
            data={k: v
                  for k, v in mapped.items() if v})
        timestamp_interval_serializer.is_valid(raise_exception=True)
        filter_data = timestamp_interval_serializer.get_filter_data()

        queryset = queryset.filter(search_text=search_text,
                                   should_terms=should_terms,
                                   must_terms=must_terms,
                                   must_not_terms=must_not_terms,
                                   start=filter_data.get('start'),
                                   end=filter_data.get('end'))

        order_by = request.query_params.get('o', '-@timestamp')
        if order_by:
            queryset = queryset.order_by(order_by)

        return queryset