Exemplo n.º 1
0
class SecureNamespaceAPIWithSuperuserTest(FluidinfoTestCase):

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

    def setUp(self):
        super(SecureNamespaceAPIWithSuperuserTest, self).setUp()
        system = createSystemData()
        user = system.users[u'fluiddb']
        self.namespaces = SecureNamespaceAPI(user)
        self.permissions = CachingPermissionAPI(user)

    def testCreateIsAllowed(self):
        """
        Creating a new L{Namespace} should be allowed if we're a user with a
        L{Role.SUPERUSER} no matter what permissions we have.
        """
        values = [(u'fluiddb', Operation.CREATE_NAMESPACE, Policy.CLOSED, [])]
        self.permissions.set(values)
        result = self.namespaces.create([(u'fluiddb/test', u'description')])
        self.assertEqual(1, len(result))

    def testDeleteIsAllowed(self):
        """
        Deleting a L{Namespace} should be allowed if we're a user with a
        L{Role.SUPERUSER} no matter what permissions we have.
        """
        result1 = self.namespaces.create([(u'fluiddb/test', u'description')])
        values = [(u'fluiddb/test', Operation.DELETE_NAMESPACE, Policy.CLOSED,
                   [])]
        self.permissions.set(values)
        result2 = self.namespaces.delete([u'fluiddb/test'])
        self.assertEqual(result1, result2)

    def testSetIsAllowed(self):
        """
        Updating a L{Namespace} should be allowed if we're a user with a
        L{Role.SUPERUSER} no matter what permissions we have.
        """
        self.namespaces.create([(u'fluiddb/test', u'description')])
        values = [(u'fluiddb/test', Operation.UPDATE_NAMESPACE, Policy.CLOSED,
                   [])]
        self.permissions.set(values)
        self.namespaces.set({u'fluiddb/test': u'new description'})

    def testGetIsAllowed(self):
        """
        Getting information about a L{Namespace} should be allowed if we're a
        user with a L{Role.SUPERUSER} no matter what permissions we have.
        """
        self.namespaces.create([(u'fluiddb/test', u'description')])
        values = [(u'fluiddb/test', Operation.LIST_NAMESPACE, Policy.CLOSED,
                   [])]
        self.permissions.set(values)
        result = self.namespaces.get([u'fluiddb'],
                                     withDescriptions=False,
                                     withTags=True,
                                     withNamespaces=True)
        self.assertEqual(1, len(result))
Exemplo n.º 2
0
class SecureNamespaceAPIWithSuperuserTest(FluidinfoTestCase):

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

    def setUp(self):
        super(SecureNamespaceAPIWithSuperuserTest, self).setUp()
        system = createSystemData()
        user = system.users[u'fluiddb']
        self.namespaces = SecureNamespaceAPI(user)
        self.permissions = CachingPermissionAPI(user)

    def testCreateIsAllowed(self):
        """
        Creating a new L{Namespace} should be allowed if we're a user with a
        L{Role.SUPERUSER} no matter what permissions we have.
        """
        values = [(u'fluiddb', Operation.CREATE_NAMESPACE, Policy.CLOSED, [])]
        self.permissions.set(values)
        result = self.namespaces.create([(u'fluiddb/test', u'description')])
        self.assertEqual(1, len(result))

    def testDeleteIsAllowed(self):
        """
        Deleting a L{Namespace} should be allowed if we're a user with a
        L{Role.SUPERUSER} no matter what permissions we have.
        """
        result1 = self.namespaces.create([(u'fluiddb/test', u'description')])
        values = [(u'fluiddb/test', Operation.DELETE_NAMESPACE,
                   Policy.CLOSED, [])]
        self.permissions.set(values)
        result2 = self.namespaces.delete([u'fluiddb/test'])
        self.assertEqual(result1, result2)

    def testSetIsAllowed(self):
        """
        Updating a L{Namespace} should be allowed if we're a user with a
        L{Role.SUPERUSER} no matter what permissions we have.
        """
        self.namespaces.create([(u'fluiddb/test', u'description')])
        values = [(u'fluiddb/test', Operation.UPDATE_NAMESPACE,
                   Policy.CLOSED, [])]
        self.permissions.set(values)
        self.namespaces.set({u'fluiddb/test': u'new description'})

    def testGetIsAllowed(self):
        """
        Getting information about a L{Namespace} should be allowed if we're a
        user with a L{Role.SUPERUSER} no matter what permissions we have.
        """
        self.namespaces.create([(u'fluiddb/test', u'description')])
        values = [(u'fluiddb/test', Operation.LIST_NAMESPACE,
                   Policy.CLOSED, [])]
        self.permissions.set(values)
        result = self.namespaces.get([u'fluiddb'], withDescriptions=False,
                                     withTags=True, withNamespaces=True)
        self.assertEqual(1, len(result))
Exemplo n.º 3
0
class SecurePermissionAPI(object):
    """The public API to secure permission-related functionality.

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

    def __init__(self, user):
        self._user = user
        self._permissions = CachingPermissionAPI(user)

    def get(self, values):
        """See L{PermissionAPI.get}.

        @raise PermissionDeniedError: Raised if the user is not authorized to
            see the specified permissions.
        """
        self._checkPermissions(values)
        return self._permissions.get(values)

    def set(self, values):
        """See L{PermissionAPI.set}.

        @raise PermissionDeniedError: Raised if the user is not authorized to
            change the specified permissions.
        """
        self._checkPermissions([(path, operation)
                                for path, operation, _, _ in values])
        return self._permissions.set(values)

    def _checkPermissions(self, values):
        """Check C{CONTROL} permissions for a set of path-operation pairs.

        @param values: A sequence of C{(path, Operation)} 2-tuples with the
            that should be checked.
        @raise PermissionDeniedError: Raised if the user doesn't have
            C{CONTROL} permissions for a given path-L{Operation} pair.
        @raise RuntimeError: Raised if an invalid L{Operation} is provided.
        """
        pathsAndOperations = set()
        for path, operation in values:
            if operation in [Operation.WRITE_TAG_VALUE,
                             Operation.READ_TAG_VALUE,
                             Operation.DELETE_TAG_VALUE,
                             Operation.CONTROL_TAG_VALUE]:
                pathsAndOperations.add((path, Operation.CONTROL_TAG_VALUE))
            elif operation in [Operation.UPDATE_TAG, Operation.DELETE_TAG,
                               Operation.CONTROL_TAG]:
                pathsAndOperations.add((path, Operation.CONTROL_TAG))
            elif operation in Operation.NAMESPACE_OPERATIONS:
                pathsAndOperations.add((path, Operation.CONTROL_NAMESPACE))
            else:
                raise RuntimeError('Invalid operation %r.' % operation)

        deniedOperations = checkPermissions(self._user, pathsAndOperations)
        if deniedOperations:
            raise PermissionDeniedError(self._user.username, deniedOperations)
Exemplo n.º 4
0
class SecureTagAPIWithSuperuserTest(FluidinfoTestCase):

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

    def setUp(self):
        super(SecureTagAPIWithSuperuserTest, self).setUp()
        system = createSystemData()
        user = system.users[u'fluiddb']
        self.tags = SecureTagAPI(user)
        self.permissions = CachingPermissionAPI(user)

    def testCreateIsAllowed(self):
        """
        Creating a new L{Tag} should be allowed if we're a user with a
        L{Role.SUPERUSER} no matter what permissions we have.
        """
        values = [(u'fluiddb', Operation.CREATE_NAMESPACE, Policy.CLOSED, [])]
        self.permissions.set(values)
        result = self.tags.create([(u'fluiddb/test', u'description')])
        self.assertEqual(1, len(result))

    def testDeleteIsAllowed(self):
        """
        Deleting a L{Tag} should be allowed if we're a user with a
        L{Role.SUPERUSER} no matter what permissions we have.
        """
        result1 = self.tags.create([(u'fluiddb/test', u'description')])
        values = [(u'fluiddb/test', Operation.DELETE_TAG, Policy.CLOSED, [])]
        self.permissions.set(values)
        result2 = self.tags.delete([u'fluiddb/test'])
        self.assertEqual(result1, result2)

    def testSetIsAllowed(self):
        """
        Updating a L{Tag} should be allowed if we're a user with a
        L{Role.SUPERUSER} no matter what permissions we have.
        """
        result = self.tags.create([(u'fluiddb/test', u'A description')])
        [(objectID, _)] = result
        values = [(u'fluiddb/test', Operation.UPDATE_TAG, Policy.CLOSED, [])]
        self.permissions.set(values)
        self.tags.set({u'fluiddb/test': u'A new description'})

        result = self.tags.get([u'fluiddb/test'], withDescriptions=True)
        expected = {
            u'fluiddb/test': {
                'id': objectID,
                'description': u'A new description'
            }
        }
        self.assertEqual(expected, result)
Exemplo n.º 5
0
class SecureTagAPIWithSuperuserTest(FluidinfoTestCase):

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

    def setUp(self):
        super(SecureTagAPIWithSuperuserTest, self).setUp()
        system = createSystemData()
        user = system.users[u'fluiddb']
        self.tags = SecureTagAPI(user)
        self.permissions = CachingPermissionAPI(user)

    def testCreateIsAllowed(self):
        """
        Creating a new L{Tag} should be allowed if we're a user with a
        L{Role.SUPERUSER} no matter what permissions we have.
        """
        values = [(u'fluiddb', Operation.CREATE_NAMESPACE, Policy.CLOSED, [])]
        self.permissions.set(values)
        result = self.tags.create([(u'fluiddb/test', u'description')])
        self.assertEqual(1, len(result))

    def testDeleteIsAllowed(self):
        """
        Deleting a L{Tag} should be allowed if we're a user with a
        L{Role.SUPERUSER} no matter what permissions we have.
        """
        result1 = self.tags.create([(u'fluiddb/test', u'description')])
        values = [(u'fluiddb/test', Operation.DELETE_TAG, Policy.CLOSED, [])]
        self.permissions.set(values)
        result2 = self.tags.delete([u'fluiddb/test'])
        self.assertEqual(result1, result2)

    def testSetIsAllowed(self):
        """
        Updating a L{Tag} should be allowed if we're a user with a
        L{Role.SUPERUSER} no matter what permissions we have.
        """
        result = self.tags.create([(u'fluiddb/test', u'A description')])
        [(objectID, _)] = result
        values = [(u'fluiddb/test', Operation.UPDATE_TAG, Policy.CLOSED, [])]
        self.permissions.set(values)
        self.tags.set({u'fluiddb/test': u'A new description'})

        result = self.tags.get([u'fluiddb/test'], withDescriptions=True)
        expected = {u'fluiddb/test': {'id': objectID,
                                      'description': u'A new description'}}
        self.assertEqual(expected, result)
Exemplo n.º 6
0
class SecureTagValueAPIWithSuperuserRoleTest(FluidinfoTestCase):

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

    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)

    def testGetIsAllowed(self):
        """L{SecureTagValueAPI.get} is always allowed for the superuser."""
        objectID = uuid4()
        values = {objectID: {u'fluiddb/tag': 16}}
        self.tagValues.set(values)
        self.permissions.set([(u'fluiddb/tag', Operation.READ_TAG_VALUE,
                               Policy.CLOSED, [])])
        result = self.tagValues.get(objectIDs=[objectID],
                                    paths=[u'fluiddb/tag'])
        self.assertEqual(16, result[objectID][u'fluiddb/tag'].value)

    def testSetIsAllowed(self):
        """L{SecureTagValueAPI.set} is always allowed for the superuser."""
        self.permissions.set([(u'fluiddb/tag', Operation.WRITE_TAG_VALUE,
                               Policy.CLOSED, [])])
        objectID = uuid4()
        values = {objectID: {u'fluiddb/tag': 16}}
        self.tagValues.set(values)
        result = self.tagValues.get(objectIDs=[objectID],
                                    paths=[u'fluiddb/tag'])
        self.assertEqual(16, result[objectID][u'fluiddb/tag'].value)

    def testDeleteIsAllowed(self):
        """L{SecureTagValueAPI.delete} is always allowed for the superuser."""
        self.permissions.set([(u'fluiddb/tag', Operation.DELETE_TAG_VALUE,
                               Policy.CLOSED, [])])
        objectID = uuid4()
        values = {objectID: {u'fluiddb/tag': 16}}
        self.tagValues.set(values)
        self.tagValues.delete([(objectID, u'fluiddb/tag')])
        result = self.tagValues.get(objectIDs=[objectID],
                                    paths=[u'fluiddb/tag'])
        self.assertEqual({}, result)
Exemplo n.º 7
0
class SecureTagAPIWithNormalUserTest(FluidinfoTestCase):

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

    def setUp(self):
        super(SecureTagAPIWithNormalUserTest, self).setUp()
        createSystemData()
        UserAPI().create([(u'user', u'password', u'User', u'*****@*****.**')
                          ])
        self.user = getUser(u'user')
        self.permissions = CachingPermissionAPI(self.user)
        self.tags = SecureTagAPI(self.user)

    def testCreateIsAllowed(self):
        """
        L{SecureTagAPI.create} should allow the creation of tags whose parent
        namespace has open C{Operation.CREATE_NAMESPACE} permissions.
        """
        result = self.tags.create([(u'user/test', u'description')])
        self.assertEqual(1, len(result))

    def testCreateIsDenied(self):
        """
        L{SecureTagAPI.create} should raise L{PermissonDeniedError} if
        the user doesn't have C{Operation.CREATE_NAMESPACE} permissions on the
        parent namespace.
        """
        values = [(u'user', Operation.CREATE_NAMESPACE, Policy.CLOSED, [])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError, self.tags.create,
                                  [(u'user/test', u'description')])
        self.assertEqual([(u'user', Operation.CREATE_NAMESPACE)],
                         sorted(error.pathsAndOperations))

    def testDeleteIsAllowed(self):
        """
        L{SecureTagAPI.delete} should allow the deletion of a tag if the user
        has C{Operation.DELETE_TAG} permissions.
        """
        result1 = self.tags.create([(u'user/test', u'description')])
        result2 = self.tags.delete([u'user/test'])
        self.assertEqual(result1, result2)

    def testDeleteIsDenied(self):
        """
        L{SecureTagAPI.delete} should raise L{PermissonDeniedError} if the
        user doesn't have C{Operation.DELETE_TAG} permissions.
        """
        self.tags.create([(u'user/test', u'description')])
        values = [(u'user/test', Operation.DELETE_TAG, Policy.OPEN, [u'user'])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError, self.tags.delete,
                                  [(u'user/test')])
        self.assertEqual([(u'user/test', Operation.DELETE_TAG)],
                         sorted(error.pathsAndOperations))

    def testSetIsAllowed(self):
        """
        L{SecureTagAPI.get} should allow updating the description of a tag if
        the user has permissions.
        """
        [(objectID, _)] = self.tags.create([(u'user/test', u'A description')])
        self.tags.set({u'user/test': u'A new description'})
        result = self.tags.get([u'user/test'], withDescriptions=True)
        expected = {
            u'user/test': {
                'id': objectID,
                'description': u'A new description'
            }
        }
        self.assertEqual(expected, result)

    def testSetIsDenied(self):
        """
        L{SecureTagAPI.get} should raise L{PermissonDeniedError} if the user
        doesn't have C{Operation.UPDATE_TAG} permissions when trying to update
        a tag's description.
        """
        self.tags.create([(u'user/test', u'description')])
        values = [(u'user/test', Operation.UPDATE_TAG, Policy.CLOSED, [])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError, self.tags.set,
                                  {u'user/test': u'description'})
        self.assertEqual([(u'user/test', Operation.UPDATE_TAG)],
                         sorted(error.pathsAndOperations))
Exemplo n.º 8
0
class SecureNamespaceAPIWithNormalUserTest(FluidinfoTestCase):

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

    def setUp(self):
        super(SecureNamespaceAPIWithNormalUserTest, self).setUp()
        createSystemData()

        UserAPI().create([(u'user', u'password', u'User', u'*****@*****.**')
                          ])
        self.user = getUser(u'user')
        self.permissions = CachingPermissionAPI(self.user)
        self.namespaces = SecureNamespaceAPI(self.user)

    def testCreateIsAllowed(self):
        """
        L{SecureNamespaceAPI.create} should allow the creation of namespaces
        whose parent has open CREATE permissions.
        """
        values = [(u'user', Operation.CREATE_NAMESPACE, Policy.OPEN, [])]
        self.permissions.set(values)
        result = self.namespaces.create([(u'user/test', u'description')])
        self.assertEqual(1, len(result))

    def testCreateIsDenied(self):
        """
        L{SecureNamespaceAPI.create} should raise L{PermissonDeniedError} if
        the user doesn't have CREATE permissions on the parent namespace.
        """
        values = [(u'user', Operation.CREATE_NAMESPACE, Policy.CLOSED, [])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError,
                                  self.namespaces.create,
                                  [(u'user/test', u'description')])
        self.assertEqual([(u'user', Operation.CREATE_NAMESPACE)],
                         sorted(error.pathsAndOperations))

    def testDeleteIsAllowed(self):
        """
        {SecureNamespaceAPI.delete} should allow the deletion of a namespace
        if the user has DELETE permissions.
        """
        result1 = self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user/test', Operation.DELETE_NAMESPACE, Policy.OPEN, [])]
        self.permissions.set(values)
        result2 = self.namespaces.delete([u'user/test'])
        self.assertEqual(result1, result2)

    def testDeleteIsDenied(self):
        """
        L{SecureNamespaceAPI.delete} should raise L{PermissonDeniedError} if
        the user doesn't have DELETE permissions.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user/test', Operation.DELETE_NAMESPACE, Policy.OPEN,
                   [u'user'])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError,
                                  self.namespaces.delete, [(u'user/test')])
        self.assertEqual([(u'user/test', Operation.DELETE_NAMESPACE)],
                         sorted(error.pathsAndOperations))

    def testGetChildNamespacesIsAllowed(self):
        """
        L{SecureNamespaceAPI.get} should allow getting a list of child
        namespaces if the user has permissions.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user', Operation.LIST_NAMESPACE, Policy.OPEN, [])]
        self.permissions.set(values)
        result = self.namespaces.get([u'user'], withNamespaces=True)
        self.assertEqual(1, len(result))

    def testGetChildNamespacesIsDenied(self):
        """
        L{SecureNamespaceAPI.get} should raise L{PermissonDeniedError} if the
        user doesn't have LIST permissions when trying to get the child
        namespaces.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user', Operation.LIST_NAMESPACE, Policy.CLOSED, [])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError,
                                  self.namespaces.get, [(u'user')],
                                  withNamespaces=True)
        self.assertEqual([(u'user', Operation.LIST_NAMESPACE)],
                         sorted(error.pathsAndOperations))

    def testGetChildTagsIsAllowed(self):
        """
        L{SecureNamespaceAPI.get} should allow getting a list of child tags if
        the user has permissions.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user', Operation.LIST_NAMESPACE, Policy.CLOSED, [u'user'])
                  ]
        self.permissions.set(values)
        result = self.namespaces.get([u'user'], withTags=True)
        self.assertEqual(1, len(result))

    def testGetChildTagsIsDenied(self):
        """
        L{SecureNamespaceAPI.get} should raise L{PermissonDeniedError} if the
        user doesn't have LIST permissions when trying to get the child
        tags.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user', Operation.LIST_NAMESPACE, Policy.OPEN, [u'user'])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError,
                                  self.namespaces.get, [(u'user')],
                                  withTags=True)
        self.assertEqual([(u'user', Operation.LIST_NAMESPACE)],
                         sorted(error.pathsAndOperations))

    def testSetIsAllowed(self):
        """
        L{SecureNamespaceAPI.get} should allow updating the description of a
        namespace if the user has permissions.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user/test', Operation.UPDATE_NAMESPACE, Policy.OPEN, [])]
        self.permissions.set(values)
        self.namespaces.set({u'user/test': u'description'})

    def testSetIsDenied(self):
        """
        L{SecureNamespaceAPI.get} should raise L{PermissonDeniedError} if the
        user doesn't have UPDATE permissions when trying to update a
        namespace's description.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user/test', Operation.UPDATE_NAMESPACE, Policy.CLOSED, [])
                  ]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError, self.namespaces.set,
                                  {u'user/test': u'description'})
        self.assertEqual([(u'user/test', Operation.UPDATE_NAMESPACE)],
                         sorted(error.pathsAndOperations))
Exemplo n.º 9
0
class FacadeObjectMixinTest(FluidinfoTestCase):

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

    def setUp(self):
        super(FacadeObjectMixinTest, self).setUp()
        self.system = createSystemData()
        self.transact = Transact(self.threadPool)
        factory = FluidinfoSessionFactory('API-9000')
        self.facade = Facade(self.transact, factory)
        UserAPI().create([(u'username', u'password', u'User',
                           u'*****@*****.**')])
        self.user = getUser(u'username')
        self.permissions = CachingPermissionAPI(self.user)

    @inlineCallbacks
    def testCreateObjectPermissionDenied(self):
        """
        L{FacadeObjectMixin.createObject} raises a
        L{TUnauthorized} exception if the user is the anonymous user.
        """
        self.store.commit()

        with login(u'anon', uuid4(), self.transact) as session:
            deferred = self.facade.createObject(session)
            yield self.assertFailure(deferred, TUnauthorized)

    @inlineCallbacks
    def testCreateObjectWithoutAboutValue(self):
        """
        L{FacadeObjectAPI.createObject} always returns a valid C{UUID} in a
        C{str} for a new object ID if an about value is not given.
        """
        self.store.commit()

        with login(u'username', uuid4(), self.transact) as session:
            objectID = yield self.facade.createObject(session)
            self.assertEqual(objectID, str(UUID(objectID)))

    @inlineCallbacks
    def testCreateObjectWithAboutValue(self):
        """
        L{FacadeObjectAPI.createObject} always returns a valid C{UUID} in a
        C{str} for a new object ID if an about value is given and it doesn't
        already exist.
        """
        self.store.commit()

        with login(self.user.username, uuid4(), self.transact) as session:
            objectID = yield self.facade.createObject(session, about='foo')
            objectID = UUID(objectID)

        self.store.rollback()
        value = getAboutTagValues([objectID], [u'foo']).one()
        self.assertEqual(u'foo', value.value)

        tag = self.system.tags[u'fluiddb/about']
        value = getTagValues(values=[(objectID, tag.id)]).one()
        self.assertIdentical(self.system.users[u'fluiddb'], value.creator)

    @inlineCallbacks
    def testCreateObjectWithDuplicateAboutValue(self):
        """
        L{FacadeObjectAPI.createObject} returns a valid C{UUID} in a C{str} for
        an existing object ID if an about value is given and already exists in
        the database.
        """
        objectID = uuid4()
        createAboutTagValue(objectID, u'bar')
        values = {objectID: {u'fluiddb/about': u'bar'}}
        SecureTagValueAPI(self.system.superuser).set(values)
        self.store.commit()

        with login(self.user.username, uuid4(), self.transact) as session:
            resultObjectID = yield self.facade.createObject(session,
                                                            about='bar')
            self.assertEqual(str(objectID), resultObjectID)

    @inlineCallbacks
    def testGetObject(self):
        """
        L{FacadeObjectAPI.getObject} returns a L{TObjectInfo} with the
        L{Tag.path}s for which the L{User} has L{Operation.READ_TAG_VALUE}.
        """
        objectID = uuid4()
        SecureTagAPI(self.user).create([(u'username/foo', u'A description')])
        values = {objectID: {u'username/foo': u'bar'}}
        SecureTagValueAPI(self.user).set(values)
        self.store.commit()

        with login(self.user.username, uuid4(), self.transact) as session:
            objectInfo = yield self.facade.getObject(session, str(objectID))
            self.assertEqual([u'username/foo'], objectInfo.tagPaths)
            self.assertEqual(None, objectInfo.about)

    @inlineCallbacks
    def testGetObjectWithAboutValue(self):
        """
        L{FacadeObjectAPI.getObject} returns a L{TObjectInfo} with the
        L{Tag.path}s for which the L{User} has L{Operation.READ_TAG_VALUE},
        and the L{AboutTagValue.value} if it has one and C{showAbout} is
        C{True}.
        """
        objectID = uuid4()
        SecureTagAPI(self.user).create([(u'username/foo', u'A description')])
        values = {objectID: {u'username/foo': u'bar'}}
        SecureTagValueAPI(self.user).set(values)
        aboutTag = self.system.tags[u'fluiddb/about']
        createAboutTagValue(objectID, u'bar')
        createTagValue(self.user.id, aboutTag.id, objectID, u'about value')
        self.store.commit()

        with login(self.user.username, uuid4(), self.transact) as session:
            objectInfo = yield self.facade.getObject(session,
                                                     str(objectID),
                                                     showAbout=True)
            self.assertEqual([u'fluiddb/about', u'username/foo'],
                             sorted(objectInfo.tagPaths))
            self.assertEqual('about value', objectInfo.about)

    @inlineCallbacks
    def testGetObjectWithAboutValueDoesNotExist(self):
        """
        L{FacadeObjectAPI.getObject} returns a L{TObjectInfo} with the
        L{Tag.path}s for which the L{User} has L{Operation.READ_TAG_VALUE},
        and the L{AboutTagValue.value} if it has one and C{showAbout} is
        C{True}.
        """
        objectID = uuid4()
        tag = createTag(self.user, self.user.namespace, u'foo')
        createTagPermission(tag)
        createTagValue(self.user.id, tag.id, objectID, u'bar')
        session = AuthenticatedSession(self.user.username, uuid4())
        self.store.commit()
        with login(self.user.username, uuid4(), self.transact) as session:
            objectInfo = yield self.facade.getObject(session,
                                                     str(objectID),
                                                     showAbout=True)
            self.assertEqual([u'username/foo'], objectInfo.tagPaths)
            self.assertIdentical(None, objectInfo.about)

    @inlineCallbacks
    def testGetObjectDeniedPaths(self):
        """
        L{FacadeObjectAPI.getObject} returns a L{TObjectInfo} with the
        L{Tag.path}s for which the L{User} has L{Operation.READ_TAG_VALUE}.
        """
        SecureTagAPI(self.user).create([(u'username/tag1', u'description'),
                                        (u'username/tag2', u'description')])
        objectID = uuid4()
        values = {
            objectID: {
                u'username/tag1': 16
            },
            objectID: {
                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, [])
        ])
        self.store.commit()

        with login(self.user.username, uuid4(), self.transact) as session:
            objectInfo = yield self.facade.getObject(session, str(objectID))
            self.assertEqual([u'username/tag2'], objectInfo.tagPaths)
            self.assertEqual(None, objectInfo.about)

    @inlineCallbacks
    def testGetObjectAllPathsAreDenied(self):
        """
        L{FacadeObjectAPI.getObject} returns a L{TObjectInfo} with the
        L{Tag.path}s for which the L{User} has L{Operation.READ_TAG_VALUE}, if
        all of them are denied, L{FacadeObjectAPI.getObject} must return an
        empty L{TObjectInfo}.
        """
        SecureTagAPI(self.user).create([(u'username/tag1', u'description'),
                                        (u'username/tag2', u'description')])
        objectID = uuid4()
        values = {
            objectID: {
                u'username/tag1': 16
            },
            objectID: {
                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, [])
        ])
        self.store.commit()

        with login(self.user.username, uuid4(), self.transact) as session:
            objectInfo = yield self.facade.getObject(session, str(objectID))
            self.assertEqual([], objectInfo.tagPaths)
            self.assertEqual(None, objectInfo.about)
Exemplo n.º 10
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)
Exemplo n.º 11
0
class FacadePermissionTest(FluidinfoTestCase):

    resources = [('cache', CacheResource()),
                 ('config', ConfigResource()),
                 ('log', LoggingResource()),
                 ('store', DatabaseResource())]

    def setUp(self):
        super(FacadePermissionTest, self).setUp()
        self.transact = Transact(FakeThreadPool())
        factory = FluidinfoSessionFactory('API-9000')
        self.facade = Facade(self.transact, factory)
        createSystemData()
        UserAPI().create([(u'username', u'password', u'User',
                           u'*****@*****.**')])
        user = getUser(u'username')
        self.permissions = CachingPermissionAPI(user)
        SecureTagAPI(user).create([(u'username/tag', u'description')])

    @inlineCallbacks
    def testGetNamespacePermissions(self):
        """
        L{FacadePermissionMixin.getPermission} returns a
        L{TPolicyAndExceptions} object with the policy and exceptions list for
        a given L{Namespace} path.
        """
        self.permissions.set([(u'username', Operation.CREATE_NAMESPACE,
                               Policy.CLOSED, [])])
        with login(u'username', uuid4(), self.transact) as session:
            policyAndExceptions = yield self.facade.getPermission(
                session, u'namespaces', u'create', u'username')
        self.assertEqual(u'closed', policyAndExceptions.policy)
        self.assertEqual([], policyAndExceptions.exceptions)

    @inlineCallbacks
    def testGetTagPermissions(self):
        """
        L{FacadePermissionMixin.getPermission} returns a
        L{TPolicyAndExceptions} object with the policy and exceptions list for
        a given L{Tag} path.
        """
        self.permissions.set([(u'username/tag', Operation.UPDATE_TAG,
                               Policy.CLOSED, [u'username'])])
        with login(u'username', uuid4(), self.transact) as session:
            policyAndExceptions = yield self.facade.getPermission(
                session, u'tags', u'update', u'username/tag')
        self.assertEqual(u'closed', policyAndExceptions.policy)
        self.assertEqual([u'username'], policyAndExceptions.exceptions)

    @inlineCallbacks
    def testGetTagValuePermissions(self):
        """
        L{FacadePermissionMixin.getPermission} returns a
        L{TPolicyAndExceptions} object with the policy and exceptions list for
        a given L{TagValue} path.
        """
        self.permissions.set([(u'username/tag', Operation.WRITE_TAG_VALUE,
                               Policy.CLOSED, [])])
        with login(u'username', uuid4(), self.transact) as session:
            policyAndExceptions = yield self.facade.getPermission(
                session, u'tag-values', u'write', u'username/tag')
        self.assertEqual(u'closed', policyAndExceptions.policy)
        self.assertEqual([], policyAndExceptions.exceptions)

    @inlineCallbacks
    def testGetWithInvalidAction(self):
        """
        L{FacadePermissionMixin.getPermission} raises a L{TBadRequest} error if
        the given C{action} is invalid.
        """
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.getPermission(session, u'namespaces',
                                                 u'invalid', u'username')
            yield self.assertFailure(deferred, TBadRequest)

    @inlineCallbacks
    def testGetWithInvalidCategory(self):
        """
        L{FacadePermissionMixin.getPermission} raises a L{TBadRequest} error if
        the given C{category} is invalid.
        """
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.getPermission(session, u'invalid',
                                                 u'create', u'username')
            yield self.assertFailure(deferred, TBadRequest)

    @inlineCallbacks
    def testGetWithUnknownNamespace(self):
        """
        L{FacadePermissionMixin.getPermission} raises a
        L{TNonexistentNamespace} error if the given L{Namespace} path does not
        exist.
        """
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.getPermission(session, u'namespaces',
                                                 u'create', u'unknown')
            yield self.assertFailure(deferred, TNonexistentNamespace)

    @inlineCallbacks
    def testGetWithUnknownTag(self):
        """
        L{FacadePermissionMixin.getPermission} raises a L{TNonexistentTag}
        error if the given L{Tag} path does not exist.
        """
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.getPermission(
                session, u'tags', u'update', u'username/unknown')
            yield self.assertFailure(deferred, TNonexistentTag)

    @inlineCallbacks
    def testGetNamespacePermissionsIsDenied(self):
        """
        L{FacadePermissionMixin.getPermission} raises a
        L{TPathPermissionDenied} error if the user doesn't have
        C{Operation.CONTROL_NAMESPACE} permissions on the given L{Namespace}.
        """
        self.permissions.set([(u'username', Operation.CONTROL_NAMESPACE,
                               Policy.CLOSED, [])])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.getPermission(session, u'namespaces',
                                                 u'update', u'username')
            yield self.assertFailure(deferred, TPathPermissionDenied)

    @inlineCallbacks
    def testGetTagPermissionsIsDenied(self):
        """
        L{FacadePermissionMixin.getPermission} raises a
        L{TPathPermissionDenied} error if the user doesn't have
        C{Operation.CONTROL_TAG} permissions on the given L{Tag}.
        """
        self.permissions.set([(u'username/tag', Operation.CONTROL_TAG,
                               Policy.CLOSED, [])])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.getPermission(session, u'tags',
                                                 u'delete', u'username/tag')
            yield self.assertFailure(deferred, TPathPermissionDenied)

    @inlineCallbacks
    def testGetTagValuePermissionsIsDenied(self):
        """
        L{FacadePermissionMixin.getPermission} raises a
        L{TPathPermissionDenied} error if the user doesn't have
        C{Operation.CONTROL_TAG_VALUE} permissions on the given L{Tag}.
        """
        self.permissions.set([(u'username/tag', Operation.CONTROL_TAG_VALUE,
                               Policy.CLOSED, [])])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.getPermission(session, u'tag-values',
                                                 u'read', u'username/tag')
            yield self.assertFailure(deferred, TPathPermissionDenied)

    @inlineCallbacks
    def testSetNamespacePermissions(self):
        """
        L{FacadePermissionMixin.updatePermission} updates the permissions for a
        given L{Namespace} path.
        """
        policyAndExceptions = TPolicyAndExceptions(u'closed', [])
        with login(u'username', uuid4(), self.transact) as session:
            yield self.facade.updatePermission(session, u'namespaces',
                                               u'create', u'username',
                                               policyAndExceptions)
        pathAndAction = (u'username', Operation.CREATE_NAMESPACE)
        result = self.permissions.get([pathAndAction])
        self.assertEqual((Policy.CLOSED, []), result[pathAndAction])

    @inlineCallbacks
    def testSetTagPermissions(self):
        """
        L{FacadePermissionMixin.updatePermission} updates the permissions for a
        given L{Tag} path.
        """
        policyAndExceptions = TPolicyAndExceptions(u'open', [u'username'])
        with login(u'username', uuid4(), self.transact) as session:
            yield self.facade.updatePermission(session, u'tags', u'update',
                                               u'username/tag',
                                               policyAndExceptions)
        pathAndAction = (u'username/tag', Operation.UPDATE_TAG)
        result = self.permissions.get([pathAndAction])
        self.assertEqual((Policy.OPEN, [u'username']), result[pathAndAction])

    @inlineCallbacks
    def testSetTagValuePermissions(self):
        """
        L{FacadePermissionMixin.updatePermission} updates the permissions for a
        given L{TagValue} path.
        """
        policyAndExceptions = TPolicyAndExceptions(u'closed', [u'username'])
        with login(u'username', uuid4(), self.transact) as session:
            yield self.facade.updatePermission(session, u'tag-values',
                                               u'write', u'username/tag',
                                               policyAndExceptions)
        pathAndAction = (u'username/tag', Operation.WRITE_TAG_VALUE)
        result = self.permissions.get([pathAndAction])
        self.assertEqual((Policy.CLOSED, [u'username']), result[pathAndAction])

    @inlineCallbacks
    def testSetWithInvalidAction(self):
        """
        L{FacadePermissionMixin.updatePermission} raises a L{TBadRequest} error
        if the given C{action} is invalid.
        """
        policyAndExceptions = TPolicyAndExceptions(u'closed', [])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updatePermission(session, u'namespaces',
                                                    u'invalid', u'username',
                                                    policyAndExceptions)
            yield self.assertFailure(deferred, TBadRequest)

    @inlineCallbacks
    def testSetWithInvalidCategory(self):
        """
        L{FacadePermissionMixin.updatePermission} raises a L{TBadRequest} error
        if the given C{category} is invalid.
        """
        policyAndExceptions = TPolicyAndExceptions(u'closed', [])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updatePermission(session, u'invalid',
                                                    u'update', u'username',
                                                    policyAndExceptions)
            yield self.assertFailure(deferred, TBadRequest)

    @inlineCallbacks
    def testSetWithInvalidPolicy(self):
        """
        L{FacadePermissionMixin.updatePermission} raises a L{TInvalidPolicy}
        error if the given C{policy} is invalid.
        """
        policyAndExceptions = TPolicyAndExceptions(u'invalid', [])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updatePermission(session, u'namespaces',
                                                    u'create', u'username',
                                                    policyAndExceptions)
            yield self.assertFailure(deferred, TInvalidPolicy)

    @inlineCallbacks
    def testSetWithUnknownNamespace(self):
        """
        L{FacadePermissionMixin.updatePermission} raises a
        L{TNonexistentNamespace} error if the given L{Namespace} path does not
        exist.
        """
        policyAndExceptions = TPolicyAndExceptions(u'closed', [])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updatePermission(session, u'namespaces',
                                                    u'create', u'unknown',
                                                    policyAndExceptions)
            yield self.assertFailure(deferred, TNonexistentNamespace)

    @inlineCallbacks
    def testSetWithUnknownTag(self):
        """
        L{FacadePermissionMixin.updatePermission} raises a L{TNonexistentTag}
        error if the given L{Tag} path does not exist.
        """
        policyAndExceptions = TPolicyAndExceptions(u'closed', [])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updatePermission(
                session, u'tags', u'update', u'username/unknown',
                policyAndExceptions)
            yield self.assertFailure(deferred, TNonexistentTag)

    @inlineCallbacks
    def testSetWithUnknownUser(self):
        """
        L{FacadePermissionMixin.updatePermission} raises a L{TNoSuchUser}
        error if a L{User} in the exceptions list doesn't exist.
        """
        policyAndExceptions = TPolicyAndExceptions(u'closed', [u'unknown'])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updatePermission(
                session, u'tags', u'update', u'username/tag',
                policyAndExceptions)
            error = yield self.assertFailure(deferred, TNoSuchUser)
            self.assertEqual('unknown', error.name)

    @inlineCallbacks
    def testSetWithSuperuser(self):
        """
        L{FacadePermissionMixin.updatePermission} raises a L{TInvalidUsername}
        error if a superuser is specified in the exceptions list.
        """
        policyAndExceptions = TPolicyAndExceptions(u'closed', [u'fluiddb'])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updatePermission(
                session, u'tags', u'update', u'username/tag',
                policyAndExceptions)
            yield self.assertFailure(deferred, TInvalidUsername)

    @inlineCallbacks
    def testSetWithAnonymous(self):
        """
        L{FacadePermissionMixin.updatePermission} raises a L{TInvalidUsername}
        error if the anonymous user is specified in the exceptions list for
        non-allowed operations.
        """
        policyAndExceptions = TPolicyAndExceptions(u'closed', [u'anon'])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updatePermission(
                session, u'tags', u'update', u'username/tag',
                policyAndExceptions)
            yield self.assertFailure(deferred, TInvalidUsername)

    @inlineCallbacks
    def testSetWithUnknownUserUTF8EncodesUsername(self):
        """
        L{FacadePermissionMixin.updatePermission} raises a L{TNoSuchUser}
        error if a L{User} in the exceptions list doesn't exist.  The username
        passed to L{TNoSuchUser} is UTF-8 encoded.
        """
        policyAndExceptions = TPolicyAndExceptions(u'closed',
                                                   [u'\N{HIRAGANA LETTER A}'])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updatePermission(
                session, u'tags', u'update', u'username/tag',
                policyAndExceptions)
            error = yield self.assertFailure(deferred, TNoSuchUser)
            self.assertEqual(u'\N{HIRAGANA LETTER A}'.encode('utf-8'),
                             error.name)

    @inlineCallbacks
    def testSetNamespacePermissionsIsDenied(self):
        """
        L{FacadePermissionMixin.updatePermission} raises a
        L{TPathPermissionDenied} error if the user doesn't have
        C{Operation.CONTROL_NAMESPACE} permissions on the given L{Namespace}.
        """
        self.permissions.set([(u'username', Operation.CONTROL_NAMESPACE,
                               Policy.CLOSED, [])])
        policyAndExceptions = TPolicyAndExceptions(u'open', [])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updatePermission(session, u'namespaces',
                                                    u'control', u'username',
                                                    policyAndExceptions)
            yield self.assertFailure(deferred, TPathPermissionDenied)

    @inlineCallbacks
    def testSetTagPermissionsIsDenied(self):
        """
        L{FacadePermissionMixin.updatePermission} raises a
        L{TPathPermissionDenied} error if the user doesn't have
        C{Operation.CONTROL_TAG} permissions on the given L{Tag}.
        """
        self.permissions.set([(u'username/tag', Operation.CONTROL_TAG,
                               Policy.CLOSED, [])])
        policyAndExceptions = TPolicyAndExceptions(u'open', [])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updatePermission(
                session, u'tags', u'control', u'username/tag',
                policyAndExceptions)
            yield self.assertFailure(deferred, TPathPermissionDenied)

    @inlineCallbacks
    def testSetTagValuePermissionsIsDenied(self):
        """
        L{FacadePermissionMixin.updatePermission} raises a
        L{TPathPermissionDenied} error if the user doesn't have
        C{Operation.CONTROL_TAG_VALUE} permissions on the given L{Tag}.
        """
        self.permissions.set([(u'username/tag', Operation.CONTROL_TAG_VALUE,
                               Policy.CLOSED, [])])
        policyAndExceptions = TPolicyAndExceptions(u'open', [])
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updatePermission(
                session, u'tag-values', u'control', u'username/tag',
                policyAndExceptions)
            yield self.assertFailure(deferred, TPathPermissionDenied)
Exemplo n.º 12
0
class SecureRecentActivityAPIWithAnonymousRoleTest(FluidinfoTestCase):

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

    def setUp(self):
        super(SecureRecentActivityAPIWithAnonymousRoleTest, self).setUp()
        system = createSystemData()
        self.anon = system.users[u'anon']
        UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')])
        self.user = getUser(u'user')
        self.recentActivity = SecureRecentActivityAPI(self.anon)
        self.permissions = CachingPermissionAPI(self.user)

    def testGetForObjectsReturnsOnlyAllowedTags(self):
        """
        L{SecureRecentActivityAPI.getForObjects} will return all the tags for
        which the user has C{Operation.READ_TAG_VALUE} permissions, but not
        those for which the user doesn't have.
        """
        tagValues = TagValueAPI(self.user)
        objectID1 = ObjectAPI(self.user).create(u'object1')
        objectID2 = uuid4()

        # Use commit() frequently to have different timestamps on each value.
        self.store.commit()
        tagValues.set({objectID1: {u'user/tag1': u'A'}})
        self.store.commit()
        tagValues.set({objectID1: {u'user/tag2': u'B'}})
        self.store.commit()
        tagValues.set({objectID2: {u'user/tag1': u'C'}})
        self.store.commit()
        tagValues.set({objectID2: {u'user/tag2': u'D'}})
        self.store.commit()
        tagValues.set({uuid4(): {u'user/tag1': u'E'}})
        self.store.commit()
        tagValues.set({uuid4(): {u'user/tag2': u'F'}})
        self.store.commit()

        self.permissions.set([(u'user/tag2', Operation.READ_TAG_VALUE,
                               Policy.OPEN, [u'anon'])])

        expected = [(u'user/tag1', objectID2, None, u'C', u'user'),
                    (u'user/tag1', objectID1, u'object1', u'A', u'user'),
                    (u'fluiddb/about', objectID1, u'object1', u'object1',
                     u'fluiddb')]

        result = self.recentActivity.getForObjects([objectID1, objectID2])

        # Remove the creation times from the result, with the order is enough.
        result = [(path, objectID, about, value, username)
                  for path, objectID, about, value, username, time in result]
        self.assertEqual(expected, result)

    def testGetForUsersReturnsOnlyAllowedTags(self):
        """
        L{SecureRecentActivityAPI.getForUsers} will return all the tags for
        which the user has C{Operation.READ_TAG_VALUE} permissions, but not
        those for which the user doesn't have.
        """
        tagValues = TagValueAPI(self.user)
        objectID1 = ObjectAPI(self.user).create(u'object1')
        objectID2 = uuid4()

        # Use commit() frequently to have different timestamps on each value.
        self.store.commit()
        tagValues.set({objectID1: {u'user/tag1': u'A'}})
        self.store.commit()
        tagValues.set({objectID1: {u'user/tag2': u'B'}})
        self.store.commit()

        UserAPI().create([(u'user2', u'secret', u'User', u'*****@*****.**')])
        tagValues = TagValueAPI(getUser(u'user2'))

        tagValues.set({objectID1: {u'user2/tag1': u'C'}})
        self.store.commit()
        tagValues.set({objectID2: {u'user2/tag2': u'D'}})
        self.store.commit()

        UserAPI().create([(u'user3', u'secret', u'User', u'*****@*****.**')])
        tagValues = TagValueAPI(getUser(u'user3'))

        tagValues.set({objectID1: {u'user3/tag1': u'C'}})
        self.store.commit()
        tagValues.set({objectID2: {u'user3/tag2': u'D'}})
        self.store.commit()

        self.permissions.set([
            (u'user/tag2', Operation.READ_TAG_VALUE, Policy.OPEN, [u'anon']),
            (u'user2/tag2', Operation.READ_TAG_VALUE, Policy.CLOSED, [])
        ])

        expected = [(u'user2/tag1', objectID1, u'object1', u'C', u'user2'),
                    (u'user/tag1', objectID1, u'object1', u'A', u'user')]

        result = self.recentActivity.getForUsers([u'user', u'user2'])
        # Remove the creation times from the result, with the order is enough.
        result = [(path, objectID, about, value, username)
                  for path, objectID, about, value, username, time in result]
        self.assertEqual(expected, result)
Exemplo n.º 13
0
class SecureNamespaceAPIWithNormalUserTest(FluidinfoTestCase):

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

    def setUp(self):
        super(SecureNamespaceAPIWithNormalUserTest, self).setUp()
        createSystemData()

        UserAPI().create([(u'user', u'password', u'User',
                           u'*****@*****.**')])
        self.user = getUser(u'user')
        self.permissions = CachingPermissionAPI(self.user)
        self.namespaces = SecureNamespaceAPI(self.user)

    def testCreateIsAllowed(self):
        """
        L{SecureNamespaceAPI.create} should allow the creation of namespaces
        whose parent has open CREATE permissions.
        """
        values = [(u'user', Operation.CREATE_NAMESPACE, Policy.OPEN, [])]
        self.permissions.set(values)
        result = self.namespaces.create([(u'user/test', u'description')])
        self.assertEqual(1, len(result))

    def testCreateIsDenied(self):
        """
        L{SecureNamespaceAPI.create} should raise L{PermissonDeniedError} if
        the user doesn't have CREATE permissions on the parent namespace.
        """
        values = [(u'user', Operation.CREATE_NAMESPACE, Policy.CLOSED, [])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError,
                                  self.namespaces.create,
                                  [(u'user/test', u'description')])
        self.assertEqual([(u'user', Operation.CREATE_NAMESPACE)],
                         sorted(error.pathsAndOperations))

    def testDeleteIsAllowed(self):
        """
        {SecureNamespaceAPI.delete} should allow the deletion of a namespace
        if the user has DELETE permissions.
        """
        result1 = self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user/test', Operation.DELETE_NAMESPACE, Policy.OPEN, [])]
        self.permissions.set(values)
        result2 = self.namespaces.delete([u'user/test'])
        self.assertEqual(result1, result2)

    def testDeleteIsDenied(self):
        """
        L{SecureNamespaceAPI.delete} should raise L{PermissonDeniedError} if
        the user doesn't have DELETE permissions.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user/test', Operation.DELETE_NAMESPACE,
                   Policy.OPEN, [u'user'])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError,
                                  self.namespaces.delete, [(u'user/test')])
        self.assertEqual([(u'user/test', Operation.DELETE_NAMESPACE)],
                         sorted(error.pathsAndOperations))

    def testGetChildNamespacesIsAllowed(self):
        """
        L{SecureNamespaceAPI.get} should allow getting a list of child
        namespaces if the user has permissions.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user', Operation.LIST_NAMESPACE, Policy.OPEN, [])]
        self.permissions.set(values)
        result = self.namespaces.get([u'user'], withNamespaces=True)
        self.assertEqual(1, len(result))

    def testGetChildNamespacesIsDenied(self):
        """
        L{SecureNamespaceAPI.get} should raise L{PermissonDeniedError} if the
        user doesn't have LIST permissions when trying to get the child
        namespaces.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user', Operation.LIST_NAMESPACE, Policy.CLOSED, [])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError,
                                  self.namespaces.get,
                                  [(u'user')], withNamespaces=True)
        self.assertEqual([(u'user', Operation.LIST_NAMESPACE)],
                         sorted(error.pathsAndOperations))

    def testGetChildTagsIsAllowed(self):
        """
        L{SecureNamespaceAPI.get} should allow getting a list of child tags if
        the user has permissions.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user', Operation.LIST_NAMESPACE,
                   Policy.CLOSED, [u'user'])]
        self.permissions.set(values)
        result = self.namespaces.get([u'user'], withTags=True)
        self.assertEqual(1, len(result))

    def testGetChildTagsIsDenied(self):
        """
        L{SecureNamespaceAPI.get} should raise L{PermissonDeniedError} if the
        user doesn't have LIST permissions when trying to get the child
        tags.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user', Operation.LIST_NAMESPACE, Policy.OPEN, [u'user'])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError,
                                  self.namespaces.get,
                                  [(u'user')], withTags=True)
        self.assertEqual([(u'user', Operation.LIST_NAMESPACE)],
                         sorted(error.pathsAndOperations))

    def testSetIsAllowed(self):
        """
        L{SecureNamespaceAPI.get} should allow updating the description of a
        namespace if the user has permissions.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user/test', Operation.UPDATE_NAMESPACE, Policy.OPEN, [])]
        self.permissions.set(values)
        self.namespaces.set({u'user/test': u'description'})

    def testSetIsDenied(self):
        """
        L{SecureNamespaceAPI.get} should raise L{PermissonDeniedError} if the
        user doesn't have UPDATE permissions when trying to update a
        namespace's description.
        """
        self.namespaces.create([(u'user/test', u'description')])
        values = [(u'user/test', Operation.UPDATE_NAMESPACE,
                   Policy.CLOSED, [])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError,
                                  self.namespaces.set,
                                  {u'user/test': u'description'})
        self.assertEqual([(u'user/test', Operation.UPDATE_NAMESPACE)],
                         sorted(error.pathsAndOperations))
Exemplo n.º 14
0
class SecureTagValueAPIWithUserRoleTest(FluidinfoTestCase):

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

    def setUp(self):
        super(SecureTagValueAPIWithUserRoleTest, self).setUp()
        createSystemData()
        UserAPI().create([(u'username', u'password', u'User',
                           u'*****@*****.**')])
        self.user = getUser(u'username')
        self.permissions = CachingPermissionAPI(self.user)
        TagAPI(self.user).create([(u'username/tag', u'description')])
        self.tagValues = SecureTagValueAPI(self.user)

    def testGetIsAllowed(self):
        """
        L{SecureTagAPI.get} is allowed if the user has
        C{Operation.READ_TAG_VALUE} permissions.
        """
        objectID = uuid4()
        values = {objectID: {u'username/tag': 16}}
        self.tagValues.set(values)
        self.permissions.set([(u'username/tag', Operation.READ_TAG_VALUE,
                               Policy.OPEN, [])])
        result = self.tagValues.get(objectIDs=[objectID],
                                    paths=[u'username/tag'])
        self.assertEqual(16, result[objectID][u'username/tag'].value)

    def testGetIsDenied(self):
        """
        L{SecureTagAPI.get} raises L{PermissionDeniedError} if the user doesn't
        have C{Operation.READ_TAG_VALUE} permissions.
        """
        objectID = uuid4()
        values = {objectID: {u'username/tag': 16}}
        self.tagValues.set(values)
        self.permissions.set([(u'username/tag', Operation.READ_TAG_VALUE,
                               Policy.CLOSED, [])])
        error = self.assertRaises(PermissionDeniedError,
                                  self.tagValues.get, objectIDs=[objectID],
                                  paths=[u'username/tag'])
        self.assertEqual([(u'username/tag', Operation.READ_TAG_VALUE)],
                         error.pathsAndOperations)

    def testSetIsAllowed(self):
        """
        L{SecureTagAPI.set} is allowed if the user has
        C{Operation.WRITE_TAG_VALUE} permissions.
        """
        self.permissions.set([(u'username/tag', Operation.WRITE_TAG_VALUE,
                               Policy.OPEN, [])])
        objectID = uuid4()
        values = {objectID: {u'username/tag': 16}}
        self.tagValues.set(values)
        result = self.tagValues.get(objectIDs=[objectID],
                                    paths=[u'username/tag'])
        self.assertEqual(16, result[objectID][u'username/tag'].value)

    def testSetIsDenied(self):
        """
        L{SecureTagAPI.set} raises L{PermissionDeniedError} if the user doesn't
        have C{Operation.WRITE_TAG_VALUE} permissions.
        """
        self.permissions.set([(u'username/tag', Operation.WRITE_TAG_VALUE,
                               Policy.CLOSED, [])])
        values = {uuid4(): {u'username/tag': 16}}
        error = self.assertRaises(PermissionDeniedError,
                                  self.tagValues.set, values)
        self.assertEqual([(u'username/tag', Operation.WRITE_TAG_VALUE)],
                         error.pathsAndOperations)

    def testDeleteIsAllowed(self):
        """
        L{SecureTagAPI.delete} is allowed if the user has
        C{Operation.DELETE_TAG_VALUE} permissions.
        """
        self.permissions.set([(u'username/tag', Operation.DELETE_TAG_VALUE,
                               Policy.OPEN, [])])
        objectID = uuid4()
        values = {objectID: {u'username/tag': 16}}
        self.tagValues.set(values)
        self.tagValues.delete([(objectID, u'username/tag')])
        result = self.tagValues.get(objectIDs=[objectID],
                                    paths=[u'username/tag'])
        self.assertEqual({}, result)

    def testDeleteIsDenied(self):
        """
        L{SecureTagAPI.delete} raises L{PermissionDeniedError} if the user
        doesn't have C{Operation.DELETE_TAG_VALUE} permissions.
        """
        objectID = uuid4()
        values = {objectID: {u'username/tag': 16}}
        self.tagValues.set(values)
        self.permissions.set([(u'username/tag', Operation.DELETE_TAG_VALUE,
                               Policy.CLOSED, [])])
        error = self.assertRaises(PermissionDeniedError,
                                  self.tagValues.delete,
                                  [(objectID, u'username/tag')])
        self.assertEqual([(u'username/tag', Operation.DELETE_TAG_VALUE)],
                         error.pathsAndOperations)
Exemplo n.º 15
0
class SecureTagAPIWithNormalUserTest(FluidinfoTestCase):

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

    def setUp(self):
        super(SecureTagAPIWithNormalUserTest, self).setUp()
        createSystemData()
        UserAPI().create([(u'user', u'password', u'User',
                           u'*****@*****.**')])
        self.user = getUser(u'user')
        self.permissions = CachingPermissionAPI(self.user)
        self.tags = SecureTagAPI(self.user)

    def testCreateIsAllowed(self):
        """
        L{SecureTagAPI.create} should allow the creation of tags whose parent
        namespace has open C{Operation.CREATE_NAMESPACE} permissions.
        """
        result = self.tags.create([(u'user/test', u'description')])
        self.assertEqual(1, len(result))

    def testCreateIsDenied(self):
        """
        L{SecureTagAPI.create} should raise L{PermissonDeniedError} if
        the user doesn't have C{Operation.CREATE_NAMESPACE} permissions on the
        parent namespace.
        """
        values = [(u'user', Operation.CREATE_NAMESPACE, Policy.CLOSED, [])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError,
                                  self.tags.create,
                                  [(u'user/test', u'description')])
        self.assertEqual([(u'user', Operation.CREATE_NAMESPACE)],
                         sorted(error.pathsAndOperations))

    def testDeleteIsAllowed(self):
        """
        L{SecureTagAPI.delete} should allow the deletion of a tag if the user
        has C{Operation.DELETE_TAG} permissions.
        """
        result1 = self.tags.create([(u'user/test', u'description')])
        result2 = self.tags.delete([u'user/test'])
        self.assertEqual(result1, result2)

    def testDeleteIsDenied(self):
        """
        L{SecureTagAPI.delete} should raise L{PermissonDeniedError} if the
        user doesn't have C{Operation.DELETE_TAG} permissions.
        """
        self.tags.create([(u'user/test', u'description')])
        values = [(u'user/test', Operation.DELETE_TAG, Policy.OPEN, [u'user'])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError,
                                  self.tags.delete, [(u'user/test')])
        self.assertEqual([(u'user/test', Operation.DELETE_TAG)],
                         sorted(error.pathsAndOperations))

    def testSetIsAllowed(self):
        """
        L{SecureTagAPI.get} should allow updating the description of a tag if
        the user has permissions.
        """
        [(objectID, _)] = self.tags.create([(u'user/test', u'A description')])
        self.tags.set({u'user/test': u'A new description'})
        result = self.tags.get([u'user/test'], withDescriptions=True)
        expected = {u'user/test': {'id': objectID,
                                   'description': u'A new description'}}
        self.assertEqual(expected, result)

    def testSetIsDenied(self):
        """
        L{SecureTagAPI.get} should raise L{PermissonDeniedError} if the user
        doesn't have C{Operation.UPDATE_TAG} permissions when trying to update
        a tag's description.
        """
        self.tags.create([(u'user/test', u'description')])
        values = [(u'user/test', Operation.UPDATE_TAG, Policy.CLOSED, [])]
        self.permissions.set(values)
        error = self.assertRaises(PermissionDeniedError,
                                  self.tags.set,
                                  {u'user/test': u'description'})
        self.assertEqual([(u'user/test', Operation.UPDATE_TAG)],
                         sorted(error.pathsAndOperations))
Exemplo n.º 16
0
class SecureObjectAPIWithUserRoleTest(FluidinfoTestCase):

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

    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)

    def testGetTagsByObjectsPathIsAllowed(self):
        """
        L{SecureObjectAPI.getTagsByObjects} will return all the tags for
        which the 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, [])])
        result = self.objects.getTagsByObjects([objectID])
        expected = {objectID: [u'username/tag']}
        self.assertEqual(expected, result)

    def testGetTagsByObjectsReturnsOnlyAllowedTags(self):
        """
        L{SecureObjectAPI.getTagsByObjects} will return all the tags for
        which the user has C{Operation.READ_TAG_VALUE} permissions, but not
        those for which the user doesn't have.
        """
        TagAPI(self.user).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 testGetTagsByObjectsReturnsNoneAllowedTags(self):
        """
        L{SecureObjectAPI.getTagsByObjects} will return all the tags for
        which the user has C{Operation.READ_TAG_VALUE} permissions, but not
        those for which the user doesn't have.
        """
        TagAPI(self.user).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)
        self.assertEqual({objectID: [u'username/open']}, 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]))
Exemplo n.º 17
0
class FacadeTagMixinTest(FluidinfoTestCase):

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

    def setUp(self):
        super(FacadeTagMixinTest, self).setUp()
        createSystemData()
        self.transact = Transact(self.threadPool)
        factory = FluidinfoSessionFactory('API-9000')
        self.facade = Facade(self.transact, factory)
        UserAPI().create([(u'username', u'password', u'User',
                           u'*****@*****.**')])
        self.user = getUser(u'username')
        self.permissions = CachingPermissionAPI(self.user)

    @inlineCallbacks
    def testGetTagWithoutData(self):
        """
        L{FacadeTagMixin.getTag} raises a L{TNonexistentTag} exception if the
        requested L{Tag.path} doesn't exist.
        """
        self.store.commit()
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.getTag(session, u'username/unknown', False)
            yield self.assertFailure(deferred, TNonexistentTag)

    @inlineCallbacks
    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)

    @inlineCallbacks
    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)

    @inlineCallbacks
    def testCreateTag(self):
        """L{FacadeTagMixin.createTag} creates a new L{Tag}."""
        self.store.commit()
        with login(u'username', uuid4(), self.transact) as session:
            objectID = yield self.facade.createTag(
                session, u'username', u'tag', u'A tag.', 'ignored', 'ignored')
            self.assertNotIdentical(None, objectID)

        self.store.rollback()
        tag = getTags(paths=[u'username/tag']).one()
        self.assertIdentical(self.user, tag.creator)
        self.assertIdentical(self.user.namespace, tag.namespace)
        self.assertEqual(u'username/tag', tag.path)
        self.assertEqual(u'tag', tag.name)
        self.assertEqual(objectID, str(tag.objectID))

    @inlineCallbacks
    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)

    @inlineCallbacks
    def testCreateTagWithInvalidPath(self):
        """
        L{FacadeTagMixin.createTag} raises a L{TInvalidPath} exception if the
        path of the L{Tag} is not well formed.
        """
        self.store.commit()
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.createTag(session, u'username', u'bad name',
                                             u'A tag.', 'ignored', 'ignored')
            yield self.assertFailure(deferred, TInvalidPath)

    @inlineCallbacks
    def testCreateTagWithUnknownParent(self):
        """
        L{FacadeTagMixin.createTag} raises a L{TNonexistentTag} exception if a
        non-existent parent L{Tag} is specified.
        """
        self.store.commit()
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.createTag(
                session, u'unknown', u'name', u'A tag.', 'ignored', 'ignored')
            yield self.assertFailure(deferred, TNonexistentTag)

    @inlineCallbacks
    def testCreateIsDenied(self):
        """
        L{Facade.createTag} raises a L{TPathPermissionDenied} exception if the
        user doesn't have C{CREATE} permissions on the parent L{Namespace}.
        """
        self.permissions.set([(u'username', Operation.CREATE_NAMESPACE,
                               Policy.CLOSED, [])])
        self.store.commit()
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.createTag(
                session, u'username', u'test', u'A tag.', 'ignored', 'ignored')
            yield self.assertFailure(deferred, TPathPermissionDenied)

    @inlineCallbacks
    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'])

    @inlineCallbacks
    def testUpdateTagWithUnknownPath(self):
        """
        L{FacadeTagMixin.updateTag} raises a L{TNonexistentTag} exception if
        the requested L{Tag.path} doesn't exist.
        """
        self.store.commit()
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updateTag(session, u'username/unknown',
                                             u'A new description.')
            yield self.assertFailure(deferred, TNonexistentTag)

    @inlineCallbacks
    def testUpdateIsDenied(self):
        """
        L{Facade.updateTag} raises a L{TPathPermissionDenied} exception if the
        user doesn't have C{UPDATE} permissions on the specified L{Tag}.
        """
        TagAPI(self.user).create([(u'username/test', u'A tag.')])
        self.permissions.set([(u'username/test', Operation.UPDATE_TAG,
                               Policy.CLOSED, [])])
        self.store.commit()
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.updateTag(session, u'username/test',
                                             u'A new description.')
            yield self.assertFailure(deferred, TPathPermissionDenied)

    @inlineCallbacks
    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']))

    @inlineCallbacks
    def testDeleteTagWithUnknownPath(self):
        """
        L{FacadeTagMixin.deleteTag} raises a L{TNonexistentTag} exception if
        the requested L{Tag.path} doesn't exist.
        """
        self.store.commit()
        with login(u'username', uuid4(), self.transact) as session:
            deferred = self.facade.deleteTag(session, u'username/unknown')
            yield self.assertFailure(deferred, TNonexistentTag)

    @inlineCallbacks
    def testDeleteTagWithData(self):
        """
        L{FacadeTagMixin.deleteTag} removes L{TagValue}s associated with the
        deleted L{Tag}.
        """
        objectID = uuid4()
        TagAPI(self.user).create([(u'username/tag', u'A tag.')])
        tagValues = TagValueAPI(self.user)
        tagValues.set({objectID: {u'username/tag': 42}})
        self.store.commit()
        with login(u'username', uuid4(), self.transact) as session:
            yield self.facade.deleteTag(session, u'username/tag')

        self.store.rollback()
        self.assertEqual({}, tagValues.get(objectIDs=[objectID],
                                           paths=[u'username/tag']))

    @inlineCallbacks
    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.º 18
0
class SecureObjectAPIWithSuperuserRoleTest(FluidinfoTestCase):

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

    def setUp(self):
        super(SecureObjectAPIWithSuperuserRoleTest, self).setUp()
        system = createSystemData()
        self.superuser = system.users[u'fluiddb']
        self.permissions = CachingPermissionAPI(self.superuser)
        self.objects = SecureObjectAPI(self.superuser)
        UserAPI().create([(u'username', u'password', u'User',
                           u'*****@*****.**')])

    def testGetTagsByObjectsIsAlwaysAllowed(self):
        """
        L{SecureObjectAPI.getTagsByObjects} is always allowed for the
        superuser.
        """
        TagAPI(self.superuser).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.superuser).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])
        self.assertEqual(1, len(result))
        self.assertIn(objectID, result)
        self.assertEqual([u'username/tag1', u'username/tag2'],
                         sorted(result[objectID]))

    def testGetTagsByObjectsWithCustomPermission(self):
        """
        L{SecureObjectAPI.getTagsByObjects} optionally accepts a permission
        type to check for instead of L{Operation.READ_TAG_VALUE}).
        """
        TagAPI(self.superuser).create(
            [(u'username/open', u'An accessible tag'),
             (u'username/closed', u'A denied tag')])
        objectID = uuid4()
        SecureTagValueAPI(self.superuser).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)
        # Superuser can always delete values, regardless of permission settings
        result[objectID].sort()
        self.assertEqual({objectID: [u'username/closed', u'username/open']},
                         result)

    def testGetTagsForObjectsIsAlwaysAllowed(self):
        """
        L{SecureObjectAPI.getTagsForObjects} is always allowed for the
        superuser.
        """
        TagAPI(self.superuser).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.superuser).set(values)
        self.permissions.set([(u'username/tag1', Operation.READ_TAG_VALUE,
                               Policy.CLOSED, []),
                              (u'username/tag2', Operation.READ_TAG_VALUE,
                               Policy.OPEN, [])])

        self.assertEqual(
            sorted([u'username/tag1', u'username/tag2']),
            sorted(self.objects.getTagsForObjects([objectID])))
Exemplo n.º 19
0
class SecureRecentActivityAPIWithAnonymousRoleTest(FluidinfoTestCase):

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

    def setUp(self):
        super(SecureRecentActivityAPIWithAnonymousRoleTest, self).setUp()
        system = createSystemData()
        self.anon = system.users[u'anon']
        UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')])
        self.user = getUser(u'user')
        self.recentActivity = SecureRecentActivityAPI(self.anon)
        self.permissions = CachingPermissionAPI(self.user)

    def testGetForObjectsReturnsOnlyAllowedTags(self):
        """
        L{SecureRecentActivityAPI.getForObjects} will return all the tags for
        which the user has C{Operation.READ_TAG_VALUE} permissions, but not
        those for which the user doesn't have.
        """
        tagValues = TagValueAPI(self.user)
        objectID1 = ObjectAPI(self.user).create(u'object1')
        objectID2 = uuid4()

        # Use commit() frequently to have different timestamps on each value.
        self.store.commit()
        tagValues.set({objectID1: {u'user/tag1': u'A'}})
        self.store.commit()
        tagValues.set({objectID1: {u'user/tag2': u'B'}})
        self.store.commit()
        tagValues.set({objectID2: {u'user/tag1': u'C'}})
        self.store.commit()
        tagValues.set({objectID2: {u'user/tag2': u'D'}})
        self.store.commit()
        tagValues.set({uuid4(): {u'user/tag1': u'E'}})
        self.store.commit()
        tagValues.set({uuid4(): {u'user/tag2': u'F'}})
        self.store.commit()

        self.permissions.set([(u'user/tag2', Operation.READ_TAG_VALUE,
                               Policy.OPEN, [u'anon'])])

        expected = [
            (u'user/tag1', objectID2, None, u'C', u'user'),
            (u'user/tag1', objectID1, u'object1', u'A', u'user'),
            (u'fluiddb/about', objectID1, u'object1', u'object1', u'fluiddb')]

        result = self.recentActivity.getForObjects([objectID1, objectID2])

        # Remove the creation times from the result, with the order is enough.
        result = [(path, objectID, about, value, username)
                  for path, objectID, about, value, username, time in result]
        self.assertEqual(expected, result)

    def testGetForUsersReturnsOnlyAllowedTags(self):
        """
        L{SecureRecentActivityAPI.getForUsers} will return all the tags for
        which the user has C{Operation.READ_TAG_VALUE} permissions, but not
        those for which the user doesn't have.
        """
        tagValues = TagValueAPI(self.user)
        objectID1 = ObjectAPI(self.user).create(u'object1')
        objectID2 = uuid4()

        # Use commit() frequently to have different timestamps on each value.
        self.store.commit()
        tagValues.set({objectID1: {u'user/tag1': u'A'}})
        self.store.commit()
        tagValues.set({objectID1: {u'user/tag2': u'B'}})
        self.store.commit()

        UserAPI().create([(u'user2', u'secret', u'User', u'*****@*****.**')])
        tagValues = TagValueAPI(getUser(u'user2'))

        tagValues.set({objectID1: {u'user2/tag1': u'C'}})
        self.store.commit()
        tagValues.set({objectID2: {u'user2/tag2': u'D'}})
        self.store.commit()

        UserAPI().create([(u'user3', u'secret', u'User', u'*****@*****.**')])
        tagValues = TagValueAPI(getUser(u'user3'))

        tagValues.set({objectID1: {u'user3/tag1': u'C'}})
        self.store.commit()
        tagValues.set({objectID2: {u'user3/tag2': u'D'}})
        self.store.commit()

        self.permissions.set([(u'user/tag2', Operation.READ_TAG_VALUE,
                               Policy.OPEN, [u'anon']),
                              (u'user2/tag2', Operation.READ_TAG_VALUE,
                               Policy.CLOSED, [])])

        expected = [
            (u'user2/tag1', objectID1, u'object1', u'C', u'user2'),
            (u'user/tag1', objectID1, u'object1', u'A', u'user')]

        result = self.recentActivity.getForUsers([u'user', u'user2'])
        # Remove the creation times from the result, with the order is enough.
        result = [(path, objectID, about, value, username)
                  for path, objectID, about, value, username, time in result]
        self.assertEqual(expected, result)
Exemplo n.º 20
0
class FacadeObjectMixinTest(FluidinfoTestCase):

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

    def setUp(self):
        super(FacadeObjectMixinTest, self).setUp()
        self.system = createSystemData()
        self.transact = Transact(self.threadPool)
        factory = FluidinfoSessionFactory('API-9000')
        self.facade = Facade(self.transact, factory)
        UserAPI().create([(u'username', u'password', u'User',
                           u'*****@*****.**')])
        self.user = getUser(u'username')
        self.permissions = CachingPermissionAPI(self.user)

    @inlineCallbacks
    def testCreateObjectPermissionDenied(self):
        """
        L{FacadeObjectMixin.createObject} raises a
        L{TUnauthorized} exception if the user is the anonymous user.
        """
        self.store.commit()

        with login(u'anon', uuid4(), self.transact) as session:
            deferred = self.facade.createObject(session)
            yield self.assertFailure(deferred, TUnauthorized)

    @inlineCallbacks
    def testCreateObjectWithoutAboutValue(self):
        """
        L{FacadeObjectAPI.createObject} always returns a valid C{UUID} in a
        C{str} for a new object ID if an about value is not given.
        """
        self.store.commit()

        with login(u'username', uuid4(), self.transact) as session:
            objectID = yield self.facade.createObject(session)
            self.assertEqual(objectID, str(UUID(objectID)))

    @inlineCallbacks
    def testCreateObjectWithAboutValue(self):
        """
        L{FacadeObjectAPI.createObject} always returns a valid C{UUID} in a
        C{str} for a new object ID if an about value is given and it doesn't
        already exist.
        """
        self.store.commit()

        with login(self.user.username, uuid4(), self.transact) as session:
            objectID = yield self.facade.createObject(session, about='foo')
            objectID = UUID(objectID)

        self.store.rollback()
        value = getAboutTagValues([objectID], [u'foo']).one()
        self.assertEqual(u'foo', value.value)

        tag = self.system.tags[u'fluiddb/about']
        value = getTagValues(values=[(objectID, tag.id)]).one()
        self.assertIdentical(self.system.users[u'fluiddb'], value.creator)

    @inlineCallbacks
    def testCreateObjectWithDuplicateAboutValue(self):
        """
        L{FacadeObjectAPI.createObject} returns a valid C{UUID} in a C{str} for
        an existing object ID if an about value is given and already exists in
        the database.
        """
        objectID = uuid4()
        createAboutTagValue(objectID, u'bar')
        values = {objectID: {u'fluiddb/about': u'bar'}}
        SecureTagValueAPI(self.system.superuser).set(values)
        self.store.commit()

        with login(self.user.username, uuid4(), self.transact) as session:
            resultObjectID = yield self.facade.createObject(session,
                                                            about='bar')
            self.assertEqual(str(objectID), resultObjectID)

    @inlineCallbacks
    def testGetObject(self):
        """
        L{FacadeObjectAPI.getObject} returns a L{TObjectInfo} with the
        L{Tag.path}s for which the L{User} has L{Operation.READ_TAG_VALUE}.
        """
        objectID = uuid4()
        SecureTagAPI(self.user).create([(u'username/foo', u'A description')])
        values = {objectID: {u'username/foo': u'bar'}}
        SecureTagValueAPI(self.user).set(values)
        self.store.commit()

        with login(self.user.username, uuid4(), self.transact) as session:
            objectInfo = yield self.facade.getObject(session, str(objectID))
            self.assertEqual([u'username/foo'], objectInfo.tagPaths)
            self.assertEqual(None, objectInfo.about)

    @inlineCallbacks
    def testGetObjectWithAboutValue(self):
        """
        L{FacadeObjectAPI.getObject} returns a L{TObjectInfo} with the
        L{Tag.path}s for which the L{User} has L{Operation.READ_TAG_VALUE},
        and the L{AboutTagValue.value} if it has one and C{showAbout} is
        C{True}.
        """
        objectID = uuid4()
        SecureTagAPI(self.user).create([(u'username/foo', u'A description')])
        values = {objectID: {u'username/foo': u'bar'}}
        SecureTagValueAPI(self.user).set(values)
        aboutTag = self.system.tags[u'fluiddb/about']
        createAboutTagValue(objectID, u'bar')
        createTagValue(self.user.id, aboutTag.id, objectID, u'about value')
        self.store.commit()

        with login(self.user.username, uuid4(), self.transact) as session:
            objectInfo = yield self.facade.getObject(session, str(objectID),
                                                     showAbout=True)
            self.assertEqual([u'fluiddb/about', u'username/foo'],
                             sorted(objectInfo.tagPaths))
            self.assertEqual('about value', objectInfo.about)

    @inlineCallbacks
    def testGetObjectWithAboutValueDoesNotExist(self):
        """
        L{FacadeObjectAPI.getObject} returns a L{TObjectInfo} with the
        L{Tag.path}s for which the L{User} has L{Operation.READ_TAG_VALUE},
        and the L{AboutTagValue.value} if it has one and C{showAbout} is
        C{True}.
        """
        objectID = uuid4()
        tag = createTag(self.user, self.user.namespace, u'foo')
        createTagPermission(tag)
        createTagValue(self.user.id, tag.id, objectID, u'bar')
        session = AuthenticatedSession(self.user.username, uuid4())
        self.store.commit()
        with login(self.user.username, uuid4(), self.transact) as session:
            objectInfo = yield self.facade.getObject(session, str(objectID),
                                                     showAbout=True)
            self.assertEqual([u'username/foo'], objectInfo.tagPaths)
            self.assertIdentical(None, objectInfo.about)

    @inlineCallbacks
    def testGetObjectDeniedPaths(self):
        """
        L{FacadeObjectAPI.getObject} returns a L{TObjectInfo} with the
        L{Tag.path}s for which the L{User} has L{Operation.READ_TAG_VALUE}.
        """
        SecureTagAPI(self.user).create([(u'username/tag1', u'description'),
                                        (u'username/tag2', u'description')])
        objectID = uuid4()
        values = {objectID: {u'username/tag1': 16},
                  objectID: {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, [])])
        self.store.commit()

        with login(self.user.username, uuid4(), self.transact) as session:
            objectInfo = yield self.facade.getObject(session, str(objectID))
            self.assertEqual([u'username/tag2'], objectInfo.tagPaths)
            self.assertEqual(None, objectInfo.about)

    @inlineCallbacks
    def testGetObjectAllPathsAreDenied(self):
        """
        L{FacadeObjectAPI.getObject} returns a L{TObjectInfo} with the
        L{Tag.path}s for which the L{User} has L{Operation.READ_TAG_VALUE}, if
        all of them are denied, L{FacadeObjectAPI.getObject} must return an
        empty L{TObjectInfo}.
        """
        SecureTagAPI(self.user).create([(u'username/tag1', u'description'),
                                        (u'username/tag2', u'description')])
        objectID = uuid4()
        values = {objectID: {u'username/tag1': 16},
                  objectID: {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, [])])
        self.store.commit()

        with login(self.user.username, uuid4(), self.transact) as session:
            objectInfo = yield self.facade.getObject(session, str(objectID))
            self.assertEqual([], objectInfo.tagPaths)
            self.assertEqual(None, objectInfo.about)