Example #1
0
 def setUp(self):
     super(TestSpamListView, self).setUp()
     Comment.remove()
     self.project = ProjectFactory(is_public=True)
     self.user_1 = AuthUserFactory()
     self.user_2 = AuthUserFactory()
     self.project.add_contributor(self.user_1)
     self.project.add_contributor(self.user_2)
     self.project.save()
     self.user_1.save()
     self.user_2.save()
     date = datetime.utcnow()
     self.comment_1 = CommentFactory(node=self.project, user=self.user_1)
     self.comment_2 = CommentFactory(node=self.project, user=self.user_1)
     self.comment_3 = CommentFactory(node=self.project, user=self.user_1)
     self.comment_4 = CommentFactory(node=self.project, user=self.user_1)
     self.comment_5 = CommentFactory(node=self.project, user=self.user_2)
     self.comment_6 = CommentFactory(node=self.project, user=self.user_2)
     self.comment_1.report_abuse(user=self.user_2, save=True, category="spam", date=date - timedelta(seconds=5))
     self.comment_2.report_abuse(user=self.user_2, save=True, category="spam", date=date - timedelta(seconds=4))
     self.comment_3.report_abuse(user=self.user_2, save=True, category="spam", date=date - timedelta(seconds=3))
     self.comment_4.report_abuse(user=self.user_2, save=True, category="spam", date=date - timedelta(seconds=2))
     self.comment_5.report_abuse(user=self.user_1, save=True, category="spam", date=date - timedelta(seconds=1))
     self.comment_6.report_abuse(user=self.user_1, save=True, category="spam")
     self.request = RequestFactory().get("/fake_path")
     self.view = SpamList()
     self.view = setup_view(self.view, self.request, user_id=self.user_1._id)
Example #2
0
 def setUp(self):
     super(TestMigrateSpam, self).setUp()
     self.generic_report = {
         'category': 'spam',
         'text': 'spammer spam',
         'date': datetime.utcnow(),
         'retracted': False
     }
     Comment.remove()
     self.user = AuthUserFactory()
     self.comment_1 = CommentFactory()
     self.comment_1.spam_status = 0
     self.comment_1.reports[self.user._id] = self.generic_report
     self.comment_1.save()
     self.comment_2 = CommentFactory()
     self.comment_2.spam_status = 0
     self.comment_2.reports[self.user._id] = self.generic_report
     self.comment_2.save()
     self.comment_3 = CommentFactory()
     self.comment_3.spam_status = 0
     self.comment_3.save()
     self.comment_4 = CommentFactory()
     self.comment_4.date_last_reported = None
     self.comment_4.spam_status = Comment.FLAGGED
     self.comment_4.reports[self.user._id] = self.generic_report
     self.comment_4.save()
     self.comment_5 = CommentFactory()
     self.comment_5.date_last_reported = None
     self.comment_5.spam_status = Comment.UNKNOWN
     self.comment_5.save()
     self.comment_6 = CommentFactory()
     self.comment_6.date_last_reported = None
     self.comment_6.spam_status = Comment.SPAM
     self.comment_6.reports[self.user._id] = self.generic_report
     self.comment_6.save()
Example #3
0
    def get_comment(self, check_permissions=True):
        pk = self.kwargs[self.comment_lookup_url_kwarg]
        try:
            comment = Comment.find_one(Q('_id', 'eq', pk) & Q('root_target', 'ne', None))
        except NoResultsFound:
            raise NotFound

        # Deleted root targets still appear as tuples in the database and are included in
        # the above query, requiring an additional check
        if isinstance(comment.root_target.referent, TrashedFileNode):
            comment.root_target = None
            comment.save()

        if comment.root_target is None:
            raise NotFound

        if isinstance(comment.root_target.referent, StoredFileNode):
            root_target = comment.root_target
            referent = root_target.referent

            if referent.provider == 'osfstorage':
                try:
                    StoredFileNode.find(
                        Q('node', 'eq', comment.node._id) &
                        Q('_id', 'eq', referent._id) &
                        Q('is_file', 'eq', True)
                    )
                except NoResultsFound:
                    Comment.update(Q('root_target', 'eq', root_target), data={'root_target': None})
                    raise NotFound
            else:
                if referent.provider == 'dropbox':
                    # referent.path is the absolute path for the db file, but wb requires the relative path
                    referent = DropboxFile.load(referent._id)
                url = waterbutler_api_url_for(comment.node._id, referent.provider, referent.path, meta=True)
                waterbutler_request = requests.get(
                    url,
                    cookies=self.request.COOKIES,
                    headers={'Authorization': self.request.META.get('HTTP_AUTHORIZATION')},
                )

                if waterbutler_request.status_code == 401:
                    raise PermissionDenied

                if waterbutler_request.status_code == 404:
                    Comment.update(Q('root_target', 'eq', root_target), data={'root_target': None})
                    raise NotFound

                if is_server_error(waterbutler_request.status_code):
                    raise ServiceUnavailableError(detail='Could not retrieve files information at this time.')

                try:
                    waterbutler_request.json()['data']
                except KeyError:
                    raise ServiceUnavailableError(detail='Could not retrieve files information at this time.')

        if check_permissions:
            # May raise a permission denied
            self.check_object_permissions(self.request, comment)
        return comment
Example #4
0
    def test_comments_move_when_folder_moved_to_different_provider(self, destination_provider, destination_path):
        if self.provider == destination_provider:
            return True

        self.project.add_addon(destination_provider, auth=Auth(self.user))
        self.project.save()
        self.addon_settings = self.project.get_addon(destination_provider)
        self.addon_settings.folder = '/AddonFolder'
        self.addon_settings.save()

        source = {
            'path': '/subfolder/',
            'node': self.project,
            'provider': self.provider
        }
        destination = {
            'path': '/subfolder/',
            'node': self.project,
            'provider': destination_provider,
            'children': [{
                    'path': '/subfolder/file.txt',
                    'node': self.project,
                    'provider': destination_provider
            }]
        }
        file_name = 'file.txt'
        self._create_file_with_comment(node=source['node'], path='{}{}'.format(source['path'], file_name))
        payload = self._create_payload('move', self.user, source, destination, self.file._id)
        update_file_guid_referent(self=None, node=destination['node'], event_type='addon_file_moved', payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class(destination_provider, FileNode.FILE).get_or_create(destination['node'], destination_path)
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q('root_target', 'eq', self.guid._id))
        assert_equal(file_comments.count(), 1)
Example #5
0
 def get_queryset(self):
     query = (
         Q('reports', 'ne', {}) &
         Q('reports', 'ne', None) &
         Q('spam_status', 'eq', int(self.request.GET.get('status', '1')))
     )
     return Comment.find(query).sort(self.ordering)
Example #6
0
 def get_queryset(self):
     query = (
         Q("reports", "ne", {})
         & Q("reports", "ne", None)
         & Q("spam_status", "eq", int(self.request.GET.get("status", "1")))
     )
     return Comment.find(query).sort(self.ordering)
Example #7
0
 def form_valid(self, form):
     spam_id = self.kwargs.get('spam_id')
     item = Comment.load(spam_id)
     try:
         if int(form.cleaned_data.get('confirm')) == Comment.SPAM:
             item.confirm_spam()
             item.is_deleted = True
             log_message = 'Confirmed SPAM: {}'.format(spam_id)
             log_action = CONFIRM_SPAM
         else:
             item.confirm_ham()
             item.is_deleted = False
             log_message = 'Confirmed HAM: {}'.format(spam_id)
             log_action = CONFIRM_HAM
         item.save()
     except AttributeError:
         raise Http404('Spam with id "{}" not found.'.format(spam_id))
     update_admin_log(
         user_id=self.request.user.id,
         object_id=spam_id,
         object_repr='Comment',
         message=log_message,
         action_flag=log_action
     )
     return super(SpamDetail, self).form_valid(form)
Example #8
0
 def get_context_data(self, **kwargs):
     item = Comment.load(self.kwargs.get('spam_id'))
     kwargs = super(SpamDetail, self).get_context_data(**kwargs)
     kwargs.setdefault('page_number', self.request.GET.get('page', 1))
     kwargs.setdefault('comment', serialize_comment(item))
     kwargs.setdefault('status', self.request.GET.get('status', u'1'))
     return kwargs
Example #9
0
    def test_comments_move_when_file_moved_to_osfstorage(self):
        osfstorage = self.project.get_addon('osfstorage')
        root_node = osfstorage.get_root()
        osf_file = root_node.append_file('file.txt')
        osf_file.create_version(self.user, {
            'object': '06d80e',
            'service': 'cloud',
            osfstorage_settings.WATERBUTLER_RESOURCE: 'osf',
        }, {
            'size': 1337,
            'contentType': 'img/png',
            'etag': 'abcdefghijklmnop'
        }).save()

        source = {
            'path': '/file.txt',
            'node': self.project,
            'provider': self.provider
        }
        destination = {
            'path': osf_file.path,
            'node': self.project,
            'provider': 'osfstorage'
        }
        self._create_file_with_comment(node=source['node'], path=source['path'])
        payload = self._create_payload('move', self.user, source, destination, self.file._id, destination_file_id=destination['path'].strip('/'))
        update_file_guid_referent(self=None, node=destination['node'], event_type='addon_file_moved', payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class('osfstorage', FileNode.FILE).get_or_create(destination['node'], destination['path'])
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q('root_target', 'eq', self.guid._id))
        assert_equal(file_comments.count(), 1)
Example #10
0
    def get_paginated_response(self, data):
        """Add number of unread comments to links.meta when viewing list of comments filtered by
        a target node, file or wiki page."""
        response = super(CommentPagination, self).get_paginated_response(data)
        response_dict = response.data
        kwargs = self.request.parser_context['kwargs'].copy()

        if self.request.query_params.get('related_counts', False):
            target_id = self.request.query_params.get('filter[target]', None)
            node_id = kwargs.get('node_id', None)
            node = Node.load(node_id)
            user = self.request.user
            if target_id and not user.is_anonymous() and node.is_contributor(user):
                root_target = Guid.load(target_id)
                if root_target:
                    page = getattr(root_target.referent, 'root_target_page', None)
                    if page:
                        if not len(data):
                            unread = 0
                        else:
                            unread = Comment.find_n_unread(user=user, node=node, page=page, root_id=target_id)
                        if self.request.version < '2.1':
                            response_dict['links']['meta']['unread'] = unread
                        else:
                            response_dict['meta']['unread'] = unread
        return Response(response_dict)
Example #11
0
    def test_comments_move_when_folder_moved_to_different_provider(self, destination_provider, destination_path):
        if self.provider == destination_provider:
            return True

        self.project.add_addon(destination_provider, auth=Auth(self.user))
        self.project.save()
        self.addon_settings = self.project.get_addon(destination_provider)
        self.addon_settings.folder = "/AddonFolder"
        self.addon_settings.save()

        source = {"path": "/subfolder/", "node": self.project, "provider": self.provider}
        destination = {
            "path": "/subfolder/",
            "node": self.project,
            "provider": destination_provider,
            "children": [{"path": "/subfolder/file.txt", "node": self.project, "provider": destination_provider}],
        }
        file_name = "file.txt"
        self._create_file_with_comment(node=source["node"], path="{}{}".format(source["path"], file_name))
        payload = self._create_payload("move", self.user, source, destination, self.file._id)
        update_file_guid_referent(self=None, node=destination["node"], event_type="addon_file_moved", payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class(destination_provider, FileNode.FILE).get_or_create(
            destination["node"], destination_path
        )
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q("root_target", "eq", self.guid._id))
        assert_equal(file_comments.count(), 1)
Example #12
0
    def test_comments_move_when_folder_moved_to_osfstorage(self):
        osfstorage = self.project.get_addon("osfstorage")
        root_node = osfstorage.get_root()
        osf_folder = root_node.append_folder("subfolder")
        osf_file = osf_folder.append_file("file.txt")
        osf_file.create_version(
            self.user,
            {"object": "06d80e", "service": "cloud", osfstorage_settings.WATERBUTLER_RESOURCE: "osf"},
            {"size": 1337, "contentType": "img/png", "etag": "1234567890abcde"},
        ).save()

        source = {"path": "/subfolder/", "node": self.project, "provider": self.provider}
        destination = {
            "path": "/subfolder/",
            "node": self.project,
            "provider": "osfstorage",
            "children": [{"path": "/subfolder/file.txt", "node": self.project, "provider": "osfstorage"}],
        }
        file_name = "file.txt"
        self._create_file_with_comment(node=source["node"], path="{}{}".format(source["path"], file_name))
        payload = self._create_payload(
            "move", self.user, source, destination, self.file._id, destination_file_id=osf_file._id
        )
        update_file_guid_referent(self=None, node=destination["node"], event_type="addon_file_moved", payload=payload)
        self.guid.reload()

        file_node = FileNode.resolve_class("osfstorage", FileNode.FILE).get_or_create(destination["node"], osf_file._id)
        assert_equal(self.guid._id, file_node.get_guid()._id)
        file_comments = Comment.find(Q("root_target", "eq", self.guid._id))
        assert_equal(file_comments.count(), 1)
Example #13
0
 def test_find_unread_does_not_include_deleted_comments(self):
     project = ProjectFactory()
     user = AuthUserFactory()
     project.add_contributor(user)
     project.save()
     comment = CommentFactory(node=project, user=project.creator, is_deleted=True)
     n_unread = Comment.find_n_unread(user=user, node=project)
     assert_equal(n_unread, 0)
Example #14
0
 def test_find_unread_new_comments(self):
     project = ProjectFactory()
     user = UserFactory()
     project.add_contributor(user)
     project.save()
     comment = CommentFactory(node=project, user=project.creator)
     n_unread = Comment.find_n_unread(user=user, node=project)
     assert_equal(n_unread, 1)
Example #15
0
 def test_find_unread_includes_comment_replies(self):
     project = ProjectFactory()
     user = UserFactory()
     project.add_contributor(user)
     project.save()
     comment = CommentFactory(node=project, user=user)
     reply = CommentFactory(node=project, target=comment, user=project.creator)
     n_unread = Comment.find_n_unread(user=user, node=project)
     assert_equal(n_unread, 1)
Example #16
0
 def get_context_data(self, **kwargs):
     spam_id = self.kwargs.get("spam_id")
     try:
         kwargs.setdefault("comment", serialize_comment(Comment.load(spam_id)))
     except AttributeError:
         raise Http404("Spam with id {} not found.".format(spam_id))
     kwargs.setdefault("page_number", self.request.GET.get("page", "1"))
     kwargs.setdefault("status", self.request.GET.get("status", "1"))
     return super(EmailFormView, self).get_context_data(**kwargs)
Example #17
0
    def test_find_unread_includes_edited_comments(self):
        project = ProjectFactory()
        user = AuthUserFactory()
        project.add_contributor(user)
        project.save()
        comment = CommentFactory(node=project, user=project.creator)

        url = project.api_url_for("update_comments_timestamp")
        payload = {"page": "node", "rootId": project._id}
        res = self.app.put_json(url, payload, auth=user.auth)
        user.reload()
        n_unread = Comment.find_n_unread(user=user, node=project, page="node")
        assert_equal(n_unread, 0)

        # Edit previously read comment
        comment.edit(auth=Auth(project.creator), content="edited", save=True)
        n_unread = Comment.find_n_unread(user=user, node=project, page="node")
        assert_equal(n_unread, 1)
Example #18
0
 def test_create_comment_content_cannot_exceed_max_length(self):
     with assert_raises(ValidationValueError):
         comment = Comment.create(
             auth=self.auth,
             user=self.comment.user,
             node=self.comment.node,
             target=self.comment.target,
             is_public=True,
             content=''.join(['c' for c in range(settings.COMMENT_MAXLENGTH + 1)])
         )
Example #19
0
 def get_context_data(self, **kwargs):
     spam_id = self.kwargs.get('spam_id')
     try:
         kwargs.setdefault('comment',
                           serialize_comment(Comment.load(spam_id)))
     except AttributeError:
         raise Http404('Spam with id {} not found.'.format(spam_id))
     kwargs.setdefault('page_number', self.request.GET.get('page', '1'))
     kwargs.setdefault('status', self.request.GET.get('status', '1'))
     return super(EmailFormView, self).get_context_data(**kwargs)
Example #20
0
 def test_create_comment_content_cannot_be_none(self):
     with assert_raises(ValidationError) as error:
         comment = Comment.create(
             auth=self.auth,
             user=self.comment.user,
             node=self.comment.node,
             target=self.comment.target,
             is_public=True,
             content=None
     )
     assert_equal(error.exception.message, 'Value <content> is required.')
Example #21
0
 def test_create_comment_content_cannot_be_whitespace(self):
     with assert_raises(ValidationValueError) as error:
         comment = Comment.create(
             auth=self.auth,
             user=self.comment.user,
             node=self.comment.node,
             target=self.comment.target,
             is_public=True,
             content='    '
     )
     assert_equal(error.exception.message, 'Value must not be empty.')
Example #22
0
 def get_context_data(self, **kwargs):
     spam_id = self.kwargs.get("spam_id")
     kwargs = super(SpamDetail, self).get_context_data(**kwargs)
     try:
         kwargs.setdefault("comment", serialize_comment(Comment.load(spam_id)))
     except AttributeError:
         raise Http404('Spam with id "{}" not found.'.format(spam_id))
     kwargs.setdefault("page_number", self.request.GET.get("page", "1"))
     kwargs.setdefault("status", self.request.GET.get("status", "1"))
     kwargs.update(STATUS)  # Pass status in to check against
     return kwargs
Example #23
0
 def test_create_sends_comment_added_signal(self):
     with capture_signals() as mock_signals:
         comment = Comment.create(
             auth=self.auth,
             user=self.comment.user,
             node=self.comment.node,
             target=self.comment.target,
             is_public=True,
             content='This is a comment.'
         )
     assert_equal(mock_signals.signals_sent(), set([comment_added]))
Example #24
0
 def post(self, request, *args, **kwargs):
     spam_id = kwargs.get('spam_id', None)
     self.spam_id = spam_id
     self.page = request.GET.get('page', 1)
     try:
         self.spam = serialize_comment(Comment.load(spam_id))
     except (AttributeError, TypeError):
         return HttpResponseNotFound(
             '<h1>Spam comment ({}) not found.</h1>'.format(spam_id)
         )
     return super(EmailFormView, self).post(request, *args, **kwargs)
Example #25
0
    def create(self, validated_data):
        user = validated_data['user']
        auth = Auth(user)
        node = validated_data['node']

        validated_data['content'] = validated_data.pop('get_content')
        if node and node.can_comment(auth):
            comment = Comment.create(auth=auth, **validated_data)
        else:
            raise PermissionDenied("Not authorized to comment on this project.")
        return comment
Example #26
0
    def get_comment(self, check_permissions=True):
        pk = self.kwargs[self.comment_lookup_url_kwarg]
        try:
            comment = Comment.find_one(Q('_id', 'eq', pk))
        except NoResultsFound:
            raise NotFound

        if check_permissions:
            # May raise a permission denied
            self.check_object_permissions(self.request, comment)
        return comment
Example #27
0
 def get_context_data(self, **kwargs):
     spam_id = self.kwargs.get('spam_id')
     kwargs = super(SpamDetail, self).get_context_data(**kwargs)
     try:
         kwargs.setdefault('comment',
                           serialize_comment(Comment.load(spam_id)))
     except AttributeError:
         raise Http404('Spam with id "{}" not found.'.format(spam_id))
     kwargs.setdefault('page_number', self.request.GET.get('page', '1'))
     kwargs.setdefault('status', self.request.GET.get('status', '1'))
     kwargs.update({'SPAM_STATUS': SpamStatus})  # Pass status in to check against
     return kwargs
Example #28
0
 def get_target(self, node_id, target_id):
     node = Node.load(target_id)
     if node and node_id != target_id:
         raise ValueError('Cannot post comment to another node.')
     elif target_id == node_id:
         return Node.load(node_id)
     else:
         comment = Comment.load(target_id)
         if comment:
             return comment
         else:
             raise ValueError
Example #29
0
 def test_create_comment_content_does_not_exceed_max_length_complex(self):
     comment = Comment.create(
         auth=self.auth,
         user=self.comment.user,
         node=self.comment.node,
         target=self.comment.target,
         is_public=True,
         content="".join(["c" for c in range(settings.COMMENT_MAXLENGTH - 12)])
         + "[@George Ant](http://localhost:5000/"
         + self.comment.user._id
         + "/)",
     )
Example #30
0
 def get_initial(self):
     spam_id = self.kwargs.get("spam_id")
     try:
         spam = serialize_comment(Comment.load(spam_id))
     except AttributeError:
         raise Http404("Spam with id {} not found.".format(spam_id))
     self.initial = {
         "author": spam["author"].fullname,
         "email": [(r, r) for r in spam["author"].emails],
         "subject": "Reports of spam",
         "message": render(None, "spam/email_template.html", {"item": spam}).content,
     }
     return super(EmailFormView, self).get_initial()
Example #31
0
 def get_has_children(self, obj):
     return Comment.find(Q('target', 'eq', obj)).count() > 0
Example #32
0
 def get_has_children(self, obj):
     return Comment.find(Q('target', 'eq', Guid.load(obj._id))).count() > 0
Example #33
0
 def get_unread_comments_count(self, obj):
     user = self.context['request'].user
     if user.is_anonymous():
         return 0
     return Comment.find_n_unread(user=user, node=obj.node, page='files', root_id=obj._id)
Example #34
0
 def get_queryset(self):
     query = (
         Q('reports', 'ne', {}) & Q('reports', 'ne', None)
         & Q('user', 'eq', self.kwargs.get('user_id', None))
         & Q('spam_status', 'eq', int(self.request.GET.get('status', '1'))))
     return Comment.find(query).sort(self.ordering)