Beispiel #1
0
 def run(nextPageID, currentPageID, username, followedByUsername,
         filterTags, filterAbout, additionalTags):
     api = SecureCommentAPI(session.auth.user)
     try:
         comments = api.getForObject(
             about,
             username=username,
             followedByUsername=followedByUsername,
             filterTags=filterTags,
             filterAbout=filterAbout,
             limit=26,
             olderThan=nextPageID,
             newerThan=currentPageID,
             additionalTags=additionalTags)
     except UnknownPathError as error:
         raise JSONRPCError("Unknown path in additionalTags: '%s'." %
                            error.paths[0].encode('utf-8'))
     nextPageID = None
     if len(comments) == 26:
         nextPageID = comments[-2][u'fluidinfo.com/info/timestamp']
         comments = comments[:-1]
     currentPageID = (comments[0][u'fluidinfo.com/info/timestamp']
                      if comments else None)
     return {
         'currentPageID': currentPageID,
         'nextPageID': nextPageID,
         'comments': comments
     }
Beispiel #2
0
 def setUp(self):
     super(SecureCommentAPIWithUserRoleTest, self).setUp()
     createSystemData()
     UserAPI().create([
         (u'username', u'password', u'User', u'*****@*****.**'),
         (u'fluidinfo.com', u'secret', u'Fluidinfo', u'*****@*****.**')])
     self.user = getUser(u'username')
     self.comments = SecureCommentAPI(self.user)
Beispiel #3
0
 def run(nextPageID, currentPageID):
     api = SecureCommentAPI(session.auth.user)
     comments = api.getAllFollowed(username, limit=26,
                                   olderThan=nextPageID,
                                   newerThan=currentPageID)
     nextPageID = None
     if len(comments) == 26:
         nextPageID = comments[-2][u'fluidinfo.com/info/timestamp']
         comments = comments[:-1]
     currentPageID = (comments[0][u'fluidinfo.com/info/timestamp']
                      if comments else None)
     return {'currentPageID': currentPageID,
             'nextPageID': nextPageID,
             'comments': comments}
Beispiel #4
0
        def run(nextPageID, objectType):
            api = SecureCommentAPI(session.auth.user)
            result = api.getFollowedObjects(username, limit=21,
                                            olderThan=nextPageID,
                                            objectType=objectType)

            objects = [{'about': followedObject['about'],
                       'following': followedObject['following']}
                       for followedObject in result]
            nextPageID = None
            if len(result) == 21:
                nextPageID = result[-2][u'creationTime']
                objects = objects[:-1]
            return {'nextPageID': nextPageID, 'objects': objects}
Beispiel #5
0
        def run(nextPageID, objectType):
            api = SecureCommentAPI(session.auth.user)
            result = api.getFollowedObjects(username,
                                            limit=21,
                                            olderThan=nextPageID,
                                            objectType=objectType)

            objects = [{
                'about': followedObject['about'],
                'following': followedObject['following']
            } for followedObject in result]
            nextPageID = None
            if len(result) == 21:
                nextPageID = result[-2][u'creationTime']
                objects = objects[:-1]
            return {'nextPageID': nextPageID, 'objects': objects}
Beispiel #6
0
 def run(nextPageID, currentPageID, filterTags, additionalTags):
     api = SecureCommentAPI(session.auth.user)
     comments = api.getRecent(limit=26,
                              olderThan=nextPageID,
                              newerThan=currentPageID,
                              filterTags=filterTags,
                              additionalTags=additionalTags)
     nextPageID = None
     if len(comments) == 26:
         nextPageID = comments[-2][u'fluidinfo.com/info/timestamp']
         comments = comments[:-1]
     currentPageID = (comments[0][u'fluidinfo.com/info/timestamp']
                      if comments else None)
     return {'currentPageID': currentPageID,
             'nextPageID': nextPageID,
             'comments': comments}
Beispiel #7
0
    def upload(self, comments, message=None):
        """Upload batch comment data directly into Fluidinfo.

        @param comments: A C{list} of comment C{dict}s, each with keys:
            about: (Optional) A C{list} of C{unicode} values the comment is
                about.
            importer: The C{unicode} name of the importer application.
            text: The C{unicode} text of the comment.
            timestamp: A C{datetime.datetime} instance or C{None} if the
                current time should be used.
            url: A C{str} URL where the comment took place, or C{None}.
            username: The user's C{unicode} name in Fluidinfo. Note that the
                user might not officially exist in Fluidinfo yet. For example,
                we could be importing the tweets of someone who is followed by
                an actual Fluidinfo user.
        @param message: An optional C{unicode} message used to make logging
            output less generic.
        """
        message = (u'%s: ' % message) if message else u''
        nComments = len(comments)
        nImported = 0
        logging.info('%sImporting %d new comments.', message, nComments)
        startTime = time()

        while comments:
            # NOTE: Be careful here.  An obvious refactoring, at first
            # glance, is to move the logic to get the user and create the
            # comment API outside the loop, but doing so will cause the
            # user object to be used across transaction boundaries, which
            # we don't want to do.  It's important that the database
            # interactions for each batch processed here are managed in a
            # single transaction.
            thisBatch = comments[0:min(len(comments), self._batchSize)]
            try:
                user = getUser(u'fluidinfo.com')
                if user is None:
                    raise UnknownUserError([u'fluidinfo.com'])
                for comment in thisBatch:
                    SecureCommentAPI(user).create(comment['text'],
                                                  comment['username'],
                                                  importer=comment['importer'],
                                                  url=comment['url'],
                                                  about=comment.get('about'),
                                                  when=comment['timestamp'])
                transaction.commit()
                nImported += len(thisBatch)
                logging.info('%sImported %d/%d new comments.', message,
                             nImported, nComments)
            except:
                transaction.abort()
                logging.info('%sImport failed. Aborting.', message)
                raise
            else:
                comments = comments[len(thisBatch):]
        elapsed = time() - startTime
        logging.info(
            '%sImported %d comments in %s seconds, %.3f '
            'comments/second.', message, nComments, elapsed,
            float(nComments) / elapsed)
Beispiel #8
0
 def run(nextPageID, currentPageID):
     api = SecureCommentAPI(session.auth.user)
     comments = api.getAllFollowed(username,
                                   limit=26,
                                   olderThan=nextPageID,
                                   newerThan=currentPageID)
     nextPageID = None
     if len(comments) == 26:
         nextPageID = comments[-2][u'fluidinfo.com/info/timestamp']
         comments = comments[:-1]
     currentPageID = (comments[0][u'fluidinfo.com/info/timestamp']
                      if comments else None)
     return {
         'currentPageID': currentPageID,
         'nextPageID': nextPageID,
         'comments': comments
     }
Beispiel #9
0
 def run(nextPageID, currentPageID, filterTags, additionalTags):
     api = SecureCommentAPI(session.auth.user)
     comments = api.getRecent(limit=26,
                              olderThan=nextPageID,
                              newerThan=currentPageID,
                              filterTags=filterTags,
                              additionalTags=additionalTags)
     nextPageID = None
     if len(comments) == 26:
         nextPageID = comments[-2][u'fluidinfo.com/info/timestamp']
         comments = comments[:-1]
     currentPageID = (comments[0][u'fluidinfo.com/info/timestamp']
                      if comments else None)
     return {
         'currentPageID': currentPageID,
         'nextPageID': nextPageID,
         'comments': comments
     }
Beispiel #10
0
 def testCreateIsDenied(self):
     """
     L{SecureObjectAPI.create} raises a L{PermissionDeniedError} if it's
     invoked by a L{User} with the L{Role.ANONYMOUS}.
     """
     commentAPI = SecureCommentAPI(self.anon)
     error = self.assertRaises(PermissionDeniedError, commentAPI.create,
                               'text...', 'joe')
     self.assertEqual(self.anon.username, error.username)
     self.assertEqual(
         [(u'fluidinfo.com/info/username', Operation.WRITE_TAG_VALUE)],
         error.pathsAndOperations)
Beispiel #11
0
 def testUpdateWithAnonymous(self):
     """
     L{SecureObjectAPI.update} raises a L{PermissionDeniedError} if it's
     invoked by a L{User} with the L{Role.ANONYMOUS}.
     """
     commentAPI = SecureCommentAPI(self.anon)
     error = self.assertRaises(PermissionDeniedError, commentAPI.update,
                               'digg.com', 'joe', datetime.utcnow(), u'new')
     self.assertEqual(self.anon.username, error.username)
     self.assertEqual(
         [(u'fluidinfo.com/info/username', Operation.WRITE_TAG_VALUE)],
         error.pathsAndOperations)
Beispiel #12
0
 def run(nextPageID, currentPageID, username, followedByUsername,
         filterTags, filterAbout, additionalTags):
     api = SecureCommentAPI(session.auth.user)
     try:
         comments = api.getForObject(about, username=username,
                                     followedByUsername=
                                     followedByUsername,
                                     filterTags=filterTags,
                                     filterAbout=filterAbout,
                                     limit=26, olderThan=nextPageID,
                                     newerThan=currentPageID,
                                     additionalTags=additionalTags)
     except UnknownPathError as error:
         raise JSONRPCError("Unknown path in additionalTags: '%s'." %
                            error.paths[0].encode('utf-8'))
     nextPageID = None
     if len(comments) == 26:
         nextPageID = comments[-2][u'fluidinfo.com/info/timestamp']
         comments = comments[:-1]
     currentPageID = (comments[0][u'fluidinfo.com/info/timestamp']
                      if comments else None)
     return {'currentPageID': currentPageID,
             'nextPageID': nextPageID,
             'comments': comments}
Beispiel #13
0
 def run():
     api = SecureCommentAPI(session.auth.user)
     return api.summarizeObject(about)
Beispiel #14
0
 def run():
     api = SecureCommentAPI(session.auth.user)
     return api.create(text,
                       session.auth.username,
                       about=about,
                       when=creationTime)
Beispiel #15
0
 def run():
     api = SecureCommentAPI(session.auth.user)
     return api.summarizeObject(about)
Beispiel #16
0
 def run(importer, username, when, newText):
     api = SecureCommentAPI(session.auth.user)
     return api.update(importer, username, when, newText)
Beispiel #17
0
 def run(importer, username, when):
     api = SecureCommentAPI(session.auth.user)
     return {'deletedComments': api.delete(importer, username, when)}
Beispiel #18
0
class SecureCommentAPIWithUserRoleTest(CommentAPITestMixin, FluidinfoTestCase):

    resources = [('cache', CacheResource()),
                 ('config', ConfigResource()),
                 ('store', DatabaseResource()),
                 ('threadPool', ThreadPoolResource())]

    def setUp(self):
        super(SecureCommentAPIWithUserRoleTest, self).setUp()
        createSystemData()
        UserAPI().create([
            (u'username', u'password', u'User', u'*****@*****.**'),
            (u'fluidinfo.com', u'secret', u'Fluidinfo', u'*****@*****.**')])
        self.user = getUser(u'username')
        self.comments = SecureCommentAPI(self.user)

    def testCreateSucceeds(self):
        """
        L{SecureCommentAPI.create} returns a C{dict} with the expected
        keys and values.
        """
        when = datetime.utcnow()
        floatTime = timegm(when.utctimetuple()) + float(when.strftime('0.%f'))
        isoTime = when.isoformat()
        result = self.comments.create(u'Comment text', u'username', when=when)
        expected = {
            'fluidinfo.com/info/about': [],
            'fluidinfo.com/info/text': u'Comment text',
            'fluidinfo.com/info/timestamp': floatTime,
            'fluidinfo.com/info/url': (
                'https://fluidinfo.com/comment/fluidinfo.com/username/' +
                isoTime),
            'fluidinfo.com/info/username': u'username',
        }
        self.assertEqual(expected, result)

    def testDeleteAnotherUsersComment(self):
        """
        L{SecureObjectAPI.delete} raises a L{PermissionDeniedError} if a
        L{User} tries to delete a comment made by someone else.
        """
        error = self.assertRaises(PermissionDeniedError, self.comments.delete,
                                  'digg.com', 'joe', datetime.utcnow())
        self.assertEqual(u'username', error.username)
        self.assertEqual(
            [(u'fluidinfo.com/info/username', Operation.DELETE_TAG_VALUE)],
            error.pathsAndOperations)

    def testUpdateAnotherUsersComment(self):
        """
        L{SecureObjectAPI.update} raises a L{PermissionDeniedError} if a
        L{User} tries to update a comment made by someone else.
        """
        error = self.assertRaises(PermissionDeniedError, self.comments.update,
                                  'digg.com', 'joe', datetime.utcnow(), u'new')
        self.assertEqual(u'username', error.username)
        self.assertEqual(
            [(u'fluidinfo.com/info/username', Operation.WRITE_TAG_VALUE)],
            error.pathsAndOperations)

    def testGetForObjectWithAdditionalTagsUnreadable(self):
        """
        L{SecureCommentAPI.getForObject} raises a L{PermissionDeniedError} if a
        L{User} tries to retrieve C{additionalTags} which are unreadable to
        them.
        """
        objectID = uuid4()
        values = {objectID: {u'username/tag': 16}}
        SecureTagValueAPI(self.user).set(values)
        CachingPermissionAPI(self.user).set([(u'username/tag',
                                              Operation.READ_TAG_VALUE,
                                              Policy.CLOSED, [])])

        error = self.assertRaises(PermissionDeniedError,
                                  self.comments.getForObject, u'about',
                                  additionalTags=[u'username/tag'])
        self.assertEqual(u'username', error.username)
        self.assertEqual(
            [(u'username/tag', Operation.READ_TAG_VALUE)],
            error.pathsAndOperations)

    def testGetForObjectWithAdditionalTagsNonexistent(self):
        """
        L{SecureCommentAPI.getForObject} raises a L{PermissionDeniedError} if a
        L{User} tries to retrieve C{additionalTags} which are unreadable to
        them.
        """
        self.assertRaises(UnknownPathError,
                          self.comments.getForObject, u'about',
                          additionalTags=[u'user/nonexistent'])

    def testGetForUserWithAdditionalTagsUnreadable(self):
        """
        L{SecureCommentAPI.getForUser} raises a L{PermissionDeniedError} if a
        L{User} tries to retrieve C{additionalTags} which are unreadable to
        them.
        """
        objectID = uuid4()
        values = {objectID: {u'username/tag': 16}}
        SecureTagValueAPI(self.user).set(values)
        CachingPermissionAPI(self.user).set([(u'username/tag',
                                              Operation.READ_TAG_VALUE,
                                              Policy.CLOSED, [])])

        error = self.assertRaises(PermissionDeniedError,
                                  self.comments.getForUser, u'username',
                                  additionalTags=[u'username/tag'])
        self.assertEqual(u'username', error.username)
        self.assertEqual(
            [(u'username/tag', Operation.READ_TAG_VALUE)],
            error.pathsAndOperations)

    def testGetForUserWithAdditionalTagsNonexistent(self):
        """
        L{SecureCommentAPI.getForUser} raises a L{PermissionDeniedError} if a
        L{User} tries to retrieve C{additionalTags} which are unreadable to
        them.
        """
        self.assertRaises(UnknownPathError,
                          self.comments.getForUser, u'username',
                          additionalTags=[u'user/nonexistent'])
Beispiel #19
0
 def run():
     api = SecureCommentAPI(session.auth.user)
     return api.create(text, session.auth.username, about=about,
                       when=creationTime)
Beispiel #20
0
 def run(importer, username, when):
     api = SecureCommentAPI(session.auth.user)
     return {'deletedComments': api.delete(importer, username, when)}
Beispiel #21
0
 def run(importer, username, when, newText):
     api = SecureCommentAPI(session.auth.user)
     return api.update(importer, username, when, newText)