Exemplo n.º 1
0
class CommentSerializer(JSONAPISerializer):

    filterable_fields = frozenset(
        ['deleted', 'date_created', 'date_modified', 'target'])

    id = IDField(source='_id', read_only=True)
    type = TypeField()
    content = AuthorizedCharField(source='get_content')

    target = TargetField(link_type='related', meta={'type': 'get_target_type'})
    user = RelationshipField(related_view='users:user-detail',
                             related_view_kwargs={'user_id': '<user._id>'})
    node = RelationshipField(related_view='nodes:node-detail',
                             related_view_kwargs={'node_id': '<node._id>'})
    replies = RelationshipField(self_view='comments:comment-replies',
                                self_view_kwargs={'comment_id': '<pk>'})
    reports = RelationshipField(related_view='comments:comment-reports',
                                related_view_kwargs={'comment_id': '<pk>'})

    date_created = ser.DateTimeField(read_only=True)
    date_modified = ser.DateTimeField(read_only=True)
    modified = ser.BooleanField(read_only=True, default=False)
    deleted = ser.BooleanField(read_only=True,
                               source='is_deleted',
                               default=False)

    # LinksField.to_representation adds link to "self"
    links = LinksField({})

    class Meta:
        type_ = 'comments'

    def update(self, comment, validated_data):
        assert isinstance(comment, Comment), 'comment must be a Comment'
        auth = Auth(self.context['request'].user)
        if validated_data:
            if 'get_content' in validated_data:
                comment.edit(validated_data['get_content'],
                             auth=auth,
                             save=True)
            if validated_data.get('is_deleted', None) is True:
                comment.delete(auth, save=True)
            elif comment.is_deleted:
                comment.undelete(auth, save=True)
        return comment

    def get_target_type(self, obj):
        if isinstance(obj, Node):
            return 'nodes'
        elif isinstance(obj, Comment):
            return 'comments'
        else:
            raise InvalidModelValueError(source={
                'pointer':
                '/data/relationships/target/links/related/meta/type'
            },
                                         detail='Invalid comment target type.')
Exemplo n.º 2
0
class FileSerializer(BaseFileSerializer):
    node = ShowIfVersion(
        FileNodeRelationshipField(
            related_view='nodes:node-detail',
            related_view_kwargs={'node_id': '<target._id>'},
            help_text='The project that this file belongs to'
        ),
        min_version='2.0', max_version='2.7'
    )
    target = TargetField(link_type='related', meta={'type': 'get_target_type'})

    def get_target_type(self, obj):
        target_type = 'node'
        if isinstance(obj, PreprintService):
            target_type = 'preprint'
        return target_type
Exemplo n.º 3
0
class CommentSerializer(JSONAPISerializer):

    filterable_fields = frozenset(
        ['deleted', 'date_created', 'date_modified', 'page', 'target'])

    id = IDField(source='_id', read_only=True)
    type = TypeField()
    content = AuthorizedCharField(source='get_content', required=True)
    page = ser.CharField(read_only=True)

    target = TargetField(link_type='related', meta={'type': 'get_target_type'})
    user = RelationshipField(related_view='users:user-detail',
                             related_view_kwargs={'user_id': '<user._id>'})
    reports = RelationshipField(related_view='comments:comment-reports',
                                related_view_kwargs={'comment_id': '<pk>'})

    date_created = DateByVersion(read_only=True)
    date_modified = DateByVersion(read_only=True)
    modified = ser.BooleanField(read_only=True, default=False)
    deleted = ser.BooleanField(read_only=True,
                               source='is_deleted',
                               default=False)
    is_abuse = ser.SerializerMethodField(
        help_text='If the comment has been reported or confirmed.')
    is_ham = ser.SerializerMethodField(
        help_text='Comment has been confirmed as ham.')
    has_report = ser.SerializerMethodField(
        help_text='If the user reported this comment.')
    has_children = ser.SerializerMethodField(
        help_text='Whether this comment has any replies.')
    can_edit = ser.SerializerMethodField(
        help_text='Whether the current user can edit this comment.')

    # LinksField.to_representation adds link to "self"
    links = LinksField({})

    class Meta:
        type_ = 'comments'

    def get_is_ham(self, obj):
        if obj.spam_status == SpamStatus.HAM:
            return True
        return False

    def get_has_report(self, obj):
        user = self.context['request'].user
        if user.is_anonymous():
            return False
        return user._id in obj.reports and not obj.reports[user._id].get(
            'retracted', True)

    def get_is_abuse(self, obj):
        if obj.spam_status == SpamStatus.FLAGGED or obj.spam_status == SpamStatus.SPAM:
            return True
        return False

    def get_can_edit(self, obj):
        user = self.context['request'].user
        if user.is_anonymous():
            return False
        return obj.user._id == user._id and obj.node.can_comment(Auth(user))

    def get_has_children(self, obj):
        return Comment.find(Q('target', 'eq', Guid.load(obj._id))).count() > 0

    def get_absolute_url(self, obj):
        return absolute_reverse(
            'comments:comment-detail',
            kwargs={
                'comment_id':
                obj._id,
                'version':
                self.context['request'].parser_context['kwargs']['version']
            })

    def update(self, comment, validated_data):
        assert isinstance(comment, Comment), 'comment must be a Comment'
        auth = Auth(self.context['request'].user)

        if validated_data:
            if validated_data.get('is_deleted',
                                  None) is False and comment.is_deleted:
                try:
                    comment.undelete(auth, save=True)
                except PermissionsError:
                    raise PermissionDenied(
                        'Not authorized to undelete this comment.')
            elif validated_data.get('is_deleted',
                                    None) is True and not comment.is_deleted:
                try:
                    comment.delete(auth, save=True)
                except PermissionsError:
                    raise PermissionDenied(
                        'Not authorized to delete this comment.')
            elif 'get_content' in validated_data:
                content = validated_data.pop('get_content')
                try:
                    comment.edit(content, auth=auth, save=True)
                except PermissionsError:
                    raise PermissionDenied(
                        'Not authorized to edit this comment.')
                except ValidationValueError as err:
                    raise ValidationError(err.args[0])
        return comment

    def get_target_type(self, obj):
        if not getattr(obj.referent, 'target_type', None):
            raise InvalidModelValueError(source={
                'pointer':
                '/data/relationships/target/links/related/meta/type'
            },
                                         detail='Invalid comment target type.')
        return obj.referent.target_type

    def sanitize_data(self):
        ret = super(CommentSerializer, self).sanitize_data()
        content = self.validated_data.get('get_content', None)
        if content:
            ret['get_content'] = bleach.clean(content)
        return ret
Exemplo n.º 4
0
class CommentSerializer(JSONAPISerializer):

    filterable_fields = frozenset([
        'deleted',
        'date_created',
        'date_modified',
        'target'
    ])

    id = IDField(source='_id', read_only=True)
    type = TypeField()
    content = AuthorizedCharField(source='get_content', required=True, max_length=osf_settings.COMMENT_MAXLENGTH)

    target = TargetField(link_type='related', meta={'type': 'get_target_type'})
    user = RelationshipField(related_view='users:user-detail', related_view_kwargs={'user_id': '<user._id>'})
    node = RelationshipField(related_view='nodes:node-detail', related_view_kwargs={'node_id': '<node._id>'})
    replies = RelationshipField(self_view='comments:comment-replies', self_view_kwargs={'comment_id': '<pk>'})
    reports = RelationshipField(related_view='comments:comment-reports', related_view_kwargs={'comment_id': '<pk>'})

    date_created = ser.DateTimeField(read_only=True)
    date_modified = ser.DateTimeField(read_only=True)
    modified = ser.BooleanField(read_only=True, default=False)
    deleted = ser.BooleanField(read_only=True, source='is_deleted', default=False)
    is_abuse = ser.SerializerMethodField(help_text='Whether the current user reported this comment.')
    has_children = ser.SerializerMethodField(help_text='Whether this comment has any replies.')
    can_edit = ser.SerializerMethodField(help_text='Whether the current user can edit this comment.')

    # LinksField.to_representation adds link to "self"
    links = LinksField({})

    class Meta:
        type_ = 'comments'

    def validate_content(self, value):
        if value is None or not value.strip():
            raise ValidationError('Comment cannot be empty.')
        return value

    def get_is_abuse(self, obj):
        user = self.context['request'].user
        if user.is_anonymous():
            return False
        return user._id in obj.reports

    def get_can_edit(self, obj):
        user = self.context['request'].user
        if user.is_anonymous():
            return False
        return obj.user._id == user._id

    def get_has_children(self, obj):
        return bool(getattr(obj, 'commented', []))

    def update(self, comment, validated_data):
        assert isinstance(comment, Comment), 'comment must be a Comment'
        auth = Auth(self.context['request'].user)
        if validated_data:
            if 'get_content' in validated_data:
                content = validated_data.pop('get_content')
                try:
                    comment.edit(content, auth=auth, save=True)
                except PermissionsError:
                    raise PermissionDenied('Not authorized to edit this comment.')
            if validated_data.get('is_deleted', None) is True:
                try:
                    comment.delete(auth, save=True)
                except PermissionsError:
                    raise PermissionDenied('Not authorized to delete this comment.')
            elif comment.is_deleted:
                try:
                    comment.undelete(auth, save=True)
                except PermissionsError:
                    raise PermissionDenied('Not authorized to undelete this comment.')
        return comment

    def get_target_type(self, obj):
        if isinstance(obj, Node):
            return 'nodes'
        elif isinstance(obj, Comment):
            return 'comments'
        else:
            raise InvalidModelValueError(
                source={'pointer': '/data/relationships/target/links/related/meta/type'},
                detail='Invalid comment target type.'
            )
Exemplo n.º 5
0
class CommentSerializer(JSONAPISerializer):

    filterable_fields = frozenset(
        ['deleted', 'date_created', 'date_modified', 'page', 'target'])

    id = IDField(source='_id', read_only=True)
    type = TypeField()
    content = AuthorizedCharField(source='get_content',
                                  required=True,
                                  max_length=osf_settings.COMMENT_MAXLENGTH)
    page = ser.CharField(read_only=True)

    target = TargetField(link_type='related', meta={'type': 'get_target_type'})
    user = RelationshipField(related_view='users:user-detail',
                             related_view_kwargs={'user_id': '<user._id>'})
    node = RelationshipField(related_view='nodes:node-detail',
                             related_view_kwargs={'node_id': '<node._id>'})
    replies = RelationshipField(self_view='nodes:node-comments',
                                self_view_kwargs={'node_id': '<node._id>'},
                                filter={'target': '<pk>'})
    reports = RelationshipField(related_view='comments:comment-reports',
                                related_view_kwargs={'comment_id': '<pk>'})

    date_created = ser.DateTimeField(read_only=True)
    date_modified = ser.DateTimeField(read_only=True)
    modified = ser.BooleanField(read_only=True, default=False)
    deleted = ser.BooleanField(read_only=True,
                               source='is_deleted',
                               default=False)
    is_abuse = ser.SerializerMethodField(
        help_text='Whether the current user reported this comment.')
    has_children = ser.SerializerMethodField(
        help_text='Whether this comment has any replies.')
    can_edit = ser.SerializerMethodField(
        help_text='Whether the current user can edit this comment.')

    # LinksField.to_representation adds link to "self"
    links = LinksField({})

    class Meta:
        type_ = 'comments'

    def get_is_abuse(self, obj):
        user = self.context['request'].user
        if user.is_anonymous():
            return False
        return user._id in obj.reports and not obj.reports[user._id].get(
            'retracted', True)

    def get_can_edit(self, obj):
        user = self.context['request'].user
        if user.is_anonymous():
            return False
        return obj.user._id == user._id and obj.node.can_comment(Auth(user))

    def get_has_children(self, obj):
        return Comment.find(Q('target', 'eq', Guid.load(obj._id))).count() > 0

    def get_absolute_url(self, obj):
        return absolute_reverse('comments:comment-detail',
                                kwargs={'comment_id': obj._id})
        # return self.data.get_absolute_url()

    def update(self, comment, validated_data):
        assert isinstance(comment, Comment), 'comment must be a Comment'
        auth = Auth(self.context['request'].user)
        if validated_data:
            if validated_data.get('is_deleted',
                                  None) is False and comment.is_deleted:
                try:
                    comment.undelete(auth, save=True)
                except PermissionsError:
                    raise PermissionDenied(
                        'Not authorized to undelete this comment.')
            elif 'get_content' in validated_data:
                content = validated_data.pop('get_content')
                try:
                    comment.edit(content, auth=auth, save=True)
                except PermissionsError:
                    raise PermissionDenied(
                        'Not authorized to edit this comment.')
        return comment

    def get_target_type(self, obj):
        if isinstance(obj.referent, Node):
            return 'nodes'
        elif isinstance(obj.referent, Comment):
            return 'comments'
        elif isinstance(obj.referent, StoredFileNode):
            return 'files'
        else:
            raise InvalidModelValueError(source={
                'pointer':
                '/data/relationships/target/links/related/meta/type'
            },
                                         detail='Invalid comment target type.')

    def sanitize_data(self):
        ret = super(CommentSerializer, self).sanitize_data()
        content = self.validated_data.get('get_content', None)
        if content:
            ret['get_content'] = bleach.clean(content)
        return ret