Пример #1
0
class RatingSerializer(serializers.ModelSerializer):
    app = SplitField(
        SlugOrPrimaryKeyRelatedField(slug_field='app_slug',
                                     queryset=Webapp.objects.all(),
                                     source='addon'),
        serializers.HyperlinkedRelatedField(view_name='app-detail',
                                            read_only=True,
                                            source='addon'))
    body = serializers.CharField()
    user = AccountSerializer(read_only=True)
    report_spam = serializers.SerializerMethodField('get_report_spam_link')
    resource_uri = serializers.HyperlinkedIdentityField(
        view_name='ratings-detail')
    is_author = serializers.SerializerMethodField('get_is_author')
    has_flagged = serializers.SerializerMethodField('get_has_flagged')
    version = SimpleVersionSerializer(read_only=True)

    class Meta:
        model = Review
        fields = ('app', 'body', 'created', 'has_flagged', 'is_author',
                  'modified', 'rating', 'report_spam', 'resource_uri', 'user',
                  'version')

    def __init__(self, *args, **kwargs):
        super(RatingSerializer, self).__init__(*args, **kwargs)
        if 'request' in self.context:
            self.request = self.context['request']
        else:
            self.request = None

        if not self.request or not self.request.amo_user:
            self.fields.pop('is_author')
            self.fields.pop('has_flagged')

        if self.request and self.request.method in ('PUT', 'PATCH'):
            # Don't let users modify 'app' field at edit time
            self.fields['app'].read_only = True

    def get_report_spam_link(self, obj):
        return reverse('ratings-flag', kwargs={'pk': obj.pk})

    def get_is_author(self, obj):
        return obj.user.pk == self.request.amo_user.pk

    def get_has_flagged(self, obj):
        return (not self.get_is_author(obj) and
                obj.reviewflag_set.filter(user=self.request.amo_user).exists())

    def validate(self, attrs):
        if not getattr(self, 'object'):
            # If we are creating a rating, then we need to do various checks on
            # the app. Because these checks need the version as well, we have
            # to do them here and not in validate_app().

            # Assign user and ip_address. It won't change once the review is
            # created.
            attrs['user'] = self.request.amo_user
            attrs['ip_address'] = self.request.META.get('REMOTE_ADDR', '')

            # If the app is packaged, add in the current version.
            if attrs['addon'].is_packaged:
                attrs['version'] = attrs['addon'].current_version

            # Return 409 if the user has already reviewed this app.
            app = attrs['addon']
            amo_user = self.request.amo_user
            qs = self.context['view'].queryset.filter(addon=app, user=amo_user)
            if app.is_packaged:
                qs = qs.filter(version=attrs['version'])
            if qs.exists():
                raise Conflict('You have already reviewed this app.')

            # Return 403 is the app is not public.
            if not app.is_public():
                raise PermissionDenied('The app requested is not public.')

            # Return 403 if the user is attempting to review their own app.
            if app.has_author(amo_user):
                raise PermissionDenied('You may not review your own app.')

            # Return 403 if not a free app and the user hasn't purchased it.
            if app.is_premium() and not app.is_purchased(amo_user):
                raise PermissionDenied("You may not review paid apps you "
                                       "haven't purchased.")

            # Return 403 if the app is not available in the current region.
            current_region = get_region()
            if not app.listed_in(region=current_region):
                raise PermissionDenied('App not available in region "%s".' %
                                       current_region.slug)

        return attrs

    def validate_app(self, attrs, source):
        # Don't allow users to change the app on an existing rating.
        if getattr(self, 'object'):
            attrs[source] = self.object.addon
        return attrs
Пример #2
0
 def serializer(self):
     return AccountSerializer(instance=self.account)
Пример #3
0
class RatingSerializer(serializers.ModelSerializer):
    app = SplitField(
        SlugOrPrimaryKeyRelatedField(slug_field='app_slug',
                                     queryset=Webapp.objects.all(),
                                     source='addon'),
        serializers.HyperlinkedRelatedField(view_name='app-detail',
                                            read_only=True,
                                            source='addon'))
    body = serializers.CharField()
    user = AccountSerializer(read_only=True)
    report_spam = serializers.SerializerMethodField('get_report_spam_link')
    resource_uri = serializers.HyperlinkedIdentityField(
        view_name='ratings-detail')
    is_author = serializers.SerializerMethodField('get_is_author')
    has_flagged = serializers.SerializerMethodField('get_has_flagged')
    version = SimpleVersionSerializer(read_only=True)

    class Meta:
        model = Review
        fields = ('app', 'body', 'created', 'has_flagged', 'is_author',
                  'modified', 'rating', 'report_spam', 'resource_uri', 'user',
                  'version')

    def __init__(self, *args, **kwargs):
        super(RatingSerializer, self).__init__(*args, **kwargs)
        if 'request' in self.context:
            self.request = self.context['request']
        else:
            self.request = None

        if not self.request or not self.request.amo_user:
            self.fields.pop('is_author')
            self.fields.pop('has_flagged')

        if self.request.method in ('PUT', 'PATCH'):
            # Don't let users modify 'app' field at edit time
            self.fields['app'].read_only = True

    def get_report_spam_link(self, obj):
        return reverse('ratings-flag', kwargs={'pk': obj.pk})

    def get_is_author(self, obj):
        return obj.user.pk == self.request.amo_user.pk

    def get_has_flagged(self, obj):
        return (not self.get_is_author(obj) and
                obj.reviewflag_set.filter(user=self.request.amo_user).exists())

    @classmethod
    def get_app_from_value(cls, value):
        try:
            app = Webapp.objects.valid().get(id=value)
        except (Webapp.DoesNotExist, ValueError):
            try:
                app = Webapp.objects.valid().get(app_slug=value)
            except Webapp.DoesNotExist:
                raise serializers.ValidationError('Invalid app')
        if not app.listed_in(region=REGIONS_DICT[get_region()]):
            raise serializers.ValidationError(
                'App not available in this region')
        return app

    def validate(self, attrs):
        attrs['user'] = self.request.amo_user
        attrs['ip_address'] = self.request.META.get('REMOTE_ADDR', '')

        if not getattr(self, 'object'):
            if attrs['addon'].is_packaged:
                attrs['version'] = attrs['addon'].current_version

            # Return 409 if the user has already reviewed this app.
            app = attrs['addon']
            amo_user = self.request.amo_user
            qs = self.context['view'].queryset.filter(addon=app, user=amo_user)
            if app.is_packaged:
                qs = qs.filter(version=attrs['version'])

            if qs.exists():
                raise Conflict('You have already reviewed this app.')

            # Return 403 if the user is attempting to review their own app:
            if app.has_author(amo_user):
                raise PermissionDenied('You may not review your own app.')

            # Return 403 if not a free app and the user hasn't purchased it.
            if app.is_premium() and not app.is_purchased(amo_user):
                raise PermissionDenied("You may not review paid apps you "
                                       "haven't purchased.")
        return attrs

    def validate_app(self, attrs, source):
        if not getattr(self, 'object'):
            app = attrs[source]
            attrs[source] = RatingSerializer.get_app_from_value(app.pk)
        else:
            attrs[source] = self.object.addon
        return attrs