Exemplo n.º 1
0
    def testDeleteTag(self):
        """L{FacadeTagMixin.deleteTag} deletes a L{Tag}."""
        tags = TagAPI(self.user)
        tags.create([(u'username/name', u'A tag.')])
        self.store.commit()
        with login(u'username', uuid4(), self.transact) as session:
            yield self.facade.deleteTag(session, u'username/name')

        self.store.rollback()
        self.assertEqual({}, tags.get([u'username/name']))
Exemplo n.º 2
0
 def setUp(self):
     super(SecureObjectAPIWithAnonymousRoleTest, self).setUp()
     system = createSystemData()
     self.anon = system.users[u'anon']
     UserAPI().create([(u'username', u'password', u'User',
                        u'*****@*****.**')])
     self.user = getUser(u'username')
     self.tags = TagAPI(self.user)
     self.tags.create([(u'username/tag', u'description')])
     self.permissions = CachingPermissionAPI(self.user)
     self.objects = SecureObjectAPI(self.anon)
Exemplo n.º 3
0
    def testPrepareForTestingCreatesTags(self):
        """
        L{prepareForTesting} creates all the necessary testing L{Tag}s.
        """
        prepareForTesting()

        paths = [
            u'fluiddb/testing/test1', u'fluiddb/testing/test2',
            u'testuser1/testing/test1', u'testuser1/testing/test2',
            u'testuser2/testing/test1', u'testuser2/testing/test2'
        ]
        tags = TagAPI(self.admin).get(paths)
        self.assertEqual(paths, sorted(tags.iterkeys()))
Exemplo n.º 4
0
    def testPrepareForTestingCreatesTags(self):
        """
        L{prepareForTesting} creates all the necessary testing L{Tag}s.
        """
        prepareForTesting()

        paths = [u'fluiddb/testing/test1',
                 u'fluiddb/testing/test2',
                 u'testuser1/testing/test1',
                 u'testuser1/testing/test2',
                 u'testuser2/testing/test1',
                 u'testuser2/testing/test2']
        tags = TagAPI(self.admin).get(paths)
        self.assertEqual(paths, sorted(tags.iterkeys()))
Exemplo n.º 5
0
def removeTestingData():
    """
    Delete L{User}s, L{Namespace}s and L{Tag}s used for testing purposes.
    """
    admin = getUser(u'fluiddb')
    logging.info('Deleting testing tags.')
    result = TagAPI(admin).get(TESTING_DATA[u'tags'])
    if result:
        TagAPI(admin).delete(result.keys())

    logging.info('Deleting testing namespaces.')
    result = NamespaceAPI(admin).get(TESTING_DATA[u'namespaces'])
    # we must delete namespaces one by one, otherwise we'll get NotEmptyError.
    for path in sorted(result.keys(), reverse=True):
        NamespaceAPI(admin).delete([path])

    logging.info('Deleting testing users.')
    result = UserAPI().get(TESTING_DATA[u'users'])
    if result:
        for username in result:
            path = '%s/private' % username
            try:
                NamespaceAPI(admin).delete([path])
            except FeatureError:
                # FIXME This is a bit crap, but it's faster than checking to
                # see if the namespace exists before attempting to delete it.
                continue
    if result:
        UserAPI().delete(result.keys())
    getMainStore().commit()
Exemplo n.º 6
0
    def testCreateChildTagWithDelegatedCreator(self):
        """
        L{TagAPI.create} always ensures that a new L{Tag} is usable by the
        L{User} that created it.  In the case of default permissions, the user
        creating the new L{Tag} is granted L{Operation.UPDATE_TAG},
        L{Operation.DELETE_TAG}, L{Operation.WRITE_TAG_VALUE} and
        L{Operation.DELETE_TAG_VALUE}.
        """
        UserAPI().create([(u'friend', u'secret', u'name', u'*****@*****.**')
                          ])
        PermissionAPI(self.user).set([(u'username', Operation.CREATE_NAMESPACE,
                                       Policy.CLOSED, [u'username',
                                                       u'friend'])])

        friend = getUser(u'friend')
        TagAPI(friend).create([(u'username/tag', u'A shared tag')])
        result = getTagPermissions([u'username/tag'])
        tag, permission = result.one()
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.UPDATE_TAG))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.DELETE_TAG))
        self.assertEqual((Policy.CLOSED, [self.user.id]),
                         permission.get(Operation.CONTROL_TAG))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.WRITE_TAG_VALUE))
        self.assertEqual((Policy.OPEN, []),
                         permission.get(Operation.READ_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.DELETE_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [self.user.id]),
                         permission.get(Operation.CONTROL_TAG_VALUE))
Exemplo n.º 7
0
 def testSearchWithManyQueries(self):
     """
     L{ObjectAPI.search} can be used to resolve many L{Query}s at once.
     """
     TagAPI(self.user).create([(u'user/tag', u'description')])
     objectID1 = uuid4()
     objectID2 = uuid4()
     index = ObjectIndex(self.client)
     yield index.update({
         objectID1: {
             u'user/tag': 42
         },
         objectID2: {
             u'user/tag': 65
         }
     })
     yield index.commit()
     query1 = parseQuery(u'user/tag = 42')
     query2 = parseQuery(u'user/tag = 65')
     result = self.objects.search([query1, query2])
     result = yield result.get()
     self.assertEqual({
         query1: set([objectID1]),
         query2: set([objectID2])
     }, result)
Exemplo n.º 8
0
    def testCreatePrivateChildTagWithDelegatedCreator(self):
        """
        L{TagAPI.create} always ensures that a new L{Tag} is usable by the
        L{User} that created it.  If the L{Operation.READ_TAG_VALUE}
        permission is L{Policy.CLOSED} the creator is added to the exceptions
        list.
        """
        UserAPI().create([(u'friend', u'secret', u'name', u'*****@*****.**')
                          ])
        PermissionAPI(self.user).set([(u'username', Operation.CREATE_NAMESPACE,
                                       Policy.CLOSED, [u'username',
                                                       u'friend']),
                                      (u'username', Operation.LIST_NAMESPACE,
                                       Policy.CLOSED, [u'username',
                                                       u'friend'])])

        friend = getUser(u'friend')
        TagAPI(friend).create([(u'username/tag', u'A shared tag')])
        result = getTagPermissions([u'username/tag'])
        tag, permission = result.one()
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.UPDATE_TAG))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.DELETE_TAG))
        self.assertEqual((Policy.CLOSED, [self.user.id]),
                         permission.get(Operation.CONTROL_TAG))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.WRITE_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.READ_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [self.user.id, friend.id]),
                         permission.get(Operation.DELETE_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [self.user.id]),
                         permission.get(Operation.CONTROL_TAG_VALUE))
Exemplo n.º 9
0
    def testUpdateTag(self):
        """
        L{FacadeTagMixin.updateTag} updates the description for an existing
        L{Tag}.
        """
        tags = TagAPI(self.user)
        tags.create([(u'username/name', u'A tag.')])
        self.store.commit()
        with login(u'username', uuid4(), self.transact) as session:
            yield self.facade.updateTag(session, u'username/name',
                                        u'A new description.')

        self.store.rollback()
        result = tags.get([u'username/name'], withDescriptions=True)
        self.assertEqual(u'A new description.',
                         result[u'username/name']['description'])
Exemplo n.º 10
0
    def testCheckIntegrityChecksErrorInAllRows(self):
        """
        L{checkIntegrity} should check for integrity errors in L{Namespace}s,
        L{Tag}s, L{User}s, L{AboutTagValue}s and L{TagValue}s.
        """
        createSystemData()
        [(userObjectID, _)] = UserAPI().create([(u'user', u'pass', u'Name',
                                                 u'*****@*****.**')])
        user = getUser(u'user')
        result = NamespaceAPI(user).create([(u'user/namespace', u'description')
                                            ])
        [(namespaceObjectID, _)] = result
        [(tagObjectID, _)] = TagAPI(user).create([(u'user/tag', u'description')
                                                  ])
        objectID1 = uuid4()
        objectID2 = uuid4()
        createAboutTagValue(objectID1, u'Bad about tag')
        TagValueAPI(user).set({objectID2: {u'fluiddb/about': 'about value'}})

        TagValueAPI(user).delete([(userObjectID, u'fluiddb/users/username')])
        TagValueAPI(user).delete([(namespaceObjectID,
                                   u'fluiddb/namespaces/path')])
        TagValueAPI(user).delete([(tagObjectID, u'fluiddb/tags/description')])
        checkIntegrity()

        self.assertEqual(
            "Integrity Error in namespace u'user/namespace': "
            'Path tag is missing.\n'
            "Integrity Error in tag u'user/tag': Description tag is missing.\n"
            "Integrity Error in user u'user': Username tag is missing.\n"
            "Integrity Error in object %s: AboutTagValue doesn't have an "
            'associated TagValue.\n'
            "Integrity Error in object %s: fluiddb/about TagValue doesn't "
            'have an associated AboutTagValue.\n' % (objectID1, objectID2),
            self.log.getvalue())
Exemplo n.º 11
0
 def setUp(self):
     super(SecureTagValueAPIWithSuperuserRoleTest, self).setUp()
     system = createSystemData()
     self.superuser = system.users[u'fluiddb']
     TagAPI(self.superuser).create([(u'fluiddb/tag', u'description')])
     self.tagValues = SecureTagValueAPI(self.superuser)
     self.permissions = CachingPermissionAPI(self.superuser)
Exemplo n.º 12
0
 def setUp(self):
     super(TagAPITest, self).setUp()
     self.system = createSystemData()
     UserAPI().create([(u'username', u'password', u'User',
                        u'*****@*****.**')])
     self.user = getUser(u'username')
     self.permissions = PermissionAPI(self.user)
     self.tags = TagAPI(self.user)
Exemplo n.º 13
0
 def setUp(self):
     super(SecurePermissionAPIWithNormalUserTest, self).setUp()
     createSystemData()
     UserAPI().create([(u'username', u'password', u'User',
                        u'*****@*****.**')])
     user = getUser(u'username')
     TagAPI(user).create([(u'username/tag', u'description')])
     self.permissions = SecurePermissionAPI(user)
Exemplo n.º 14
0
 def testCreateChildTagInheritsPermissions(self):
     """
     L{TagAPI.create} creates new L{Namespace}s based on the provided data.
     """
     UserAPI().create([(u'user', u'secret', u'name', u'*****@*****.**')])
     user = getUser(u'user')
     TagAPI(user).create([(u'user/tag', u'A description')])
     self.assertDefaultPermissions(user, u'user/tag')
Exemplo n.º 15
0
 def setUp(self):
     super(SecurePermissionAPIWithAnonymousRoleTest, self).setUp()
     system = createSystemData()
     user = system.users[u'anon']
     self.permissions = SecurePermissionAPI(user)
     UserAPI().create([(u'username', u'password', u'User',
                        u'*****@*****.**')])
     user = getUser(u'username')
     TagAPI(user).create([(u'username/tag', u'description')])
Exemplo n.º 16
0
 def testDeltaImportWithDeletedTag(self):
     """
     L{TagValue}s deleted via delete cascade triggered by a L{Tag} deletion
     should be deleted in the index too.
     """
     objectID = self.objects.create()
     self.values.set({objectID: {u'user/tag1': u'string',
                                 u'user/tag2': u'text'}})
     time.sleep(1)
     runDataImportHandler(self.client.url)
     tags = TagAPI(self.user)
     tags.delete([u'user/tag1'])
     self.store.commit()
     values = self.values.get([objectID], [u'user/tag1'])
     self.assertNotIn(u'user/tag1', values[objectID])
     runDataImportHandler(self.client.url, clean=False)
     yield self.assertQuery([], 'has user/tag1')
     yield self.assertQuery([], 'user/tag1 = "string"')
Exemplo n.º 17
0
 def setUp(self):
     super(SecureObjectAPIWithUserRoleTest, self).setUp()
     createSystemData()
     UserAPI().create([(u'username', u'password', u'User',
                        u'*****@*****.**')])
     self.user = getUser(u'username')
     TagAPI(self.user).create([(u'username/tag', u'description')])
     self.permissions = CachingPermissionAPI(self.user)
     self.objects = SecureObjectAPI(self.user)
Exemplo n.º 18
0
 def testGetTagWithDescription(self):
     """
     L{FacadeTagMixin.getTag} includes the L{Tag.description}, if it was
     requested.
     """
     TagAPI(self.user).create([(u'username/tag', u'A tag.')])
     self.store.commit()
     with login(u'username', uuid4(), self.transact) as session:
         result = yield self.facade.getTag(session, u'username/tag', True)
         self.assertEqual(u'A tag.', result.description)
Exemplo n.º 19
0
 def testCreateActivationTokenTag(self):
     """
     L{bootstrapWebAdminData} creates a C{fluiddb/users/activation-token}
     tag.
     """
     createSystemData()
     bootstrapWebAdminData()
     superuser = getUser(u'fluiddb')
     result = TagAPI(superuser).get([u'fluiddb/users/activation-token'])
     self.assertIn(u'fluiddb/users/activation-token', result)
Exemplo n.º 20
0
    def testCheckMultipleOpenPermissions(self):
        """L{checkPermissions} can check multiple permissions."""
        UserAPI().create([(u'user1', 'hash', u'User', u'*****@*****.**')])
        UserAPI().create([(u'user2', 'hash', u'User', u'*****@*****.**')])
        user1 = getUser(u'user1')
        user2 = getUser(u'user2')

        TagAPI(user1).create([(u'user1/tag', u'description')])
        self.permissions.set([(u'user1/tag', Operation.UPDATE_TAG, Policy.OPEN,
                               [u'user1', u'user2'])])

        TagAPI(user2).create([(u'user2/tag', u'description')])
        self.permissions.set([(u'user2/tag', Operation.WRITE_TAG_VALUE,
                               Policy.CLOSED, [u'username'])])

        values = [(u'user1/tag', Operation.UPDATE_TAG),
                  (u'user2/tag', Operation.WRITE_TAG_VALUE)]

        deniedOperations = checkPermissions(self.user, values)
        self.assertEqual([], deniedOperations)
Exemplo n.º 21
0
 def testCreateTagWithExistingPath(self):
     """
     L{FacadeTagMixin.createTag} raises a L{TTagAlreadyExists} exception if
     the new L{Tag} already exists.
     """
     TagAPI(self.user).create([(u'username/name', u'A tag.')])
     self.store.commit()
     with login(u'username', uuid4(), self.transact) as session:
         deferred = self.facade.createTag(
             session, u'username', u'name', u'A tag.', 'ignored', 'ignored')
         yield self.assertFailure(deferred, TTagAlreadyExists)
Exemplo n.º 22
0
 def testDeleteIsDenied(self):
     """
     L{Facade.deleteTag} raises a L{TPathPermissionDenied} exception if the
     user doesn't have C{DELETE} permissions on the specified L{Tag}.
     """
     TagAPI(self.user).create([(u'username/test', u'A tag.')])
     self.permissions.set([(u'username/test', Operation.DELETE_TAG,
                            Policy.OPEN, [u'username'])])
     self.store.commit()
     with login(u'username', uuid4(), self.transact) as session:
         deferred = self.facade.deleteTag(session, u'username/test')
         yield self.assertFailure(deferred, TPathPermissionDenied)
Exemplo n.º 23
0
    def testCheckClosedPermissionWithException(self):
        """
        L{checkPermissions} grants access when the policy is C{Policy.OPEN}
        and the L{User.id} is in the exceptions list.
        """
        TagAPI(self.user).create([(u'username/tag', u'description')])
        self.permissions.set([(u'username/tag', Operation.UPDATE_TAG,
                               Policy.CLOSED, [u'username'])])

        values = [(u'username/tag', Operation.UPDATE_TAG)]
        deniedOperations = checkPermissions(self.user, values)
        self.assertEqual([], deniedOperations)
Exemplo n.º 24
0
    def testRemoveTestingDataRemovesCreatesTags(self):
        """L{removeTestingData} removes all the testing L{Tag}s."""
        prepareForTesting()
        removeTestingData()

        paths = [
            u'fluiddb/testing/test1', u'fluiddb/testing/test2',
            u'testuser1/testing/test1', u'testuser1/testing/test2',
            u'testuser2/testing/test1', u'testuser2/testing/test2'
        ]
        tags = TagAPI(self.admin).get(paths)
        self.assertEqual({}, tags)
Exemplo n.º 25
0
def removeTestingData():
    """
    Delete L{User}s, L{Namespace}s and L{Tag}s used for testing purposes.
    """
    admin = getUser(u'fluiddb')
    logging.info('Deleting testing tags.')
    result = TagAPI(admin).get(TESTING_DATA[u'tags'])
    if result:
        TagAPI(admin).delete(result.keys())

    logging.info('Deleting testing namespaces.')
    result = NamespaceAPI(admin).get(TESTING_DATA[u'namespaces'])
    # we must delete namespaces one by one, otherwise we'll get NotEmptyError.
    for path in sorted(result.keys(), reverse=True):
        NamespaceAPI(admin).delete([path])

    logging.info('Deleting testing users.')
    result = UserAPI().get(TESTING_DATA[u'users'])
    if result:
        for username in result:
            path = '%s/private' % username
            try:
                NamespaceAPI(admin).delete([path])
            except FeatureError:
                # FIXME This is a bit crap, but it's faster than checking to
                # see if the namespace exists before attempting to delete it.
                continue
    if result:
        UserAPI().delete(result.keys())
    getMainStore().commit()
Exemplo n.º 26
0
 def testGetTag(self):
     """
     L{FacadeTagMixin.getTag} returns a L{TTag} instance with information
     about the requested L{Tag}.
     """
     result = TagAPI(self.user).create([(u'username/tag', u'description')])
     [(objectID, path)] = result
     self.store.commit()
     with login(u'username', uuid4(), self.transact) as session:
         result = yield self.facade.getTag(session, u'username/tag', False)
         self.assertEqual(str(objectID), result.objectId)
         self.assertEqual(u'username/tag', result.path)
         self.assertTrue(result.indexed)
Exemplo n.º 27
0
 def testCheckUserWithMissingPermission(self):
     """
     L{checkPermissions} denies the operation if, for some
     reason, a permission is not available for the entity being requested.
     """
     TagAPI(self.user).create([(u'username/tag', u'description')])
     # FIXME: don't use data functions here.
     [(tag, permission)] = getTagPermissions([u'username/tag'])
     self.store.remove(permission)
     values = [(u'username/tag', Operation.UPDATE_TAG)]
     deniedOperations = checkPermissions(self.user, values)
     self.assertEqual([(u'username/tag', Operation.UPDATE_TAG)],
                      deniedOperations)
Exemplo n.º 28
0
class CachingTagAPI(object):
    """The public API to cached tag-related logic in the model.

    @param user: The L{User} to perform operations on behalf of.
    """

    def __init__(self, user):
        self._api = TagAPI(user, factory=CachingAPIFactory())

    def create(self, values):
        """See L{TagAPI.create}."""
        return self._api.create(values)

    def delete(self, paths):
        """See L{TagAPI.delete}.

        Permissions for deleted L{Tag}s are removed from the cache.
        """
        if isgenerator(paths):
            paths = list(paths)
        # FIXME getObjectIDs is called twice--once here and once in
        # TagAPI.delete.  It would be better if we only did this once, not to
        # mention that this breaks encapsulation by bypassing the model layer
        # and accessing the data layer directly. -jkakar
        objectIDs = set(getObjectIDs(paths))
        RecentObjectActivityCache().clear(objectIDs)
        usernames = set([path.split('/')[0] for path in paths])
        RecentUserActivityCache().clear(usernames)
        PermissionCache().clearTagPermissions(paths)
        return self._api.delete(paths)

    def get(self, paths, withDescriptions=None):
        """See L{TagAPI.get}."""
        return self._api.get(paths, withDescriptions=withDescriptions)

    def set(self, values):
        """Set L{TagAPI.set}."""
        return self._api.set(values)
Exemplo n.º 29
0
 def testSetInvalidatesCachedTagPermissions(self):
     """
     L{CachingPermissionAPI.set} invalidates L{TagPermission}s to ensure
     the cache is always fresh.
     """
     TagAPI(self.user).create([(u'username/tag', u'A tag')])
     _, permission = getTagPermissions(paths=[u'username/tag']).one()
     cache = PermissionCache()
     cache.saveTagPermissions({u'username/tag': permission})
     self.permissions.set([(u'username/tag', Operation.UPDATE_TAG,
                            Policy.OPEN, [])])
     cached = cache.getTagPermissions([u'username/tag'])
     self.assertEqual({}, cached.results)
     self.assertEqual([u'username/tag'], cached.uncachedValues)
Exemplo n.º 30
0
    def testCheckReturnsMultipleDeniedPermissions(self):
        """
        L{checkPermissions} returns a C{list} of all denied paths and
        L{Operation}s for the requested actions.
        """
        UserAPI().create([(u'user1', 'hash', u'User', u'*****@*****.**')])
        UserAPI().create([(u'user2', 'hash', u'User', u'*****@*****.**')])
        user1 = getUser(u'user1')
        user2 = getUser(u'user2')

        TagAPI(user1).create([(u'user1/tag', u'description')])
        self.permissions.set([(u'user1/tag', Operation.UPDATE_TAG, Policy.OPEN,
                               [u'user1', u'user2'])])

        TagAPI(user2).create([(u'user2/tag', u'description')])
        self.permissions.set([(u'user2/tag', Operation.WRITE_TAG_VALUE,
                               Policy.OPEN, [u'username'])])

        values = [(u'user1/tag', Operation.UPDATE_TAG),
                  (u'user2/tag', Operation.WRITE_TAG_VALUE)]
        deniedOperations = checkPermissions(self.user, values)
        expected = [(u'user2/tag', Operation.WRITE_TAG_VALUE)]
        self.assertEqual(sorted(expected), sorted(deniedOperations))
Exemplo n.º 31
0
 def testGetTagsForObjectsOnlyReturnsAccessibleTags(self):
     """
     L{SecureObjectAPI.getTagsForObjects} only returns L{Tag.path}s that
     the user has C{Operation.READ_TAG_VALUE} permissions for.
     """
     TagAPI(self.user).create([(u'username/tag1', u'description'),
                               (u'username/tag2', u'description')])
     objectID = uuid4()
     SecureTagValueAPI(self.user).set({objectID: {u'username/tag1': 13,
                                                  u'username/tag2': 17}})
     self.permissions.set([(u'username/tag2', Operation.READ_TAG_VALUE,
                            Policy.CLOSED, [])])
     self.assertEqual([u'username/tag1'],
                      self.objects.getTagsForObjects([objectID]))
Exemplo n.º 32
0
class CachingTagAPI(object):
    """The public API to cached tag-related logic in the model.

    @param user: The L{User} to perform operations on behalf of.
    """
    def __init__(self, user):
        self._api = TagAPI(user, factory=CachingAPIFactory())

    def create(self, values):
        """See L{TagAPI.create}."""
        return self._api.create(values)

    def delete(self, paths):
        """See L{TagAPI.delete}.

        Permissions for deleted L{Tag}s are removed from the cache.
        """
        if isgenerator(paths):
            paths = list(paths)
        # FIXME getObjectIDs is called twice--once here and once in
        # TagAPI.delete.  It would be better if we only did this once, not to
        # mention that this breaks encapsulation by bypassing the model layer
        # and accessing the data layer directly. -jkakar
        objectIDs = set(getObjectIDs(paths))
        RecentObjectActivityCache().clear(objectIDs)
        usernames = set([path.split('/')[0] for path in paths])
        RecentUserActivityCache().clear(usernames)
        PermissionCache().clearTagPermissions(paths)
        return self._api.delete(paths)

    def get(self, paths, withDescriptions=None):
        """See L{TagAPI.get}."""
        return self._api.get(paths, withDescriptions=withDescriptions)

    def set(self, values):
        """Set L{TagAPI.set}."""
        return self._api.set(values)
Exemplo n.º 33
0
    def testGetTagPermissionsCachesMisses(self):
        """
        L{CachingPermissionCheckerAPI.getTagPermissions} adds missing
        L{TagPermission}s to the cache.
        """
        TagAPI(self.user).create([(u'username/tag', u'A tag')])
        result = self.api.getTagPermissions([u'username/tag'])
        permission = result[u'username/tag']
        self.assertTrue(isinstance(permission, TagPermission))

        # Go behind everyone's back and kill the TagPermission.
        self.store.find(TagPermission).remove()
        result = self.api.getTagPermissions([u'username/tag'])
        permission = result[u'username/tag']
        self.assertTrue(isinstance(permission, TagPermission))
Exemplo n.º 34
0
 def __init__(self, user):
     self._api = TagAPI(user, factory=CachingAPIFactory())
Exemplo n.º 35
0
class SecureObjectAPIWithAnonymousRoleTest(FluidinfoTestCase):

    resources = [('cache', CacheResource()),
                 ('client', IndexResource()),
                 ('config', ConfigResource()),
                 ('store', DatabaseResource())]

    def setUp(self):
        super(SecureObjectAPIWithAnonymousRoleTest, self).setUp()
        system = createSystemData()
        self.anon = system.users[u'anon']
        UserAPI().create([(u'username', u'password', u'User',
                           u'*****@*****.**')])
        self.user = getUser(u'username')
        self.tags = TagAPI(self.user)
        self.tags.create([(u'username/tag', u'description')])
        self.permissions = CachingPermissionAPI(self.user)
        self.objects = SecureObjectAPI(self.anon)

    def testCreateIsDenied(self):
        """
        L{SecureObjectAPI.create} raises a L{PermissionDeniedError} if it's
        invoked by a L{User} with the L{Role.ANONYMOUS}.
        """
        objects = SecureObjectAPI(self.anon)
        error = self.assertRaises(PermissionDeniedError, objects.create)
        self.assertEqual(self.anon.username, error.username)
        self.assertEqual([(None, Operation.CREATE_OBJECT)],
                         error.pathsAndOperations)

    def testGetTagsByObjectsPathIsAllowed(self):
        """
        L{SecureObjectAPI.getTagsByObjects} will return all the tags for
        which the anonymous user has C{Operation.READ_TAG_VALUE} permissions.
        """
        objectID = uuid4()
        values = {objectID: {u'username/tag': 16}}
        SecureTagValueAPI(self.user).set(values)
        self.permissions.set([(u'username/tag', Operation.READ_TAG_VALUE,
                               Policy.OPEN, [])])
        self.assertEqual({objectID: [u'username/tag']},
                         self.objects.getTagsByObjects([objectID]))

    def testGetTagsByObjectsReturnsOnlyAllowedTags(self):
        """
        L{SecureObjectAPI.getTagsByObjects} will return all the tags for
        which the anonymous user has C{Operation.READ_TAG_VALUE} permissions,
        but not those for which the user doesn't have.
        """
        self.tags.create([(u'username/tag1', u'description'),
                          (u'username/tag2', u'description')])
        objectID = uuid4()

        values = {objectID: {u'username/tag1': 16,
                             u'username/tag2': 16}}
        SecureTagValueAPI(self.user).set(values)

        self.permissions.set([(u'username/tag1', Operation.READ_TAG_VALUE,
                               Policy.CLOSED, []),
                              (u'username/tag2', Operation.READ_TAG_VALUE,
                               Policy.OPEN, [])])

        result = self.objects.getTagsByObjects([objectID])
        expected = {objectID: [u'username/tag2']}
        self.assertEqual(expected, result)

    def testGetTagsByObjectsReturnsNoneIfDenied(self):
        """
        L{SecureObjectAPI.getTagsByObjects} will return an empty C{dict} if
        the L{User} does not have C{Operation.READ_TAG_VALUE} permission on
        none of the L{Tag}s an object has.
        """
        self.tags.create([(u'username/tag1', u'description'),
                          (u'username/tag2', u'description')])
        objectID = uuid4()

        values = {objectID: {u'username/tag1': 16,
                             u'username/tag2': 16}}
        SecureTagValueAPI(self.user).set(values)

        self.permissions.set([(u'username/tag1', Operation.READ_TAG_VALUE,
                               Policy.CLOSED, []),
                              (u'username/tag2', Operation.READ_TAG_VALUE,
                               Policy.CLOSED, [])])

        result = self.objects.getTagsByObjects([objectID])
        self.assertEqual({}, result)

    def testGetTagsByObjectsWithCustomPermission(self):
        """
        L{SecureObjectAPI.getTagsByObjects} optionally accepts a permission
        type to check for instead of L{Operation.READ_TAG_VALUE}).
        """
        TagAPI(self.user).create([(u'username/open', u'An accessible tag'),
                                  (u'username/closed', u'A denied tag')])
        objectID = uuid4()
        SecureTagValueAPI(self.user).set({objectID: {u'username/open': 13,
                                                     u'username/closed': 17}})
        self.permissions.set([(u'username/closed', Operation.DELETE_TAG_VALUE,
                               Policy.CLOSED, [])])
        result = self.objects.getTagsByObjects(
            [objectID], permission=Operation.DELETE_TAG_VALUE)
        # Result is empty because anonymous users are never allowed to delete
        # values.
        self.assertEqual({}, result)

    def testGetTagsForObjectsOnlyReturnsAccessibleTags(self):
        """
        L{SecureObjectAPI.getTagsForObjects} only returns L{Tag.path}s that
        the user has C{Operation.READ_TAG_VALUE} permissions for.
        """
        TagAPI(self.user).create([(u'username/tag1', u'description'),
                                  (u'username/tag2', u'description')])
        objectID = uuid4()
        SecureTagValueAPI(self.user).set({objectID: {u'username/tag1': 13,
                                                     u'username/tag2': 17}})
        self.permissions.set([(u'username/tag2', Operation.READ_TAG_VALUE,
                               Policy.CLOSED, [])])
        self.assertEqual([u'username/tag1'],
                         self.objects.getTagsForObjects([objectID]))

    @inlineCallbacks
    def testSearch(self):
        """
        L{SecureObjectAPI.search} resolves the specified L{Query}s if the
        anonymous user has C{Operation.READ_TAG_VALUE} permissions on the
        requested L{Tag.path}s.
        """
        objectID = uuid4()
        index = ObjectIndex(self.client)
        yield index.update({objectID: {u'username/tag': 42}})
        yield self.client.commit()
        query = parseQuery(u'username/tag = 42')
        result = self.objects.search([query])
        result = yield result.get()
        self.assertEqual({query: set([objectID])}, result)

    @inlineCallbacks
    def testSearchWithoutPermission(self):
        """
        L{SecureObjectAPI.search} raises a L{PermissionDeniedError} if the
        anonymous user doesn't have C{Operation.READ_TAG_VALUE} permissions on
        the requested L{Tag.path}s.
        """
        objectID = uuid4()
        index = ObjectIndex(self.client)
        yield index.update({objectID: {u'username/tag': 42}})
        yield self.client.commit()
        self.permissions.set([(u'username/tag', Operation.READ_TAG_VALUE,
                               Policy.CLOSED, [])])
        query = parseQuery(u'username/tag = 42')
        error = self.assertRaises(PermissionDeniedError, self.objects.search,
                                  [query])
        self.assertEqual(u'anon', error.username)
        self.assertEqual([('username/tag', Operation.READ_TAG_VALUE)],
                         error.pathsAndOperations)

    @inlineCallbacks
    def testSearchWithImplicitObjectCreation(self):
        """
        L{SecureObjectAPI.search} doesn't raise a L{PermissionDeniedError} if
        the anonymous user tries to create new objects using C{fluiddb/about}
        queries, instead an empty result is returned.
        """
        query = parseQuery(u'fluiddb/about = "TestObject"')
        result = self.objects.search([query], True)
        result = yield result.get()
        self.assertEqual({query: set()}, result)