def setUp(self): super(FacadeUserMixinTest, self).setUp() self.transact = Transact(self.threadPool) factory = FluidinfoSessionFactory('API-9000') self.facade = Facade(self.transact, factory) system = createSystemData() self.admin = system.users[u'fluiddb']
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)
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')])
class FacadeTest(FluidinfoTestCase): """ Simple tests of L{Facade} functionality that are not to do with user creation or authentication. """ resources = [('config', ConfigResource()), ('log', LoggingResource()), ('store', DatabaseResource()), ('threadPool', ThreadPoolResource())] def setUp(self): super(FacadeTest, self).setUp() factory = FluidinfoSessionFactory('API-9000') self.transact = Transact(self.threadPool) self.facade = Facade(self.transact, factory) self.system = createSystemData() @inlineCallbacks def testCreateAnonymousSession(self): """ L{FacadeAuthMixin.createAnonymousSession} creates a L{FluidinfoSession} for the anonymous user C{anon} so that anonymous requests coming from the C{WSFE} can be correctly verified by the L{Facade}. """ anon = self.system.users[u'anon'] self.store.commit() session = yield self.facade.createAnonymousSession() self.assertEqual('anon', session.auth.username) self.assertEqual(anon.objectID, session.auth.objectID)
def setUp(self): super(FacadeCheckerTest, self).setUp() factory = FluidinfoSessionFactory('API-9000') transact = Transact(self.threadPool) createSystemData() self.checker = FacadeChecker() self.checker.facadeClient = Facade(transact, factory)
def setUp(self): super(RootResourceTest, self).setUp() factory = FluidinfoSessionFactory('API-9000') transact = Transact(self.threadPool) createSystemData() self.checker = AnonymousChecker() self.checker.facadeClient = Facade(transact, factory) getConfig().set('service', 'allow-anonymous-access', 'False')
def setUp(self): super(RecentObjectsActivityResourceTest, self).setUp() createSystemData() UserAPI().create([(u'username', u'password', u'User', u'*****@*****.**')]) self.user = getUser(u'username') factory = FluidinfoSessionFactory('API-9000') self.transact = Transact(self.threadPool) self.facade = Facade(self.transact, factory)
def setUp(self): super(FacadeNamespaceTest, 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 = PermissionAPI(self.user)
def setupFacade(config): """Get the L{Facade} instance to use in the API service.""" from fluiddb.api.facade import Facade from fluiddb.util.transact import Transact maxThreads = int(config.get('service', 'max-threads')) threadpool = ThreadPool(minthreads=0, maxthreads=maxThreads) reactor.callWhenRunning(threadpool.start) reactor.addSystemEventTrigger('during', 'shutdown', threadpool.stop) transact = Transact(threadpool) factory = FluidinfoSessionFactory('API-%s' % config.get('service', 'port')) return Facade(transact, factory)
class FacadeRecentActivityMixinTest(FluidinfoTestCase): resources = [('cache', CacheResource()), ('client', IndexResource()), ('config', ConfigResource()), ('log', LoggingResource()), ('store', DatabaseResource()), ('threadPool', ThreadPoolResource())] def setUp(self): super(FacadeRecentActivityMixinTest, 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 testGetRecentObjectActivity(self): """ L{FacadeRecentActivityMixin.getRecentObjectActivity} returns a C{dict} with information about the recent tag values on the given object. """ 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() expected = [ {'tag': u'user/tag2', 'id': str(objectID1), 'about': u'object1', 'value': u'B', 'username': u'username'}, {'tag': u'user/tag1', 'id': str(objectID1), 'about': u'object1', 'value': u'A', 'username': u'username'}, {'tag': u'fluiddb/about', 'id': str(objectID1), 'about': u'object1', 'value': u'object1', 'username': u'fluiddb'}] with login(self.user.username, uuid4(), self.transact) as session: result = yield self.facade.getRecentObjectActivity( session, str(objectID1)) # Remove the creation times from the result. for item in result: del item['updated-at'] self.assertEqual(expected, result) @inlineCallbacks def testGetRecentAboutActivity(self): """ L{FacadeRecentActivityMixin.getRecentAboutActivity} returns a C{dict} with information about the recent tag values on the given object. """ 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() expected = [ {'tag': u'user/tag2', 'id': str(objectID1), 'about': u'object1', 'value': u'B', 'username': u'username'}, {'tag': u'user/tag1', 'id': str(objectID1), 'about': u'object1', 'value': u'A', 'username': u'username'}, {'tag': u'fluiddb/about', 'id': str(objectID1), 'about': u'object1', 'value': u'object1', 'username': u'fluiddb'}] with login(self.user.username, uuid4(), self.transact) as session: result = yield self.facade.getRecentAboutActivity( session, 'object1') # Remove the creation times from the result. for item in result: del item['updated-at'] self.assertEqual(expected, result) @inlineCallbacks def testGetRecentAboutActivityWithUnkownAboutValue(self): """ L{FacadeRecentActivityMixin.getRecentAboutActivity} returns an empty C{list} if the about value doesn't exist. """ with login(self.user.username, uuid4(), self.transact) as session: result = yield self.facade.getRecentAboutActivity(session, 'unknown') self.assertEqual([], result) @inlineCallbacks def testGetRecentUserActivity(self): """ L{FacadeRecentActivityMixin.getRecentUserActivity} returns a C{dict} with information about the recent tag values on the given user. """ 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() expected = [ {'tag': u'user/tag2', 'id': str(objectID1), 'about': u'object1', 'value': u'B', 'username': u'username'}, {'tag': u'user/tag1', 'id': str(objectID1), 'about': u'object1', 'value': u'A', 'username': u'username'}] with login(self.user.username, uuid4(), self.transact) as session: result = yield self.facade.getRecentUserActivity( session, self.user.username.encode('utf-8')) # Remove the creation times from the result. for item in result: del item['updated-at'] self.assertEqual(expected, result) @inlineCallbacks def testGetRecentUserActivityWithUnkownUser(self): """ L{FacadeRecentActivityMixin.getRecentUserActivity} raises L{TNoSuchUser} if the given user doesn't exist. """ with login(self.user.username, uuid4(), self.transact) as session: result = self.facade.getRecentUserActivity(session, 'unknown') yield self.assertFailure(result, TNoSuchUser) @inlineCallbacks def testGetRecentActivityForQuery(self): """ L{FacadeRecentActivityMixin.getRecentActivityForQuery} returns a C{dict} with information about the recent tag values on the objects returned by the given query. """ tagValues = TagValueAPI(self.user) objectID1 = ObjectAPI(self.user).create(u'object1') # Use commit() frequently to have different timestamps on each value. self.store.commit() tagValues.set({objectID1: {u'user/following': u'A'}}) self.store.commit() runDataImportHandler(self.client.url) expected = [{'about': u'object1', 'id': str(objectID1), 'tag': u'user/following', 'username': u'username', 'value': u'A'}, {'about': u'object1', 'id': str(objectID1), 'tag': u'fluiddb/about', 'username': u'fluiddb', 'value': u'object1'}] with login(self.user.username, uuid4(), self.transact) as session: result = yield self.facade.getRecentActivityForQuery( session, u'has user/following') # Remove the creation times from the result. for item in result: del item['updated-at'] self.assertEqual(expected, result) @inlineCallbacks def testGetRecentActivityForQueryWithBadQuery(self): """ L{FacadeRecentActivityMixin.getRecentActivityForQuery} raises L{TParseError} if the given query can't be parsed. """ with login(self.user.username, uuid4(), self.transact) as session: result = self.facade.getRecentActivityForQuery(session, 'bad') yield self.assertFailure(result, TParseError) @inlineCallbacks def testGetRecentActivityForQueryWithIllegalQuery(self): """ L{FacadeRecentActivityMixin.getRecentActivityForQuery} raises L{TBadRequest} if the given query contains illegal sub queries. """ with login(self.user.username, uuid4(), self.transact) as session: result = self.facade.getRecentActivityForQuery( session, 'has fluiddb/about') yield self.assertFailure(result, TBadRequest) @inlineCallbacks def testGetRecentUserActivityForQuery(self): """ L{FacadeRecentActivityMixin.getRecentUserActivityForQuery} returns a C{dict} with information about the recent tag values by the users whose objects are returned by the given query. """ UserAPI().create([(u'user2', u'password', u'User', u'*****@*****.**')]) user2 = getUser(u'user2') objectID1 = uuid4() # Use commit() frequently to have different timestamps on each value. TagValueAPI(self.user).set({objectID1: {u'username/test': u'A'}}) self.store.commit() TagValueAPI(user2).set({objectID1: {u'user2/test': u'B'}}) self.store.commit() runDataImportHandler(self.client.url) expected = [{'about': None, 'id': str(objectID1), 'tag': u'user2/test', 'username': u'user2', 'value': u'B'}, {'about': None, 'id': str(objectID1), 'tag': u'username/test', 'username': u'username', 'value': u'A'}] with login(self.user.username, uuid4(), self.transact) as session: result = yield self.facade.getRecentUserActivityForQuery( session, u'fluiddb/users/username = "******" ' 'OR fluiddb/users/username = "******"') # Remove the creation times from the result. for item in result: del item['updated-at'] self.assertEqual(expected, result) @inlineCallbacks def testGetRecentUserActivityForQueryWithBadQuery(self): """ L{FacadeRecentActivityMixin.getRecentUserActivityForQuery} raises L{TParseError} if the given query can't be parsed. """ with login(self.user.username, uuid4(), self.transact) as session: result = self.facade.getRecentUserActivityForQuery(session, 'bad') yield self.assertFailure(result, TParseError) @inlineCallbacks def testGetRecentUserActivityForQueryWithIllegalQuery(self): """ L{FacadeRecentActivityMixin.getRecentUserActivityForQuery} raises L{TBadRequest} if the given query contains illegal sub queries. """ with login(self.user.username, uuid4(), self.transact) as session: result = self.facade.getRecentUserActivityForQuery( session, 'has fluiddb/about') yield self.assertFailure(result, TBadRequest) @inlineCallbacks def testGetRecentUserActivityForQueryWithObjectsNotUsers(self): """ L{FacadeRecentActivityMixin.getRecentUserActivityForQuery} returns an empty result if the objects returned by the query are not users. """ tagValues = TagValueAPI(self.user) objectID1 = ObjectAPI(self.user).create(u'object1') # Use commit() frequently to have different timestamps on each value. self.store.commit() tagValues.set({objectID1: {u'user/following': u'A'}}) self.store.commit() runDataImportHandler(self.client.url) with login(self.user.username, uuid4(), self.transact) as session: result = yield self.facade.getRecentUserActivityForQuery( session, u'has user/following') # Remove the creation times from the result. for item in result: del item['updated-at'] self.assertEqual([], result)
def setUp(self): super(FacadeUserCreationTest, self).setUp() factory = FluidinfoSessionFactory('API-9000') self.transact = Transact(self.threadPool) self.facade = Facade(self.transact, factory) self.system = createSystemData()
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)
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)
class FacadeAuthenticateUserWithPasswordTest(FluidinfoTestCase): """Test L{Facade} user+password authentication.""" resources = [('cache', CacheResource()), ('config', ConfigResource()), ('log', LoggingResource()), ('store', DatabaseResource()), ('threadPool', ThreadPoolResource())] def setUp(self): super(FacadeAuthenticateUserWithPasswordTest, self).setUp() factory = FluidinfoSessionFactory('API-9000') self.transact = Transact(self.threadPool) self.facade = Facade(self.transact, factory) self.system = createSystemData() @inlineCallbacks def testAuthenticateUserWithPassword(self): """ L{FacadeAuthMixin.authenticateUserWithPassword} creates a L{FluidinfoSession} for the authenticated user only if credentials are correct. """ user = createUser(u'user', u'pass', u'User', u'*****@*****.**') self.store.commit() session = yield self.facade.authenticateUserWithPassword('user', 'pass') self.assertEqual('user', session.auth.username) self.assertEqual(user.objectID, session.auth.objectID) @inlineCallbacks def testAuthenticateUserWithPasswordIgnoresCase(self): """ L{FacadeAuthMixin.authenticateUserWithPassword} ignores case for the the username. """ UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')]) self.store.commit() session = yield self.facade.authenticateUserWithPassword('UsEr', 'secret') self.assertEqual('user', session.auth.username) @inlineCallbacks def testAuthenticateUserWithPasswordUnicodeUsername(self): """ L{FacadeAuthMixin.authenticateUserWithPassword} will accept UTF-8 encoded C{str}s for the username and the password, and convert them to C{unicode} appropiately. """ username = u'\N{HIRAGANA LETTER A}' password = u'\N{HIRAGANA LETTER E}' fullname = u'\N{HIRAGANA LETTER I}' email = u'*****@*****.**' user = createUser(username, password, fullname, email) self.store.commit() session = yield self.facade.authenticateUserWithPassword( username.encode('utf-8'), password.encode('utf-8')) self.assertEqual(username, session.auth.username) self.assertEqual(user.objectID, session.auth.objectID) def testAuthenticateUserWithPasswordIncorrectPassword(self): """ L{FacadeAuthMixin.authenticateUserWithPassword} raises a L{TPasswordIncorrect} exception if the provided password doesn't match the L{User}'s. """ createUser(u'username', u'password', u'User', u'*****@*****.**') self.store.commit() deferred = self.facade.authenticateUserWithPassword('username', 'bad-password') return self.assertFailure(deferred, TPasswordIncorrect) def testAuthenticateUserWithPasswordUnknownUser(self): """ L{FacadeAuthMixin.authenticateUserWithPassword} raises a L{TNoSuchUser} exception if the provided username doesn't exist in the database. """ self.store.commit() deferred = self.facade.authenticateUserWithPassword('unknown', 'pwd') return self.assertFailure(deferred, TNoSuchUser) @inlineCallbacks def testAuthenticateUserWithPasswordStopsSessionOnError(self): """ L{FacadeAuthMixin.authenticateUserWithPassword} stops the session if an authentication error occurs, preventing memory leaks. """ self.store.commit() # We monkeypatch the Session.close method to know if it was called. oldStop = Session.stop def stopWrapper(*args, **kwargs): self.sessionStopped = True return oldStop(*args, **kwargs) Session.stop = stopWrapper self.sessionStopped = False deferred = self.facade.authenticateUserWithPassword('unknown', 'pwd') yield self.assertFailure(deferred, TNoSuchUser) self.assertTrue(self.sessionStopped) self.sessionStopped = False deferred = self.facade.authenticateUserWithPassword('username', 'bad') yield self.assertFailure(deferred, TNoSuchUser) self.assertTrue(self.sessionStopped) Session.stop = oldStop
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)
class FacadeUserMixinTest(FluidinfoTestCase): resources = [('cache', CacheResource()), ('config', ConfigResource()), ('log', LoggingResource()), ('store', DatabaseResource()), ('threadPool', ThreadPoolResource())] def setUp(self): super(FacadeUserMixinTest, self).setUp() self.transact = Transact(self.threadPool) factory = FluidinfoSessionFactory('API-9000') self.facade = Facade(self.transact, factory) system = createSystemData() self.admin = system.users[u'fluiddb'] @inlineCallbacks def testGetUserWithoutData(self): """ L{FacadeUserMixin.getUser} raises a L{TNoSuchUser} exception if the requested L{User.username} doesn't exist. """ self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: deferred = self.facade.getUser(session, u'unknown') error = yield self.assertFailure(deferred, TNoSuchUser) self.assertEqual(u'unknown', error.name) @inlineCallbacks def testGetUser(self): """ L{FacadeUserMixin.getUser} returns a L{TUser} instance with information about the requested L{User}. """ UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')]) user = getUser(u'user') self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: result = yield self.facade.getUser(session, u'user') self.assertEqual(u'user', result.username) self.assertEqual(str(user.objectID), result.objectId) self.assertEqual(u'User', result.name) self.assertEqual(u'USER', result.role) @inlineCallbacks def testGetUserIgnoresCase(self): """L{FacadeUserMixin.getUser} ignores case for the username.""" UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')]) self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: result = yield self.facade.getUser(session, u'uSeR') self.assertEqual(u'user', result.username) @inlineCallbacks def testUpdateUser(self): """ L{FacadeUserMixin.updateUser} updates the description for an existing L{User}. """ UserAPI().create([(u'test', u'secret', u'name', u'*****@*****.**')]) user = getUser(u'test') passwordHash = user.passwordHash self.store.commit() info = TUserUpdate(u'test', u'password', u'new-name', u'*****@*****.**') with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.updateUser(session, info) self.store.rollback() self.assertEqual(u'test', user.username) self.assertNotEqual(passwordHash, user.passwordHash) self.assertEqual(u'new-name', user.fullname) self.assertEqual(u'*****@*****.**', user.email) @inlineCallbacks def testUpdateUserWithoutPassword(self): """ If a L{User.password} is not passed to L{FacadeUserMixin.updateUser} the existing password will not be changed. """ UserAPI().create([(u'user', u'secret', u'name', u'*****@*****.**')]) user = getUser(u'user') passwordHash = user.passwordHash info = TUserUpdate(u'user', None, u'new-name', u'*****@*****.**', 'USER_MANAGER') self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.updateUser(session, info) self.store.rollback() self.assertEqual(u'user', user.username) self.assertEqual(passwordHash, user.passwordHash) self.assertEqual(u'new-name', user.fullname) self.assertEqual(u'*****@*****.**', user.email) self.assertEqual(Role.USER_MANAGER, user.role) @inlineCallbacks def testUpdateUserWithoutName(self): """ If a L{User.fullname} is not passed to L{FacadeUserMixin.updateUser} the existing name will not be changed. """ UserAPI().create([(u'user', u'secret', u'name', u'*****@*****.**')]) user = getUser(u'user') passwordHash = user.passwordHash info = TUserUpdate(u'user', u's3cr3t', None, u'*****@*****.**', 'USER_MANAGER') self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.updateUser(session, info) self.store.rollback() self.assertEqual(u'user', user.username) self.assertNotEqual(passwordHash, user.passwordHash) self.assertEqual(u'name', user.fullname) self.assertEqual(u'*****@*****.**', user.email) self.assertEqual(Role.USER_MANAGER, user.role) @inlineCallbacks def testUpdateUserWithoutEmail(self): """ If a L{User.email} is not passed to L{FacadeUserMixin.updateUser} the existing email address will not be changed. """ UserAPI().create([(u'user', u'secret', u'name', u'*****@*****.**')]) user = getUser(u'user') passwordHash = user.passwordHash info = TUserUpdate(u'user', u's3cr3t', u'new-name', None, 'USER_MANAGER') self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.updateUser(session, info) self.store.rollback() self.assertEqual(u'user', user.username) self.assertNotEqual(passwordHash, user.passwordHash) self.assertEqual(u'new-name', user.fullname) self.assertEqual(u'*****@*****.**', user.email) self.assertEqual(Role.USER_MANAGER, user.role) @inlineCallbacks def testUpdateUserWithoutRole(self): """ If a L{User.role} is not passed to L{FacadeUserMixin.updateUser} the existing user role will not be changed. """ UserAPI().create([(u'user', u'secret', u'name', u'*****@*****.**')]) user = getUser(u'user') passwordHash = user.passwordHash info = TUserUpdate(u'user', u's3cr3t', u'new-name', '*****@*****.**', None) self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.updateUser(session, info) self.store.rollback() self.assertEqual(u'user', user.username) self.assertNotEqual(passwordHash, user.passwordHash) self.assertEqual(u'new-name', user.fullname) self.assertEqual(u'*****@*****.**', user.email) self.assertEqual(Role.USER, user.role) @inlineCallbacks def testUpdateUserWithBadRole(self): """ If an invalid L{User.role} is passed to L{FacadeUserMixin.updateUser} a L{TBadRequest} exception is raised. """ info = TUserUpdate(u'user', u's3cr3t', u'new-name', '*****@*****.**', 'BAD_ROLE') with login(u'fluiddb', self.admin.objectID, self.transact) as session: deferred = self.facade.updateUser(session, info) yield self.assertFailure(deferred, TBadRequest) @inlineCallbacks def testUpdateUserIgnoresCase(self): """ L{FacadeUserMixin.updateUser} ignores case when updating a new user. """ UserAPI().create([(u'test', u'secret', u'name', u'*****@*****.**')]) user = getUser(u'test') passwordHash = user.passwordHash info = TUserUpdate(u'TesT', u'password', u'new-name', u'*****@*****.**') self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.updateUser(session, info) self.store.rollback() self.assertEqual(u'test', user.username) self.assertNotEqual(passwordHash, user.passwordHash) self.assertEqual(u'new-name', user.fullname) self.assertEqual(u'*****@*****.**', user.email) @inlineCallbacks def testUpdateUserWithUnknownUsername(self): """ L{FacadeUserMixin.updateUser} raises a L{TNoSuchUser} exception if the requested L{User.username} doesn't exist. """ info = TUserUpdate(u'unknown', u'password', u'name', u'*****@*****.**') self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: deferred = self.facade.updateUser(session, info) error = yield self.assertFailure(deferred, TNoSuchUser) self.assertEqual(u'unknown', error.name) @inlineCallbacks def testUpdateUserIsDenied(self): """ L{FacadeUserMixin.updateUser} raises a L{TPathPermissionDenied} exception if the user making the request is not a superuser. """ UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')]) info = TUserUpdate(u'username', u'secret', u'Username', u'*****@*****.**') self.store.commit() with login(u'user', uuid4(), self.transact) as session: deferred = self.facade.updateUser(session, info) error = yield self.assertFailure(deferred, TPathPermissionDenied) self.assertEqual(u'username', error.path) @inlineCallbacks def testDeleteUser(self): """L{FacadeUserMixin.deleteUser} deletes a L{User}.""" UserAPI().create([(u'test', u'secret', u'name', u'*****@*****.**')], createPrivateNamespace=False) self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.deleteUser(session, u'test') self.store.rollback() self.assertIdentical(None, getUser(u'test')) @inlineCallbacks def testDeleteUserIgnoresCase(self): """ L{FacadeUserMixin.deleteUser} ignores case for the username when deleting a user. """ UserAPI().create([(u'test', u'secret', u'name', u'*****@*****.**')], createPrivateNamespace=False) self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.deleteUser(session, u'tESt') self.store.rollback() self.assertIdentical(None, getUser(u'test')) @inlineCallbacks def testDeleteUserWithUnknownUsername(self): """ L{FacadeUserMixin.deleteUser} raises a L{TNoSuchUser} exception if the specified L{User.username} doesn't exist. """ self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: deferred = self.facade.deleteUser(session, u'unknown') error = yield self.assertFailure(deferred, TNoSuchUser) self.assertEqual(u'unknown', error.name) @inlineCallbacks def testDeleteUserIsDenied(self): """ L{FacadeUserMixin.deleteUser} raises a L{TPathPermissionDenied} exception if the user making the request is not a superuser. """ [(objectID, username)] = UserAPI().create( [(u'user', u'secret', u'User', u'*****@*****.**')]) self.store.commit() with login(u'user', objectID, self.transact) as session: deferred = self.facade.deleteUser(session, u'doomed') error = yield self.assertFailure(deferred, TPathPermissionDenied) self.assertEqual(u'doomed', error.path)
def setUp(self): super(FacadeAuthenticateUserWithPasswordTest, self).setUp() factory = FluidinfoSessionFactory('API-9000') self.transact = Transact(self.threadPool) self.facade = Facade(self.transact, factory) self.system = createSystemData()
class FacadeAuthenticateUserWithOAuthTest(FluidinfoTestCase): """Test L{Facade} OAuth authentication.""" resources = [('config', ConfigResource()), ('log', LoggingResource()), ('store', DatabaseResource()), ('threadPool', ThreadPoolResource())] def setUp(self): super(FacadeAuthenticateUserWithOAuthTest, self).setUp() factory = FluidinfoSessionFactory('API-9000') self.transact = Transact(self.threadPool) self.facade = Facade(self.transact, factory) self.system = createSystemData() @inlineCallbacks def testAuthenticateUserWithOAuth(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth} creates a L{FluidinfoSession} for the authenticated user only if credentials are correct. """ UserAPI().create([ (u'consumer', u'secret', u'Consumer', u'*****@*****.**'), (u'user', u'secret', u'User', u'*****@*****.**')]) consumerUser = getUser(u'consumer') user = getUser(u'user') api = OAuthConsumerAPI() consumer = api.register(consumerUser) token = api.getAccessToken(consumerUser, user) self.store.commit() timestamp = 1314976811 headers = {'header1': 'foo'} arguments = 'argument1=bar' request = Request.from_request('GET', u'https://fluidinfo.com/foo', headers, {'argument1': 'bar'}) signature = SignatureMethod_HMAC_SHA1().sign(request, consumer, None) nonce = 'nonce' credentials = OAuthCredentials( 'fluidinfo.com', consumerUser.username, token.encrypt(), 'HMAC-SHA1', signature, timestamp, nonce, 'GET', u'https://fluidinfo.com/foo', headers, arguments) session = yield self.facade.authenticateUserWithOAuth(credentials) self.assertEqual(user.username, session.auth.username) self.assertEqual(user.objectID, session.auth.objectID) @inlineCallbacks def testAuthenticateUserWithOAuthIgnoresCase(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth} ignores the case in the consumer key. """ UserAPI().create([ (u'consumer', u'secret', u'Consumer', u'*****@*****.**'), (u'user', u'secret', u'User', u'*****@*****.**')]) consumerUser = getUser(u'consumer') user = getUser(u'user') api = OAuthConsumerAPI() consumer = api.register(consumerUser) token = api.getAccessToken(consumerUser, user) self.store.commit() timestamp = 1314976811 headers = {'header1': 'foo'} arguments = 'argument1=bar' request = Request.from_request('GET', u'https://fluidinfo.com/foo', headers, {'argument1': 'bar'}) signature = SignatureMethod_HMAC_SHA1().sign(request, consumer, None) nonce = 'nonce' credentials = OAuthCredentials( 'fluidinfo.com', u'ConsumeR', token.encrypt(), 'HMAC-SHA1', signature, timestamp, nonce, 'GET', u'https://fluidinfo.com/foo', headers, arguments) session = yield self.facade.authenticateUserWithOAuth(credentials) self.assertEqual(user.username, session.auth.username) self.assertEqual(user.objectID, session.auth.objectID) @inlineCallbacks def testAuthenticateUserWithOAuthWithMixedCaseInToken(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth} ignores the case in the username in the token. """ UserAPI().create([ (u'consumer', u'secret', u'Consumer', u'*****@*****.**'), (u'user', u'secret', u'User', u'*****@*****.**')]) consumerUser = getUser(u'consumer') user = getUser(u'user') api = OAuthConsumerAPI() consumer = api.register(consumerUser) token = dataToToken(consumer.secret, {'username': u'UseR', 'creationTime': '20121228-161823'}) self.store.commit() timestamp = 1314976811 headers = {'header1': 'foo'} arguments = 'argument1=bar' request = Request.from_request('GET', u'https://fluidinfo.com/foo', headers, {'argument1': 'bar'}) signature = SignatureMethod_HMAC_SHA1().sign(request, consumer, None) nonce = 'nonce' credentials = OAuthCredentials( 'fluidinfo.com', consumerUser.username, token, 'HMAC-SHA1', signature, timestamp, nonce, 'GET', u'https://fluidinfo.com/foo', headers, arguments) session = yield self.facade.authenticateUserWithOAuth(credentials) self.assertEqual(user.username, session.auth.username) self.assertEqual(user.objectID, session.auth.objectID) def testAuthenticateUserWithOAuthIncorrectSignature(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth} raises a L{TPasswordIncorrect} exception if the signature in the OAuth credentials is incorrect. """ UserAPI().create([ (u'consumer', u'secret', u'Consumer', u'*****@*****.**'), (u'user', u'secret', u'User', u'*****@*****.**')]) consumerUser = getUser(u'consumer') user = getUser(u'user') api = OAuthConsumerAPI() api.register(consumerUser) token = api.getAccessToken(consumerUser, user) self.store.commit() timestamp = 1314976811 headers = {'header1': 'foo'} arguments = 'argument1=bar' signature = 'wrong' nonce = 'nonce' credentials = OAuthCredentials( 'fluidinfo.com', user.username, token.encrypt(), u'HMAC-SHA1', signature, timestamp, nonce, 'GET', 'https://fluidinfo.com/foo', headers, arguments) deferred = self.facade.authenticateUserWithOAuth(credentials) return self.assertFailure(deferred, TPasswordIncorrect) def testAuthenticateUserWithOAuthUnknownConsumer(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth} raises L{TNoSuchUser} if the consumer does not exist. """ user2 = createUser(u'user2', u'pass2', u'User2', u'*****@*****.**') self.store.commit() timestamp = 1314976811 headers = {'header1': 'foo'} arguments = 'argument1=bar' token = dataToToken('a' * 16, {'username': user2.username}) signature = '3MNZYSgsGftopjuwv3g2u5Q+MZM=' nonce = 'nonce' credentials = OAuthCredentials( 'fluidinfo.com', u'user1', token, 'HMAC-SHA1', signature, timestamp, nonce, 'GET', u'https://fluidinfo.com/foo', headers, arguments) deferred = self.facade.authenticateUserWithOAuth(credentials) return self.assertFailure(deferred, TNoSuchUser) def testAuthenticateUserWithOAuthUnregisteredConsumer(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth} raises L{TPasswordIncorrect} if the consumer exists as a Fluidinfo user but is not registered as an OAuth consumer. """ user1 = createUser(u'user1', u'pass1', u'User1', u'*****@*****.**') user2 = createUser(u'user2', u'pass2', u'User2', u'*****@*****.**') self.store.commit() timestamp = 1314976811 headers = {'header1': 'foo'} arguments = 'argument1=bar' token = dataToToken('a' * 16, {'username': user2.username}) signature = '3MNZYSgsGftopjuwv3g2u5Q+MZM=' nonce = 'nonce' credentials = OAuthCredentials( 'fluidinfo.com', user1.username, token, 'HMAC-SHA1', signature, timestamp, nonce, 'GET', u'https://fluidinfo.com/foo', headers, arguments) deferred = self.facade.authenticateUserWithOAuth(credentials) return self.assertFailure(deferred, TPasswordIncorrect) def testAuthenticateUserWithOAuthUnknownUsernameInToken(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth} raises a L{TNoSuchUser} exception if the username in the token does not match an existing L{User}. """ user1 = createUser(u'user1', u'pass1', u'User1', u'*****@*****.**') oauthConsumer1 = createOAuthConsumer(user1, secret='secret16charlng1') self.store.commit() timestamp = 1314976811 headers = {'header1': 'foo'} arguments = 'argument1=bar' token = dataToToken(oauthConsumer1.secret, {'username': u'unknownUser'}) signature = '3MNZYSgsGftopjuwv3g2u5Q+MZM=' nonce = 'nonce' credentials = OAuthCredentials( 'fluidinfo.com', user1.username, token, u'HMAC-SHA1', signature, timestamp, nonce, 'GET', 'https://fluidinfo.com/foo', headers, arguments) deferred = self.facade.authenticateUserWithOAuth(credentials) return self.assertFailure(deferred, TNoSuchUser)
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)
class FacadeAuthenticateUserWithOAuth2Test(FluidinfoTestCase): """Test L{Facade} OAuth2 authentication.""" resources = [('cache', CacheResource()), ('config', ConfigResource()), ('log', LoggingResource()), ('store', DatabaseResource()), ('threadPool', ThreadPoolResource())] def setUp(self): super(FacadeAuthenticateUserWithOAuth2Test, self).setUp() factory = FluidinfoSessionFactory('API-9000') self.transact = Transact(self.threadPool) self.facade = Facade(self.transact, factory) self.system = createSystemData() @inlineCallbacks def testAuthenticateUserWithOAuth2(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth2} creates a L{FluidinfoSession} for the authenticated user only if credentials are correct. """ UserAPI().create([ (u'consumer', u'secret', u'Consumer', u'*****@*****.**'), (u'user', u'secret', u'User', u'*****@*****.**')]) consumer = getUser(u'consumer') user = getUser(u'user') api = OAuthConsumerAPI() api.register(consumer) token = api.getAccessToken(consumer, user) self.store.commit() credentials = OAuth2Credentials(u'consumer', u'secret', token.encrypt()) session = yield self.facade.authenticateUserWithOAuth2(credentials) self.assertEqual(user.username, session.auth.username) self.assertEqual(user.objectID, session.auth.objectID) @inlineCallbacks def testAuthenticateUserWithOAuth2IgnoresCase(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth2} creates a L{FluidinfoSession} for the authenticated user only if credentials are correct. """ UserAPI().create([ (u'consumer', u'secret', u'Consumer', u'*****@*****.**'), (u'user', u'secret', u'User', u'*****@*****.**')]) consumer = getUser(u'consumer') user = getUser(u'user') api = OAuthConsumerAPI() api.register(consumer) token = api.getAccessToken(consumer, user) self.store.commit() credentials = OAuth2Credentials(u'ConsumeR', u'secret', token.encrypt()) session = yield self.facade.authenticateUserWithOAuth2(credentials) self.assertEqual(user.username, session.auth.username) self.assertEqual(user.objectID, session.auth.objectID) @inlineCallbacks def testAuthenticateUserWithOAuthWithMixedCaseToken(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth2} ignores case in the username in the token. """ UserAPI().create([ (u'consumer', u'secret', u'Consumer', u'*****@*****.**'), (u'user', u'secret', u'User', u'*****@*****.**')]) consumer = getUser(u'consumer') user = getUser(u'user') api = OAuthConsumerAPI() oauthConsumer = api.register(consumer) token = dataToToken(oauthConsumer.secret, {'username': u'UseR', 'creationTime': '20121228-161823'}) self.store.commit() credentials = OAuth2Credentials(consumer.username, u'secret', token) session = yield self.facade.authenticateUserWithOAuth2(credentials) self.assertEqual(user.username, session.auth.username) self.assertEqual(user.objectID, session.auth.objectID) @inlineCallbacks def testAuthenticateAnonymousUserWithOAuth2(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth2} should create a L{FluidinfoSession} for the anonymous user. """ anonymous = self.system.users[u'anon'] UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')]) user = getUser(u'user') api = OAuthConsumerAPI() api.register(anonymous) token = api.getAccessToken(anonymous, user) self.store.commit() credentials = OAuth2Credentials(u'anon', None, token.encrypt()) session = yield self.facade.authenticateUserWithOAuth2(credentials) self.assertEqual(user.username, session.auth.username) self.assertEqual(user.objectID, session.auth.objectID) def testAuthenticateUserWithOAuth2ConsumerPasswordIncorrect(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth2} raises L{TPasswordIncorrect} if the consumer's password is not correct. """ user1 = createUser(u'user1', u'pass1', u'User1', u'*****@*****.**') oauthConsumer1 = createOAuthConsumer(user1, secret='secret16charlng1') user2 = createUser(u'user2', u'pass2', u'User2', u'*****@*****.**') self.store.commit() token = dataToToken(oauthConsumer1.secret, {'username': user2.username}) credentials = OAuth2Credentials(u'user1', u'invalid', token) deferred = self.facade.authenticateUserWithOAuth2(credentials) return self.assertFailure(deferred, TPasswordIncorrect) def testAuthenticateUserWithOAuth2UnknownConsumer(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth2} raises L{TNoSuchUser} if the consumer does not exist. """ user = createUser(u'user', u'pass', u'User', u'*****@*****.**') oauthConsumer = createOAuthConsumer(user, secret='secret16charlng1') self.store.commit() token = dataToToken(oauthConsumer.secret, {'username': u'unknownUser'}) credentials = OAuth2Credentials(u'invalid', u'pass', token) deferred = self.facade.authenticateUserWithOAuth2(credentials) return self.assertFailure(deferred, TNoSuchUser) def testAuthenticateUserWithOAuth2UnregisteredConsumer(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth2} raises L{TPasswordIncorrect} if the consumer exists as a Fluidinfo user but is not registered as an OAuth consumer. """ createUser(u'user1', u'pass1', u'User1', u'*****@*****.**') createUser(u'user2', u'pass2', u'User2', u'*****@*****.**') self.store.commit() token = dataToToken('a' * 16, {'username': u'user2'}) credentials = OAuth2Credentials(u'user1', u'pass1', token) deferred = self.facade.authenticateUserWithOAuth2(credentials) return self.assertFailure(deferred, TPasswordIncorrect) def testAuthenticateUserWithOAuth2UnknownUsernameInToken(self): """ L{FacadeAuthMixin.authenticateUserWithOAuth2} ignores the case in the consumer key. """ user = createUser(u'user', u'pass', u'User', u'*****@*****.**') oauthConsumer = createOAuthConsumer(user, secret='secret16charlng1') self.store.commit() token = dataToToken(oauthConsumer.secret, {'username': u'unknownUser'}) credentials = OAuth2Credentials(u'user', u'pass', token) deferred = self.facade.authenticateUserWithOAuth2(credentials) return self.assertFailure(deferred, TNoSuchUser)
class FacadeNamespaceTest(FluidinfoTestCase): resources = [('cache', CacheResource()), ('config', ConfigResource()), ('log', LoggingResource()), ('store', DatabaseResource()), ('threadPool', ThreadPoolResource())] def setUp(self): super(FacadeNamespaceTest, 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 = PermissionAPI(self.user) @inlineCallbacks def testGetNamespaceWithoutData(self): """ L{Facade.getNamespace} raises a L{TNonexistentNamespace} exception if the requested L{Namespace.path} doesn't exist. """ self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.getNamespace(session, u'username/unknown', False, False, False) yield self.assertFailure(deferred, TNonexistentNamespace) @inlineCallbacks def testGetNamespace(self): """ L{Facade.getNamespace} returns a L{TNamespace} instance with information about the requested L{Namespace}. """ self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: result = yield self.facade.getNamespace(session, u'username', False, False, False) self.assertEqual(str(self.user.namespace.objectID), result.objectId) self.assertEqual(u'username', result.path) @inlineCallbacks def testGetNamespaceWithDescription(self): """ L{Facade.getNamespace} includes the L{Namespace.description}, if it was requested. """ namespaces = NamespaceAPI(self.user) namespaces.create([(u'username/name', u'A namespace.')]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: result = yield self.facade.getNamespace(session, u'username/name', True, False, False) self.assertEqual(u'A namespace.', result.description) @inlineCallbacks def testGetNamespaceWithNamespaces(self): """ L{Facade.getNamespace} includes child L{Namespace.name}s, if they were requested. """ namespaces = NamespaceAPI(self.user) namespaces.create([(u'username/name', u'A namespace.')]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: result = yield self.facade.getNamespace(session, u'username', False, True, False) self.assertEqual([u'name', u'private'], sorted(result.namespaces)) @inlineCallbacks def testGetNamespaceWithTags(self): """ L{Facade.getNamespace} includes child L{Tag.name}s, if they were requested. """ createTag(self.user, self.user.namespace, u'tag') self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: result = yield self.facade.getNamespace(session, u'username', False, False, True) self.assertEqual([u'tag'], result.tags) @inlineCallbacks def testGetNamespaceWithUnknownPath(self): """ L{Facade.getNamespace} raises a L{TNonexistentNamespace} exception if the specified L{Namespace} doesn't exist. """ with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.getNamespace(session, u'unknown', returnDescription=False, returnNamespaces=False, returnTags=False) yield self.assertFailure(deferred, TNonexistentNamespace) @inlineCallbacks def testGetNamespaceWithPermissionDenied(self): """ L{Facade.getNamespace} raises a L{TPathPermissionDenied} exception if the user doesn't have C{LIST} permissions on the specified L{Namespace}. """ self.permissions.set([(u'username', Operation.LIST_NAMESPACE, Policy.CLOSED, [])]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.getNamespace(session, u'username', returnDescription=True, returnNamespaces=True, returnTags=True) yield self.assertFailure(deferred, TPathPermissionDenied) @inlineCallbacks def testCreateNamespace(self): """L{Facade.createNamespace} creates a new L{Namespace}.""" self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: objectID = yield self.facade.createNamespace( session, u'username', u'name', u'A namespace.') self.store.rollback() self.assertNotIdentical(None, objectID) objectID = UUID(objectID) namespace = getNamespaces(objectIDs=[objectID]).one() self.assertIdentical(self.user, namespace.creator) self.assertEqual(u'username/name', namespace.path) self.assertEqual(u'name', namespace.name) self.assertEqual(objectID, namespace.objectID) @inlineCallbacks def testCreateNamespaceWithExistingPath(self): """ L{Facade.createNamespace} raises a L{TNamespaceAlreadyExists} exception if the new L{Namespace} already exists. """ createNamespace(self.user, u'username/name', self.user.namespace.id) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.createNamespace(session, u'username', u'name', u'A namespace.') yield self.assertFailure(deferred, TNamespaceAlreadyExists) @inlineCallbacks def testCreateNamespaceWithUnknownParent(self): """ L{Facade.createNamespace} raises a L{TNonexistentNamespace} exception if a non-existent parent L{Namespace} is specified. """ createNamespace(self.user, u'username/name', self.user.namespace.id) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.createNamespace(session, u'unknown/parent', u'name', u'A namespace.') yield self.assertFailure(deferred, TNonexistentNamespace) @inlineCallbacks def testCreateNamespaceWithInvalidPath(self): """ L{Facade.createNamespace} raises a L{TInvalidPath} exception if the path of the L{Namespace} is not well formed. """ self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.createNamespace(session, u'username', u'bad name', u'description') yield self.assertFailure(deferred, TInvalidPath) @inlineCallbacks def testCreateNamespaceImplicitlyCreatesParent(self): """ L{Facade.createNamespace} implicitly creates parent L{Namespace}s if they don't exist. """ self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: objectID = yield self.facade.createNamespace( session, u'username/parent', u'name', u'A namespace.') namespace = yield self.facade.getNamespace( session, u'username/parent/name', returnDescription=False, returnNamespaces=False, returnTags=False) self.assertEqual(objectID, namespace.objectId) @inlineCallbacks def testCreateIsDenied(self): """ L{Facade.createNamespace} 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', self.user.objectID, self.transact) as session: deferred = self.facade.createNamespace(session, u'username', u'test', u'description') yield self.assertFailure(deferred, TPathPermissionDenied) @inlineCallbacks def testUpdateNamespace(self): """ L{Facade.updateNamespace} updates the description for an existing L{Namespace}. """ namespaces = NamespaceAPI(self.user) namespaces.create([(u'username/name', u'A namespace.')]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: yield self.facade.updateNamespace(session, u'username/name', u'A new description.') self.store.rollback() result = namespaces.get([u'username/name'], withDescriptions=True) self.assertEqual(u'A new description.', result[u'username/name']['description']) @inlineCallbacks def testUpdateNamespaceWithUnknownPath(self): """ L{Facade.updateNamespace} raises a L{TNonexistentNamespace} exception if the requested L{Namespace.path} doesn't exist. """ self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.updateNamespace( session, u'username/unknown', u'A new description.') yield self.assertFailure(deferred, TNonexistentNamespace) @inlineCallbacks def testUpdateIsDenied(self): """ L{Facade.updateNamespace} raises a L{TPathPermissionDenied} exception if the user doesn't have C{UPDATE} permissions on the specified L{Namespace}. """ self.permissions.set([(u'username', Operation.UPDATE_NAMESPACE, Policy.CLOSED, [])]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.updateNamespace(session, u'username', u'description') yield self.assertFailure(deferred, TPathPermissionDenied) @inlineCallbacks def testDeleteNamespace(self): """L{Facade.deleteNamespace} deletes a L{Namespace}.""" namespaces = NamespaceAPI(self.user) namespaces.create([(u'username/name', u'A namespace.')]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: yield self.facade.deleteNamespace(session, u'username/name') self.store.rollback() self.assertEqual({}, namespaces.get([u'username/name'])) @inlineCallbacks def testDeleteNamespaceWithUnknownPath(self): """ L{Facade.deleteNamespace} raises a L{TNonexistentNamespace} exception if the requested L{Namespace.path} doesn't exist. """ self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.deleteNamespace(session, u'username/unknown') yield self.assertFailure(deferred, TNonexistentNamespace) @inlineCallbacks def testDeleteNamespaceWithData(self): """ L{Facade.deleteNamespace} raises a L{TNamespaceNotEmpty} exception if the requested L{Namespace} has child data such as other L{Namespace}s or L{Tag}s. """ namespaces = NamespaceAPI(self.user) namespaces.create([(u'username/parent', u'A parent namespace.')]) namespaces.create([(u'username/parent/child', u'A child namespace.')]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.deleteNamespace(session, u'username/parent') yield self.assertFailure(deferred, TNamespaceNotEmpty) @inlineCallbacks def testDeleteIsDenied(self): """ L{Facade.deleteNamespace} raises a L{TPathPermissionDenied} exception if the user doesn't have C{DELETE} permissions on the specified L{Namespace}. """ namespaces = NamespaceAPI(self.user) namespaces.create([(u'username/test', u'description')]) self.permissions.set([(u'username/test', Operation.DELETE_NAMESPACE, Policy.OPEN, [u'username'])]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.deleteNamespace(session, u'username/test') yield self.assertFailure(deferred, TPathPermissionDenied)
class FacadeUserCreationTest(FluidinfoTestCase): """Test L{Facade} user creation.""" resources = [('cache', CacheResource()), ('config', ConfigResource()), ('log', LoggingResource()), ('store', DatabaseResource()), ('threadPool', ThreadPoolResource())] def setUp(self): super(FacadeUserCreationTest, self).setUp() factory = FluidinfoSessionFactory('API-9000') self.transact = Transact(self.threadPool) self.facade = Facade(self.transact, factory) self.system = createSystemData() @inlineCallbacks def testCreateUserWithPassword(self): """ L{FacadeAuthMixin.createUserWithPassword} will create a new user in the database and return its object ID when invoked by the superuser. """ superuser = self.system.users[u'fluiddb'] self.store.commit() with login(u'fluiddb', superuser.objectID, self.transact) as session: objectID = yield self.facade.createUserWithPassword( session, 'user', 'secret', 'User', '*****@*****.**') self.store.rollback() self.assertEqual({u'user': {'id': UUID(objectID), 'name': u'User', 'role': Role.USER}}, UserAPI().get([u'user'])) @inlineCallbacks def testCreateUserWithPasswordIgnoresCase(self): """ L{FacadeAuthMixin.createUserWithPassword} ignores the case of the username. """ superuser = self.system.users[u'fluiddb'] self.store.commit() with login(u'fluiddb', superuser.objectID, self.transact) as session: objectID = yield self.facade.createUserWithPassword( session, 'UsEr', 'secret', 'User', '*****@*****.**') self.store.rollback() self.assertEqual({u'user': {'id': UUID(objectID), 'name': u'User', 'role': Role.USER}}, UserAPI().get([u'user'])) @inlineCallbacks def testCreateUserUnicode(self): """ L{FacadeAuthMixin.createUserWithPassword} will accept UTF-8 encoded C{str}s for the username, the password, the full name and the email address and convert them to C{unicode} appropriately. """ superuser = self.system.users[u'fluiddb'] username = u'\N{HIRAGANA LETTER A}' password = u'\N{HIRAGANA LETTER E}' name = u'\N{HIRAGANA LETTER I}' email = u'*****@*****.**' self.store.commit() with login(u'fluiddb', superuser.objectID, self.transact) as session: objectID = yield self.facade.createUserWithPassword( session, username.encode('utf-8'), password.encode('utf-8'), name.encode('utf-8'), email.encode('utf-8')) self.store.rollback() user = getUser(username) self.assertEqual(str(user.objectID), objectID) self.assertEqual(user.fullname, name) self.assertEqual(user.email, email) @inlineCallbacks def testCreateUserDuplicate(self): """ L{FacadeAuthMixin.createUserWithPassword} will raise a L{TUserAlreadyExists} if the username given already exists in the database. """ createUser(u'fred', u'password', u'Fred', u'*****@*****.**') superuser = self.system.users[u'fluiddb'] self.store.commit() with login(u'fluiddb', superuser.objectID, self.transact) as session: deferred = self.facade.createUserWithPassword( session, 'fred', 'password', 'Fred', '*****@*****.**') yield self.assertFailure(deferred, TUserAlreadyExists) @inlineCallbacks def testCreateUserWithInvalidUsername(self): """ L{FacadeAuthMixin.createUserWithPassword} will raise a L{TInvalidUsername} exception if the username given is invalid. """ superuser = self.system.users[u'fluiddb'] self.store.commit() with login(u'fluiddb', superuser.objectID, self.transact) as session: deferred = self.facade.createUserWithPassword( session, '!invalid & ', 'secret', 'None', '*****@*****.**') yield self.assertFailure(deferred, TInvalidUsername) @inlineCallbacks def testCreateUserWithLongUsername(self): """ L{FacadeAuthMixin.createUserWithPassword} will raise a L{TUsernameTooLong} exception if the username given is longer than 128 characters. """ superuser = self.system.users[u'fluiddb'] self.store.commit() with login(u'fluiddb', superuser.objectID, self.transact) as session: session.auth.login(u'fluiddb', superuser.objectID) deferred = self.facade.createUserWithPassword( session, 'x' * 129, 'secret', 'None', '*****@*****.**') yield self.assertFailure(deferred, TUsernameTooLong) @inlineCallbacks def testCreateUserNormalUserRole(self): """ L{FacadeAuthMixin.createUserWithPassword} will raise a L{TPathPermissionDenied} if invoked by a normal user. """ user = createUser(u'user', u'pass', u'User', u'*****@*****.**') self.store.commit() with login(u'user', user.objectID, self.transact) as session: deferred = self.facade.createUserWithPassword( session, 'fred', 'password', 'Fred', '*****@*****.**') yield self.assertFailure(deferred, TPathPermissionDenied) @inlineCallbacks def testCreateUserByAnonymousRole(self): """ L{FacadeAuthMixin.createUserWithPassword} will raise a L{TPathPermissionDenied} if invoked by the anonymous user. """ anonymous = self.system.users[u'anon'] self.store.commit() with login(u'anon', anonymous.objectID, self.transact) as session: deferred = self.facade.createUserWithPassword( session, 'fred', 'password', 'Fred', '*****@*****.**') yield self.assertFailure(deferred, TPathPermissionDenied)
class FacadeNamespaceTest(FluidinfoTestCase): resources = [('cache', CacheResource()), ('config', ConfigResource()), ('log', LoggingResource()), ('store', DatabaseResource()), ('threadPool', ThreadPoolResource())] def setUp(self): super(FacadeNamespaceTest, 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 = PermissionAPI(self.user) @inlineCallbacks def testGetNamespaceWithoutData(self): """ L{Facade.getNamespace} raises a L{TNonexistentNamespace} exception if the requested L{Namespace.path} doesn't exist. """ self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.getNamespace(session, u'username/unknown', False, False, False) yield self.assertFailure(deferred, TNonexistentNamespace) @inlineCallbacks def testGetNamespace(self): """ L{Facade.getNamespace} returns a L{TNamespace} instance with information about the requested L{Namespace}. """ self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: result = yield self.facade.getNamespace(session, u'username', False, False, False) self.assertEqual(str(self.user.namespace.objectID), result.objectId) self.assertEqual(u'username', result.path) @inlineCallbacks def testGetNamespaceWithDescription(self): """ L{Facade.getNamespace} includes the L{Namespace.description}, if it was requested. """ namespaces = NamespaceAPI(self.user) namespaces.create([(u'username/name', u'A namespace.')]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: result = yield self.facade.getNamespace(session, u'username/name', True, False, False) self.assertEqual(u'A namespace.', result.description) @inlineCallbacks def testGetNamespaceWithNamespaces(self): """ L{Facade.getNamespace} includes child L{Namespace.name}s, if they were requested. """ namespaces = NamespaceAPI(self.user) namespaces.create([(u'username/name', u'A namespace.')]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: result = yield self.facade.getNamespace(session, u'username', False, True, False) self.assertEqual([u'name', u'private'], sorted(result.namespaces)) @inlineCallbacks def testGetNamespaceWithTags(self): """ L{Facade.getNamespace} includes child L{Tag.name}s, if they were requested. """ createTag(self.user, self.user.namespace, u'tag') self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: result = yield self.facade.getNamespace(session, u'username', False, False, True) self.assertEqual([u'tag'], result.tags) @inlineCallbacks def testGetNamespaceWithUnknownPath(self): """ L{Facade.getNamespace} raises a L{TNonexistentNamespace} exception if the specified L{Namespace} doesn't exist. """ with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.getNamespace(session, u'unknown', returnDescription=False, returnNamespaces=False, returnTags=False) yield self.assertFailure(deferred, TNonexistentNamespace) @inlineCallbacks def testGetNamespaceWithPermissionDenied(self): """ L{Facade.getNamespace} raises a L{TPathPermissionDenied} exception if the user doesn't have C{LIST} permissions on the specified L{Namespace}. """ self.permissions.set([(u'username', Operation.LIST_NAMESPACE, Policy.CLOSED, [])]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.getNamespace(session, u'username', returnDescription=True, returnNamespaces=True, returnTags=True) yield self.assertFailure(deferred, TPathPermissionDenied) @inlineCallbacks def testCreateNamespace(self): """L{Facade.createNamespace} creates a new L{Namespace}.""" self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: objectID = yield self.facade.createNamespace( session, u'username', u'name', u'A namespace.') self.store.rollback() self.assertNotIdentical(None, objectID) objectID = UUID(objectID) namespace = getNamespaces(objectIDs=[objectID]).one() self.assertIdentical(self.user, namespace.creator) self.assertEqual(u'username/name', namespace.path) self.assertEqual(u'name', namespace.name) self.assertEqual(objectID, namespace.objectID) @inlineCallbacks def testCreateNamespaceWithExistingPath(self): """ L{Facade.createNamespace} raises a L{TNamespaceAlreadyExists} exception if the new L{Namespace} already exists. """ createNamespace(self.user, u'username/name', self.user.namespace.id) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.createNamespace(session, u'username', u'name', u'A namespace.') yield self.assertFailure(deferred, TNamespaceAlreadyExists) @inlineCallbacks def testCreateNamespaceWithUnknownParent(self): """ L{Facade.createNamespace} raises a L{TNonexistentNamespace} exception if a non-existent parent L{Namespace} is specified. """ createNamespace(self.user, u'username/name', self.user.namespace.id) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.createNamespace(session, u'unknown/parent', u'name', u'A namespace.') yield self.assertFailure(deferred, TNonexistentNamespace) @inlineCallbacks def testCreateNamespaceWithInvalidPath(self): """ L{Facade.createNamespace} raises a L{TInvalidPath} exception if the path of the L{Namespace} is not well formed. """ self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.createNamespace(session, u'username', u'bad name', u'description') yield self.assertFailure(deferred, TInvalidPath) @inlineCallbacks def testCreateNamespaceImplicitlyCreatesParent(self): """ L{Facade.createNamespace} implicitly creates parent L{Namespace}s if they don't exist. """ self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: objectID = yield self.facade.createNamespace( session, u'username/parent', u'name', u'A namespace.') namespace = yield self.facade.getNamespace(session, u'username/parent/name', returnDescription=False, returnNamespaces=False, returnTags=False) self.assertEqual(objectID, namespace.objectId) @inlineCallbacks def testCreateIsDenied(self): """ L{Facade.createNamespace} 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', self.user.objectID, self.transact) as session: deferred = self.facade.createNamespace(session, u'username', u'test', u'description') yield self.assertFailure(deferred, TPathPermissionDenied) @inlineCallbacks def testUpdateNamespace(self): """ L{Facade.updateNamespace} updates the description for an existing L{Namespace}. """ namespaces = NamespaceAPI(self.user) namespaces.create([(u'username/name', u'A namespace.')]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: yield self.facade.updateNamespace(session, u'username/name', u'A new description.') self.store.rollback() result = namespaces.get([u'username/name'], withDescriptions=True) self.assertEqual(u'A new description.', result[u'username/name']['description']) @inlineCallbacks def testUpdateNamespaceWithUnknownPath(self): """ L{Facade.updateNamespace} raises a L{TNonexistentNamespace} exception if the requested L{Namespace.path} doesn't exist. """ self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.updateNamespace(session, u'username/unknown', u'A new description.') yield self.assertFailure(deferred, TNonexistentNamespace) @inlineCallbacks def testUpdateIsDenied(self): """ L{Facade.updateNamespace} raises a L{TPathPermissionDenied} exception if the user doesn't have C{UPDATE} permissions on the specified L{Namespace}. """ self.permissions.set([(u'username', Operation.UPDATE_NAMESPACE, Policy.CLOSED, [])]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.updateNamespace(session, u'username', u'description') yield self.assertFailure(deferred, TPathPermissionDenied) @inlineCallbacks def testDeleteNamespace(self): """L{Facade.deleteNamespace} deletes a L{Namespace}.""" namespaces = NamespaceAPI(self.user) namespaces.create([(u'username/name', u'A namespace.')]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: yield self.facade.deleteNamespace(session, u'username/name') self.store.rollback() self.assertEqual({}, namespaces.get([u'username/name'])) @inlineCallbacks def testDeleteNamespaceWithUnknownPath(self): """ L{Facade.deleteNamespace} raises a L{TNonexistentNamespace} exception if the requested L{Namespace.path} doesn't exist. """ self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.deleteNamespace(session, u'username/unknown') yield self.assertFailure(deferred, TNonexistentNamespace) @inlineCallbacks def testDeleteNamespaceWithData(self): """ L{Facade.deleteNamespace} raises a L{TNamespaceNotEmpty} exception if the requested L{Namespace} has child data such as other L{Namespace}s or L{Tag}s. """ namespaces = NamespaceAPI(self.user) namespaces.create([(u'username/parent', u'A parent namespace.')]) namespaces.create([(u'username/parent/child', u'A child namespace.')]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.deleteNamespace(session, u'username/parent') yield self.assertFailure(deferred, TNamespaceNotEmpty) @inlineCallbacks def testDeleteIsDenied(self): """ L{Facade.deleteNamespace} raises a L{TPathPermissionDenied} exception if the user doesn't have C{DELETE} permissions on the specified L{Namespace}. """ namespaces = NamespaceAPI(self.user) namespaces.create([(u'username/test', u'description')]) self.permissions.set([(u'username/test', Operation.DELETE_NAMESPACE, Policy.OPEN, [u'username'])]) self.store.commit() with login(u'username', self.user.objectID, self.transact) as session: deferred = self.facade.deleteNamespace(session, u'username/test') yield self.assertFailure(deferred, TPathPermissionDenied)
class FacadeUserMixinTest(FluidinfoTestCase): resources = [('cache', CacheResource()), ('config', ConfigResource()), ('log', LoggingResource()), ('store', DatabaseResource()), ('threadPool', ThreadPoolResource())] def setUp(self): super(FacadeUserMixinTest, self).setUp() self.transact = Transact(self.threadPool) factory = FluidinfoSessionFactory('API-9000') self.facade = Facade(self.transact, factory) system = createSystemData() self.admin = system.users[u'fluiddb'] @inlineCallbacks def testGetUserWithoutData(self): """ L{FacadeUserMixin.getUser} raises a L{TNoSuchUser} exception if the requested L{User.username} doesn't exist. """ self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: deferred = self.facade.getUser(session, u'unknown') error = yield self.assertFailure(deferred, TNoSuchUser) self.assertEqual(u'unknown', error.name) @inlineCallbacks def testGetUser(self): """ L{FacadeUserMixin.getUser} returns a L{TUser} instance with information about the requested L{User}. """ UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')]) user = getUser(u'user') self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: result = yield self.facade.getUser(session, u'user') self.assertEqual(u'user', result.username) self.assertEqual(str(user.objectID), result.objectId) self.assertEqual(u'User', result.name) self.assertEqual(u'USER', result.role) @inlineCallbacks def testGetUserIgnoresCase(self): """L{FacadeUserMixin.getUser} ignores case for the username.""" UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')]) self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: result = yield self.facade.getUser(session, u'uSeR') self.assertEqual(u'user', result.username) @inlineCallbacks def testUpdateUser(self): """ L{FacadeUserMixin.updateUser} updates the description for an existing L{User}. """ UserAPI().create([(u'test', u'secret', u'name', u'*****@*****.**')]) user = getUser(u'test') passwordHash = user.passwordHash self.store.commit() info = TUserUpdate(u'test', u'password', u'new-name', u'*****@*****.**') with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.updateUser(session, info) self.store.rollback() self.assertEqual(u'test', user.username) self.assertNotEqual(passwordHash, user.passwordHash) self.assertEqual(u'new-name', user.fullname) self.assertEqual(u'*****@*****.**', user.email) @inlineCallbacks def testUpdateUserWithoutPassword(self): """ If a L{User.password} is not passed to L{FacadeUserMixin.updateUser} the existing password will not be changed. """ UserAPI().create([(u'user', u'secret', u'name', u'*****@*****.**')]) user = getUser(u'user') passwordHash = user.passwordHash info = TUserUpdate(u'user', None, u'new-name', u'*****@*****.**', 'USER_MANAGER') self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.updateUser(session, info) self.store.rollback() self.assertEqual(u'user', user.username) self.assertEqual(passwordHash, user.passwordHash) self.assertEqual(u'new-name', user.fullname) self.assertEqual(u'*****@*****.**', user.email) self.assertEqual(Role.USER_MANAGER, user.role) @inlineCallbacks def testUpdateUserWithoutName(self): """ If a L{User.fullname} is not passed to L{FacadeUserMixin.updateUser} the existing name will not be changed. """ UserAPI().create([(u'user', u'secret', u'name', u'*****@*****.**')]) user = getUser(u'user') passwordHash = user.passwordHash info = TUserUpdate(u'user', u's3cr3t', None, u'*****@*****.**', 'USER_MANAGER') self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.updateUser(session, info) self.store.rollback() self.assertEqual(u'user', user.username) self.assertNotEqual(passwordHash, user.passwordHash) self.assertEqual(u'name', user.fullname) self.assertEqual(u'*****@*****.**', user.email) self.assertEqual(Role.USER_MANAGER, user.role) @inlineCallbacks def testUpdateUserWithoutEmail(self): """ If a L{User.email} is not passed to L{FacadeUserMixin.updateUser} the existing email address will not be changed. """ UserAPI().create([(u'user', u'secret', u'name', u'*****@*****.**')]) user = getUser(u'user') passwordHash = user.passwordHash info = TUserUpdate(u'user', u's3cr3t', u'new-name', None, 'USER_MANAGER') self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.updateUser(session, info) self.store.rollback() self.assertEqual(u'user', user.username) self.assertNotEqual(passwordHash, user.passwordHash) self.assertEqual(u'new-name', user.fullname) self.assertEqual(u'*****@*****.**', user.email) self.assertEqual(Role.USER_MANAGER, user.role) @inlineCallbacks def testUpdateUserWithoutRole(self): """ If a L{User.role} is not passed to L{FacadeUserMixin.updateUser} the existing user role will not be changed. """ UserAPI().create([(u'user', u'secret', u'name', u'*****@*****.**')]) user = getUser(u'user') passwordHash = user.passwordHash info = TUserUpdate(u'user', u's3cr3t', u'new-name', '*****@*****.**', None) self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.updateUser(session, info) self.store.rollback() self.assertEqual(u'user', user.username) self.assertNotEqual(passwordHash, user.passwordHash) self.assertEqual(u'new-name', user.fullname) self.assertEqual(u'*****@*****.**', user.email) self.assertEqual(Role.USER, user.role) @inlineCallbacks def testUpdateUserWithBadRole(self): """ If an invalid L{User.role} is passed to L{FacadeUserMixin.updateUser} a L{TBadRequest} exception is raised. """ info = TUserUpdate(u'user', u's3cr3t', u'new-name', '*****@*****.**', 'BAD_ROLE') with login(u'fluiddb', self.admin.objectID, self.transact) as session: deferred = self.facade.updateUser(session, info) yield self.assertFailure(deferred, TBadRequest) @inlineCallbacks def testUpdateUserIgnoresCase(self): """ L{FacadeUserMixin.updateUser} ignores case when updating a new user. """ UserAPI().create([(u'test', u'secret', u'name', u'*****@*****.**')]) user = getUser(u'test') passwordHash = user.passwordHash info = TUserUpdate(u'TesT', u'password', u'new-name', u'*****@*****.**') self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.updateUser(session, info) self.store.rollback() self.assertEqual(u'test', user.username) self.assertNotEqual(passwordHash, user.passwordHash) self.assertEqual(u'new-name', user.fullname) self.assertEqual(u'*****@*****.**', user.email) @inlineCallbacks def testUpdateUserWithUnknownUsername(self): """ L{FacadeUserMixin.updateUser} raises a L{TNoSuchUser} exception if the requested L{User.username} doesn't exist. """ info = TUserUpdate(u'unknown', u'password', u'name', u'*****@*****.**') self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: deferred = self.facade.updateUser(session, info) error = yield self.assertFailure(deferred, TNoSuchUser) self.assertEqual(u'unknown', error.name) @inlineCallbacks def testUpdateUserIsDenied(self): """ L{FacadeUserMixin.updateUser} raises a L{TPathPermissionDenied} exception if the user making the request is not a superuser. """ UserAPI().create([(u'user', u'secret', u'User', u'*****@*****.**')]) info = TUserUpdate(u'username', u'secret', u'Username', u'*****@*****.**') self.store.commit() with login(u'user', uuid4(), self.transact) as session: deferred = self.facade.updateUser(session, info) error = yield self.assertFailure(deferred, TPathPermissionDenied) self.assertEqual(u'username', error.path) @inlineCallbacks def testDeleteUser(self): """L{FacadeUserMixin.deleteUser} deletes a L{User}.""" UserAPI().create([(u'test', u'secret', u'name', u'*****@*****.**')], createPrivateNamespace=False) self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.deleteUser(session, u'test') self.store.rollback() self.assertIdentical(None, getUser(u'test')) @inlineCallbacks def testDeleteUserIgnoresCase(self): """ L{FacadeUserMixin.deleteUser} ignores case for the username when deleting a user. """ UserAPI().create([(u'test', u'secret', u'name', u'*****@*****.**')], createPrivateNamespace=False) self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: yield self.facade.deleteUser(session, u'tESt') self.store.rollback() self.assertIdentical(None, getUser(u'test')) @inlineCallbacks def testDeleteUserWithUnknownUsername(self): """ L{FacadeUserMixin.deleteUser} raises a L{TNoSuchUser} exception if the specified L{User.username} doesn't exist. """ self.store.commit() with login(u'fluiddb', self.admin.objectID, self.transact) as session: deferred = self.facade.deleteUser(session, u'unknown') error = yield self.assertFailure(deferred, TNoSuchUser) self.assertEqual(u'unknown', error.name) @inlineCallbacks def testDeleteUserIsDenied(self): """ L{FacadeUserMixin.deleteUser} raises a L{TPathPermissionDenied} exception if the user making the request is not a superuser. """ [(objectID, username)] = UserAPI().create([ (u'user', u'secret', u'User', u'*****@*****.**') ]) self.store.commit() with login(u'user', objectID, self.transact) as session: deferred = self.facade.deleteUser(session, u'doomed') error = yield self.assertFailure(deferred, TPathPermissionDenied) self.assertEqual(u'doomed', error.path)