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)
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)
def testRenderWithUnknownConsumer(self): """ A C{BAD_REQUEST} HTTP status code is returned if an L{OAuthRenewalToken} for an unknown L{OAuthConsumer} is used in a renewal request. """ UserAPI().create( [(u'consumer', 'secret', u'Consumer', u'*****@*****.**'), (u'user', 'secret', u'User', u'*****@*****.**')]) consumer = getUser(u'consumer') user = getUser(u'consumer') api = OAuthConsumerAPI() api.register(consumer) token = api.getRenewalToken(consumer, user) headers = {'X-FluidDB-Renewal-Token': [token.encrypt()]} self.store.find(OAuthConsumer).remove() self.store.commit() request = FakeRequest(headers=Headers(headers)) with login(u'consumer', consumer.objectID, self.transact) as session: resource = RenewOAuthTokenResource(session) self.assertEqual(NOT_DONE_YET, resource.render_GET(request)) yield resource.deferred headers = dict(request.responseHeaders.getAllRawHeaders()) self.assertEqual( {'X-Fluiddb-Error-Class': ['UnknownConsumer'], 'X-Fluiddb-Username': ['consumer'], 'X-Fluiddb-Request-Id': [session.id]}, headers) self.assertEqual(BAD_REQUEST, request.code)
def testRenderRecentUsersActivity(self): """ L{RecentUsersActivityResource.deferred_render_GET} renders a response with recent activity data by the users returned by the given query. """ objectID = ObjectAPI(self.user).create(u'object1') self.store.commit() TagValueAPI(self.user).set({objectID: {u'username/tag1': u'A'}}) runDataImportHandler(self.client.url) request = FakeRequest( args={'query': ['fluiddb/users/username = "******"']}) with login(u'username', self.user.objectID, self.transact) as session: resource = RecentUsersActivityResource(self.facade, session) body = yield resource.deferred_render_GET(request) body = json.loads(body) expected = [{ u'about': u'object1', u'id': str(objectID), u'tag': u'username/tag1', u'username': u'username', u'value': u'A' }] # Clean up timestamps. for item in body: del item['updated-at'] self.assertEqual(expected, body) self.assertEqual(http.OK, request.code)
def testRenderRecentUserActivity(self): """ L{RecentUserActivityResource.deferred_render_GET} renders a response with recent activity data for the given user. """ objectID = ObjectAPI(self.user).create(u'object1') TagValueAPI(self.user).set({objectID: {u'username/tag1': u'A'}}) self.store.commit() TagValueAPI(self.user).set({objectID: {u'username/tag2': u'B'}}) self.store.commit() request = FakeRequest() with login(u'username', self.user.objectID, self.transact) as session: resource = RecentUserActivityResource(self.facade, session, u'username') body = yield resource.deferred_render_GET(request) body = json.loads(body) expected = [{ u'username': u'username', u'about': u'object1', u'id': str(objectID), u'tag': u'username/tag2', u'value': u'B' }, { u'username': u'username', u'about': u'object1', u'id': str(objectID), u'tag': u'username/tag1', u'value': u'A' }] # Clean up timestamps. for item in body: del item['updated-at'] self.assertEqual(expected, body) self.assertEqual(http.OK, request.code)
def testRenderRecentUsersActivity(self): """ L{RecentUsersActivityResource.deferred_render_GET} renders a response with recent activity data by the users returned by the given query. """ objectID = ObjectAPI(self.user).create(u'object1') self.store.commit() TagValueAPI(self.user).set({objectID: {u'username/tag1': u'A'}}) runDataImportHandler(self.client.url) request = FakeRequest( args={'query': ['fluiddb/users/username = "******"']}) with login(u'username', self.user.objectID, self.transact) as session: resource = RecentUsersActivityResource(self.facade, session) body = yield resource.deferred_render_GET(request) body = json.loads(body) expected = [{u'about': u'object1', u'id': str(objectID), u'tag': u'username/tag1', u'username': u'username', u'value': u'A'}] # Clean up timestamps. for item in body: del item['updated-at'] self.assertEqual(expected, body) self.assertEqual(http.OK, request.code)
def testRenderWithUserConflict(self): """ A C{CONFLICT} HTTP status code is returned if the authorization is successfully verified by the service provider, but the username clashes with an existing L{User} that isn't linked to the Twitter UID. The offending username is returned UTF-8 and base64 encoded. """ username = u'john\N{HIRAGANA LETTER A}' UserAPI().create([(username, 'secret', u'John', u'*****@*****.**')]) self.store.commit() self.agent._connect = self._connect headers = {'X-Verify-Credentials-Authorization': ['OAuth ...'], 'X-Auth-Service-Provider': [TWITTER_URL]} request = FakeRequest(headers=Headers(headers)) with login(u'anon', self.anonymous.objectID, self.transact) as session: resource = OAuthEchoResource(session, self.agent) self.assertEqual(NOT_DONE_YET, resource.render_GET(request)) [(_, responseDeferred)] = self.protocol.requests data = {'id': 1984245, 'screen_name': username, 'name': u'John'} response = FakeResponse(ResponseDone(), dumps(data)) responseDeferred.callback(response) yield resource.deferred self.assertEqual(CONFLICT, request.code) headers = dict(request.responseHeaders.getAllRawHeaders()) encodedUsername = b64encode(username.encode('utf-8')) self.assertEqual( {'X-Fluiddb-Error-Class': ['UsernameConflict'], 'X-Fluiddb-Username': [encodedUsername], 'X-Fluiddb-Request-Id': [session.id]}, headers)
def testRenderWithUserConflict(self): """ A C{CONFLICT} HTTP status code is returned if the authorization is successfully verified by the service provider, but the username clashes with an existing L{User} that isn't linked to the Twitter UID. The offending username is returned UTF-8 and base64 encoded. """ username = u'john\N{HIRAGANA LETTER A}' UserAPI().create([(username, 'secret', u'John', u'*****@*****.**')]) self.store.commit() self.agent._connect = self._connect headers = { 'X-Verify-Credentials-Authorization': ['OAuth ...'], 'X-Auth-Service-Provider': [TWITTER_URL] } request = FakeRequest(headers=Headers(headers)) with login(u'anon', self.anonymous.objectID, self.transact) as session: resource = OAuthEchoResource(session, self.agent) self.assertEqual(NOT_DONE_YET, resource.render_GET(request)) [(_, responseDeferred)] = self.protocol.requests data = {'id': 1984245, 'screen_name': username, 'name': u'John'} response = FakeResponse(ResponseDone(), dumps(data)) responseDeferred.callback(response) yield resource.deferred self.assertEqual(CONFLICT, request.code) headers = dict(request.responseHeaders.getAllRawHeaders()) encodedUsername = b64encode(username.encode('utf-8')) self.assertEqual( { 'X-Fluiddb-Error-Class': ['UsernameConflict'], 'X-Fluiddb-Username': [encodedUsername], 'X-Fluiddb-Request-Id': [session.id] }, headers)
def testRenderRecentUserActivity(self): """ L{RecentUserActivityResource.deferred_render_GET} renders a response with recent activity data for the given user. """ objectID = ObjectAPI(self.user).create(u'object1') TagValueAPI(self.user).set({objectID: {u'username/tag1': u'A'}}) self.store.commit() TagValueAPI(self.user).set({objectID: {u'username/tag2': u'B'}}) self.store.commit() request = FakeRequest() with login(u'username', self.user.objectID, self.transact) as session: resource = RecentUserActivityResource(self.facade, session, u'username') body = yield resource.deferred_render_GET(request) body = json.loads(body) expected = [{u'username': u'username', u'about': u'object1', u'id': str(objectID), u'tag': u'username/tag2', u'value': u'B'}, {u'username': u'username', u'about': u'object1', u'id': str(objectID), u'tag': u'username/tag1', u'value': u'A'}] # Clean up timestamps. for item in body: del item['updated-at'] self.assertEqual(expected, body) self.assertEqual(http.OK, request.code)
def testRenderWithSuccessfulVerification(self): """ An C{OK} HTTP status code is returned, along with new access and renewal tokens, if a renewal request is successful. """ UserAPI().create( [(u'consumer', 'secret', u'Consumer', u'*****@*****.**'), (u'user', 'secret', u'User', u'*****@*****.**')]) consumer = getUser(u'consumer') user = getUser(u'consumer') api = OAuthConsumerAPI() api.register(consumer) token = api.getRenewalToken(consumer, user) self.store.commit() headers = {'X-FluidDB-Renewal-Token': [token.encrypt()]} request = FakeRequest(headers=Headers(headers)) with login(u'consumer', consumer.objectID, self.transact) as session: resource = RenewOAuthTokenResource(session) self.assertEqual(NOT_DONE_YET, resource.render_GET(request)) yield resource.deferred headers = dict(request.responseHeaders.getAllRawHeaders()) self.assertTrue(headers['X-Fluiddb-Access-Token']) self.assertTrue(headers['X-Fluiddb-Renewal-Token']) self.assertEqual(OK, request.code)
def testRenderWithExpiredRenewalToken(self): """ An C{UNAUTHORIZED} HTTP status code is returned if an expired L{OAuthRenewalToken} is used in a renewal request. """ UserAPI().create( [(u'consumer', 'secret', u'Consumer', u'*****@*****.**'), (u'user', 'secret', u'User', u'*****@*****.**')]) consumer = getUser(u'consumer') user = getUser(u'consumer') api = OAuthConsumerAPI() api.register(consumer) creationTime = datetime.utcnow() - timedelta(hours=200) token = api.getRenewalToken(consumer, user, now=lambda: creationTime) self.store.commit() headers = {'X-FluidDB-Renewal-Token': [token.encrypt()]} request = FakeRequest(headers=Headers(headers)) with login(u'consumer', consumer.objectID, self.transact) as session: resource = RenewOAuthTokenResource(session) self.assertEqual(NOT_DONE_YET, resource.render_GET(request)) yield resource.deferred headers = dict(request.responseHeaders.getAllRawHeaders()) self.assertEqual( {'X-Fluiddb-Error-Class': ['ExpiredOAuth2RenewalToken'], 'X-Fluiddb-Username': ['consumer'], 'X-Fluiddb-Request-Id': [session.id]}, headers) self.assertEqual(UNAUTHORIZED, request.code)
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)
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)
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)
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)
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)
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)
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)
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']))
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)
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)
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)
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)))
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)
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)
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)
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)
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'))
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)
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']))
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)
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)
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)
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)
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)
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)
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)
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)