Beispiel #1
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()
Beispiel #2
0
 def setUp(self):
     super(NamespaceAPITest, self).setUp()
     self.system = createSystemData()
     UserAPI().create([(u'username', u'password', u'User',
                        u'*****@*****.**')])
     self.user = getUser(u'username')
     self.namespaces = NamespaceAPI(self.user)
     self.permissions = PermissionAPI(self.user)
Beispiel #3
0
    def testPrepareForTestingCreatesNamespaces(self):
        """
        L{prepareForTesting} creates all the necessary testing L{Namespace}s.
        """
        prepareForTesting()

        paths = [u'fluiddb/testing/testing',
                 u'testuser1/testing/testing',
                 u'testuser2/testing/testing']
        namespaces = NamespaceAPI(self.admin).get(paths)
        self.assertEqual(paths, sorted(namespaces.iterkeys()))
Beispiel #4
0
    def testDeleteNamespace(self):
        """L{Facade.deleteNamespace} deletes a L{Namespace}."""
        namespaces = NamespaceAPI(self.user)
        namespaces.create([(u'username/name', u'A namespace.')])
        self.store.commit()

        with login(u'username', self.user.objectID, self.transact) as session:
            yield self.facade.deleteNamespace(session, u'username/name')

        self.store.rollback()
        self.assertEqual({}, namespaces.get([u'username/name']))
Beispiel #5
0
    def testDeleteNamespace(self):
        """L{Facade.deleteNamespace} deletes a L{Namespace}."""
        namespaces = NamespaceAPI(self.user)
        namespaces.create([(u'username/name', u'A namespace.')])
        self.store.commit()

        with login(u'username', self.user.objectID, self.transact) as session:
            yield self.facade.deleteNamespace(session, u'username/name')

        self.store.rollback()
        self.assertEqual({}, namespaces.get([u'username/name']))
Beispiel #6
0
    def testPrepareForTestingCreatesNamespaces(self):
        """
        L{prepareForTesting} creates all the necessary testing L{Namespace}s.
        """
        prepareForTesting()

        paths = [
            u'fluiddb/testing/testing', u'testuser1/testing/testing',
            u'testuser2/testing/testing'
        ]
        namespaces = NamespaceAPI(self.admin).get(paths)
        self.assertEqual(paths, sorted(namespaces.iterkeys()))
Beispiel #7
0
    def testGetNamespaceWithDescription(self):
        """
        L{Facade.getNamespace} includes the L{Namespace.description}, if it
        was requested.
        """
        namespaces = NamespaceAPI(self.user)
        namespaces.create([(u'username/name', u'A namespace.')])
        self.store.commit()

        with login(u'username', self.user.objectID, self.transact) as session:
            result = yield self.facade.getNamespace(session, u'username/name',
                                                    True, False, False)
        self.assertEqual(u'A namespace.', result.description)
Beispiel #8
0
    def testGetNamespaceWithNamespaces(self):
        """
        L{Facade.getNamespace} includes child L{Namespace.name}s, if they were
        requested.
        """
        namespaces = NamespaceAPI(self.user)
        namespaces.create([(u'username/name', u'A namespace.')])
        self.store.commit()

        with login(u'username', self.user.objectID, self.transact) as session:
            result = yield self.facade.getNamespace(session, u'username',
                                                    False, True, False)
        self.assertEqual([u'name', u'private'], sorted(result.namespaces))
Beispiel #9
0
    def testGetNamespaceWithDescription(self):
        """
        L{Facade.getNamespace} includes the L{Namespace.description}, if it
        was requested.
        """
        namespaces = NamespaceAPI(self.user)
        namespaces.create([(u'username/name', u'A namespace.')])
        self.store.commit()

        with login(u'username', self.user.objectID, self.transact) as session:
            result = yield self.facade.getNamespace(session, u'username/name',
                                                    True, False, False)
        self.assertEqual(u'A namespace.', result.description)
Beispiel #10
0
    def testGetNamespaceWithNamespaces(self):
        """
        L{Facade.getNamespace} includes child L{Namespace.name}s, if they were
        requested.
        """
        namespaces = NamespaceAPI(self.user)
        namespaces.create([(u'username/name', u'A namespace.')])
        self.store.commit()

        with login(u'username', self.user.objectID, self.transact) as session:
            result = yield self.facade.getNamespace(session, u'username',
                                                    False, True, False)
        self.assertEqual([u'name', u'private'], sorted(result.namespaces))
Beispiel #11
0
    def testDeleteNamespaceWithData(self):
        """
        L{Facade.deleteNamespace} raises a L{TNamespaceNotEmpty} exception if
        the requested L{Namespace} has child data such as other L{Namespace}s
        or L{Tag}s.
        """
        namespaces = NamespaceAPI(self.user)
        namespaces.create([(u'username/parent', u'A parent namespace.')])
        namespaces.create([(u'username/parent/child', u'A child namespace.')])
        self.store.commit()

        with login(u'username', self.user.objectID, self.transact) as session:
            deferred = self.facade.deleteNamespace(session, u'username/parent')
            yield self.assertFailure(deferred, TNamespaceNotEmpty)
Beispiel #12
0
    def testDeleteIsDenied(self):
        """
        L{Facade.deleteNamespace} raises a L{TPathPermissionDenied} exception
        if the user doesn't have C{DELETE} permissions on the specified
        L{Namespace}.
        """
        namespaces = NamespaceAPI(self.user)
        namespaces.create([(u'username/test', u'description')])
        self.permissions.set([(u'username/test', Operation.DELETE_NAMESPACE,
                               Policy.OPEN, [u'username'])])
        self.store.commit()

        with login(u'username', self.user.objectID, self.transact) as session:
            deferred = self.facade.deleteNamespace(session, u'username/test')
            yield self.assertFailure(deferred, TPathPermissionDenied)
Beispiel #13
0
def apply(store):
    # Using model code in a patch isn't ideal, but writing this patch with
    # pure SQL will be heinous.
    for user in getUsers():
        if user.username in ('fluiddb', 'anon'):
            continue
        namespaces = NamespaceAPI(user)
        path = '%s/private' % user.username
        if not namespaces.get([path]):
            namespaces.create([
                (path, u'Private namespace for user %s' % user.username)
            ])
            namespace = getNamespaces(paths=[path]).one()
            permission = namespace.permission
            permission.set(Operation.LIST_NAMESPACE, Policy.CLOSED, [user.id])
Beispiel #14
0
    def testDeleteIsDenied(self):
        """
        L{Facade.deleteNamespace} raises a L{TPathPermissionDenied} exception
        if the user doesn't have C{DELETE} permissions on the specified
        L{Namespace}.
        """
        namespaces = NamespaceAPI(self.user)
        namespaces.create([(u'username/test', u'description')])
        self.permissions.set([(u'username/test', Operation.DELETE_NAMESPACE,
                               Policy.OPEN, [u'username'])])
        self.store.commit()

        with login(u'username', self.user.objectID, self.transact) as session:
            deferred = self.facade.deleteNamespace(session, u'username/test')
            yield self.assertFailure(deferred, TPathPermissionDenied)
Beispiel #15
0
class NamespaceAPITest(NamespaceAPITestMixin, FluidinfoTestCase):

    resources = [('config', ConfigResource()),
                 ('store', DatabaseResource())]

    def setUp(self):
        super(NamespaceAPITest, self).setUp()
        self.system = createSystemData()
        UserAPI().create([(u'username', u'password', u'User',
                           u'*****@*****.**')])
        self.user = getUser(u'username')
        self.namespaces = NamespaceAPI(self.user)
        self.permissions = PermissionAPI(self.user)

    def testCreateWithoutData(self):
        """
        L{NamespaceAPI.create} returns an empty C{list} if no L{Namespace}
        data is available.
        """
        result = self.namespaces.create([])
        self.assertEqual([], result)
        ignored = (
            self.system.namespaces.keys() + [u'username', u'username/private'])
        result = self.store.find(Namespace, Not(Namespace.path.is_in(ignored)))
        self.assertIdentical(None, result.one())

    def testPermissionsAreNotCreatedIfCreateFails(self):
        """
        If L{NamespaceAPI.create} fails, no permissions should be created.
        """
        self.assertRaises(MalformedPathError, self.namespaces.create,
                          [(u'!!!!/test', u'description')])

        result = getNamespacePermissions([u'username/test'])
        self.assertTrue(result.is_empty())
Beispiel #16
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())
Beispiel #17
0
class NamespaceAPITest(NamespaceAPITestMixin, FluidinfoTestCase):

    resources = [('config', ConfigResource()), ('store', DatabaseResource())]

    def setUp(self):
        super(NamespaceAPITest, self).setUp()
        self.system = createSystemData()
        UserAPI().create([(u'username', u'password', u'User',
                           u'*****@*****.**')])
        self.user = getUser(u'username')
        self.namespaces = NamespaceAPI(self.user)
        self.permissions = PermissionAPI(self.user)

    def testCreateWithoutData(self):
        """
        L{NamespaceAPI.create} returns an empty C{list} if no L{Namespace}
        data is available.
        """
        result = self.namespaces.create([])
        self.assertEqual([], result)
        ignored = (self.system.namespaces.keys() +
                   [u'username', u'username/private'])
        result = self.store.find(Namespace, Not(Namespace.path.is_in(ignored)))
        self.assertIdentical(None, result.one())

    def testPermissionsAreNotCreatedIfCreateFails(self):
        """
        If L{NamespaceAPI.create} fails, no permissions should be created.
        """
        self.assertRaises(MalformedPathError, self.namespaces.create,
                          [(u'!!!!/test', u'description')])

        result = getNamespacePermissions([u'username/test'])
        self.assertTrue(result.is_empty())
Beispiel #18
0
    def testUpdateNamespace(self):
        """
        L{Facade.updateNamespace} updates the description for an existing
        L{Namespace}.
        """
        namespaces = NamespaceAPI(self.user)
        namespaces.create([(u'username/name', u'A namespace.')])
        self.store.commit()

        with login(u'username', self.user.objectID, self.transact) as session:
            yield self.facade.updateNamespace(session, u'username/name',
                                              u'A new description.')

        self.store.rollback()
        result = namespaces.get([u'username/name'], withDescriptions=True)
        self.assertEqual(u'A new description.',
                         result[u'username/name']['description'])
Beispiel #19
0
 def setUp(self):
     super(NamespaceAPITest, self).setUp()
     self.system = createSystemData()
     UserAPI().create([(u'username', u'password', u'User',
                        u'*****@*****.**')])
     self.user = getUser(u'username')
     self.namespaces = NamespaceAPI(self.user)
     self.permissions = PermissionAPI(self.user)
Beispiel #20
0
    def testUpdateNamespace(self):
        """
        L{Facade.updateNamespace} updates the description for an existing
        L{Namespace}.
        """
        namespaces = NamespaceAPI(self.user)
        namespaces.create([(u'username/name', u'A namespace.')])
        self.store.commit()

        with login(u'username', self.user.objectID, self.transact) as session:
            yield self.facade.updateNamespace(session, u'username/name',
                                              u'A new description.')

        self.store.rollback()
        result = namespaces.get([u'username/name'], withDescriptions=True)
        self.assertEqual(u'A new description.',
                         result[u'username/name']['description'])
Beispiel #21
0
 def testRemoveTestingDataWithPartialData(self):
     """
     L{removeTestingData} only tries to remove testing data that exists.
     """
     UserAPI().create([(u'testuser1', 'secret', u'Test user',
                        u'*****@*****.**')])
     NamespaceAPI(self.admin).delete([u'testuser1/private'])
     removeTestingData()
     users = UserAPI().get([u'testuser1', u'testuser2'])
     self.assertEquals({}, users)
Beispiel #22
0
class CachingNamespaceAPI(object):
    """The public API to cached namespace-related logic in the model.

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

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

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

        Permissions for deleted L{Namespace}s are removed from the cache.
        """
        if isgenerator(paths):
            paths = list(paths)
        cache = PermissionCache()
        cache.clearNamespacePermissions(paths)
        return self._api.delete(paths)

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

    def set(self, values):
        """Set or update L{Namespace}s.

        @param values: A C{dict} mapping L{Namespace.path}s to descriptions.
        @return: A C{list} of C{(objectID, Namespace.path)} 2-tuples
            representing the L{Namespace}s that were updated.
        """
        return self._api.set(values)
Beispiel #23
0
    def testRemoveTestingDataRemovesNamespaces(self):
        """L{removeTestingData} removes all the testing L{Namespace}s."""
        prepareForTesting()
        removeTestingData()

        paths = [
            u'fluiddb/testing/testing', u'testuser1/testing/testing',
            u'testuser2/testing/testing'
        ]
        namespaces = NamespaceAPI(self.admin).get(paths)
        self.assertEqual({}, namespaces)
Beispiel #24
0
class CachingNamespaceAPI(object):
    """The public API to cached namespace-related logic in the model.

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

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

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

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

        Permissions for deleted L{Namespace}s are removed from the cache.
        """
        if isgenerator(paths):
            paths = list(paths)
        cache = PermissionCache()
        cache.clearNamespacePermissions(paths)
        return self._api.delete(paths)

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

    def set(self, values):
        """Set or update L{Namespace}s.

        @param values: A C{dict} mapping L{Namespace.path}s to descriptions.
        @return: A C{list} of C{(objectID, Namespace.path)} 2-tuples
            representing the L{Namespace}s that were updated.
        """
        return self._api.set(values)
Beispiel #25
0
 def testCreateRootNamespace(self):
     """
     L{NamespaceAPI.create} creates new root L{Namespace}s based on the
     provided data.
     """
     superuser = self.system.users[u'fluiddb']
     values = [(u'root-namespace', u'A description.')]
     NamespaceAPI(superuser).create(values)
     result = self.store.find(Namespace,
                              Namespace.path == u'root-namespace')
     namespace = result.one()
     self.assertEqual(u'root-namespace', namespace.path)
     self.assertEqual(u'root-namespace', namespace.name)
     self.assertIdentical(None, namespace.parent)
Beispiel #26
0
def prepareForTesting():
    """
    Create a set of L{User}s, L{Namespace}s and L{Tag}s for testing purposes.
    """
    admin = getUser(u'fluiddb')
    logging.info('Creating testing users.')
    UserAPI().create([(username, 'secret', u'Test user', u'*****@*****.**')
                      for username in TESTING_DATA[u'users']])
    logging.info('Creating testing namespaces.')
    NamespaceAPI(admin).create([(namespace, u'Used for testing purposes.')
                                for namespace in TESTING_DATA[u'namespaces']])
    logging.info('Creating testing tags.')
    TagAPI(admin).create([(tag, u'Used for testing purposes.')
                          for tag in TESTING_DATA[u'tags']])
    getMainStore().commit()
Beispiel #27
0
    def testCheckWithSuperuser(self):
        """
        L{checkPermissions} always grants access if the user is superuser.
        """
        TagAPI(self.user).create([(u'username/path', u'description')])
        NamespaceAPI(self.user).create([(u'username/path', u'description')])
        superuser = self.system.users[u'fluiddb']
        # Close all permissions for the tag
        values = [(u'username/path', operation, Policy.CLOSED, [])
                  for operation in Operation.PATH_OPERATIONS]
        self.permissions.set(values)

        values = [(u'username/path', operation)
                  for operation in Operation.PATH_OPERATIONS]
        deniedOperations = checkPermissions(superuser, values)
        self.assertEqual([], deniedOperations)
Beispiel #28
0
 def testDeleteRemovesSystemTags(self):
     """
     L{UserAPI.delete} removes the C{fluiddb/users/*} tag values stored for
     deleted L{User}s.
     """
     self.users.create([(u'user', u'pass', u'User', u'*****@*****.**')])
     user = getUser(u'user')
     NamespaceAPI(user).delete([u'user/private'])
     [(objectID, _)] = self.users.delete([u'user'])
     tagValues = TagValueAPI(self.system.users[u'fluiddb'])
     result = tagValues.get(objectIDs=[objectID],
                            paths=[
                                u'fluiddb/users/username',
                                u'fluiddb/users/name',
                                u'fluiddb/users/email',
                                u'fluiddb/users/role'
                            ])
     self.assertEqual({}, result)
Beispiel #29
0
    def testCheckWithSuperuserWithMissingPermission(self):
        """
        L{checkPermissions} always grants access if the user is superuser,
        even if there is no permission defined for the entity for which access
        is requested.
        """
        TagAPI(self.user).create([(u'username/path', u'description')])
        NamespaceAPI(self.user).create([(u'username/path', u'description')])
        superuser = self.system.users[u'fluiddb']
        # Close all permissions for the tag
        values = [(u'username/path', operation, Policy.CLOSED, [])
                  for operation in Operation.NAMESPACE_OPERATIONS]
        self.permissions.set(values)

        values = [(u'username/path', operation)
                  for operation in Operation.NAMESPACE_OPERATIONS]
        deniedOperations = checkPermissions(superuser, values)
        self.assertEqual([], deniedOperations)
Beispiel #30
0
 def testCheckAnonymousForbiddenOperations(self):
     """
     L{checkPermissions} always denies C{CREATE}, C{UPDATE}, or
     C{DELETE} operations if the user is anonymous.
     """
     TagAPI(self.user).create([(u'username/path', u'description')])
     NamespaceAPI(self.user).create([(u'username/path', u'description')])
     anonymous = self.system.users[u'anon']
     forbiddenOperations = (Operation.TAG_OPERATIONS +
                            Operation.NAMESPACE_OPERATIONS +
                            Operation.USER_OPERATIONS +
                            Operation.CONTROL_OPERATIONS +
                            [Operation.CREATE_OBJECT])
     for operation in Operation.ALLOWED_ANONYMOUS_OPERATIONS:
         forbiddenOperations.remove(operation)
     values = [(u'username/path', operation)
               for operation in forbiddenOperations]
     deniedOperations = checkPermissions(anonymous, values)
     self.assertEqual(sorted(values), sorted(deniedOperations))
Beispiel #31
0
    def testDeleteNamespaceWithData(self):
        """
        L{Facade.deleteNamespace} raises a L{TNamespaceNotEmpty} exception if
        the requested L{Namespace} has child data such as other L{Namespace}s
        or L{Tag}s.
        """
        namespaces = NamespaceAPI(self.user)
        namespaces.create([(u'username/parent', u'A parent namespace.')])
        namespaces.create([(u'username/parent/child', u'A child namespace.')])
        self.store.commit()

        with login(u'username', self.user.objectID, self.transact) as session:
            deferred = self.facade.deleteNamespace(session, u'username/parent')
            yield self.assertFailure(deferred, TNamespaceNotEmpty)
Beispiel #32
0
    def testRemoveTestingDataWithNonexistentData(self):
        """
        L{removeTestingData} doesn't remove anything it the testing data
        doesn't exist.
        """
        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)
        paths = [
            u'fluiddb/testing/testing', u'testuser1/testing/testing',
            u'testuser2/testing/testing'
        ]
        namespaces = NamespaceAPI(self.admin).get(paths)
        self.assertEqual({}, namespaces)
        users = UserAPI().get([u'testuser1', u'testuser2'])
        self.assertEquals({}, users)
Beispiel #33
0
    def testCheckIntegrityGetsAllRowsUsingMultipleQueries(self):
        """
        L{checkIntegrity} should check all the rows of a given object using
        multiple queries if the C{maxRowsPerQuery} argument is smaller than the
        total number of rows for a given object.
        """
        createSystemData()
        UserAPI().create([(u'user', u'pass', u'Name', u'*****@*****.**')])
        user = getUser(u'user')
        paths = [u'user/namespace%d' % i for i in xrange(10)]
        values = [(path, u'description') for path in paths]
        NamespaceAPI(user).create(values)
        namespaces = getNamespaces(paths=paths)
        values = [(namespace.objectID, u'fluiddb/namespaces/path')
                  for namespace in namespaces]
        TagValueAPI(user).delete(values)

        checkIntegrity(maxRowsPerQuery=2)

        error = 'Integrity Error in namespace %r: Path tag is missing.'
        expectedErrors = '\n'.join(error % path for path in paths) + '\n'
        self.assertEqual(expectedErrors, self.log.getvalue())
Beispiel #34
0
 def __init__(self, user):
     self._api = NamespaceAPI(user, factory=CachingAPIFactory())
Beispiel #35
0
 def namespaces(self, user):
     """Get a new L{NamespaceAPI} instance."""
     from fluiddb.model.namespace import NamespaceAPI
     return NamespaceAPI(user)
Beispiel #36
0
 def __init__(self, user):
     self._api = NamespaceAPI(user, factory=CachingAPIFactory())