def test_post_submission_require_auth_data_entry_role(self): self.user.profile.require_auth = True self.user.profile.save() alice_data = {'username': '******', 'email': '*****@*****.**'} alice_profile = self._create_user_profile(alice_data) DataEntryRole.add(alice_profile.user, self.xform) count = Attachment.objects.count() s = self.surveys[0] media_file = "1335783522563.jpg" path = os.path.join(self.main_directory, 'fixtures', 'transportation', 'instances', s, media_file) with open(path) as f: f = InMemoryUploadedFile(f, 'media_file', media_file, 'image/jpg', os.path.getsize(path), None) submission_path = os.path.join(self.main_directory, 'fixtures', 'transportation', 'instances', s, s + '.xml') with open(submission_path) as sf: data = {'xml_submission_file': sf, 'media_file': f} request = self.factory.post('/submission', data) response = self.view(request) self.assertEqual(response.status_code, 401) response = self.view(request, username=self.user.username) self.assertEqual(response.status_code, 401) self.assertEqual(count, Attachment.objects.count()) auth = DigestAuth('alice', 'bobbob') request.META.update(auth(request.META, response)) response = self.view(request, username=self.user.username) self.assertContains(response, 'Successful submission', status_code=201)
def test_get_xform_list_other_user_with_dataentry_role(self): request = self.factory.get('/') response = self.view(request) alice_data = {'username': '******', 'email': '*****@*****.**'} alice_profile = self._create_user_profile(alice_data) DataEntryRole.add(alice_profile.user, self.xform) self.assertTrue( DataEntryRole.user_has_role(alice_profile.user, self.xform) ) auth = DigestAuth('alice', 'bobbob') request.META.update(auth(request.META, response)) response = self.view(request) self.assertEqual(response.status_code, 200) path = os.path.join( os.path.dirname(__file__), '..', 'fixtures', 'formList.xml') with open(path) as f: form_list_xml = f.read().strip() data = {"hash": self.xform.hash, "pk": self.xform.pk} content = response.render().content self.assertEqual(content, form_list_xml % data) self.assertTrue(response.has_header('X-OpenRosa-Version')) self.assertTrue( response.has_header('X-OpenRosa-Accept-Content-Length')) self.assertTrue(response.has_header('Date')) self.assertEqual(response['Content-Type'], 'text/xml; charset=utf-8')
def test_retrieve_xform_manifest_linked_form(self): # for linked forms check if manifest media download url for csv # has a group_delimiter param data_type = 'media' data_value = 'xform {} transportation'.format(self.xform.pk) media = self._add_form_metadata(self.xform, data_type, data_value) self.view = XFormListViewSet.as_view({ "get": "manifest" }) # sign in bob request = self.factory.head('/') auth_response = self.view(request, pk=self.xform.pk) auth = DigestAuth('bob', 'bobbob') # set up bob's request request = self.factory.get('/xformsManifest') request.META.update(auth(request.META, auth_response)) # make request response = self.view(request, pk=self.xform.pk, format='csv') # test manifest_media_url = "%s?%s=%s" % (media.data['media_url'], GROUP_DELIMETER_TAG, ExportBuilder.GROUP_DELIMITER_DOT) self.assertEqual(manifest_media_url, response.data[0]['downloadUrl'])
def test_submission_to_require_auth_with_perm(self): """ Test submission to a private form by non-owner is forbidden. TODO send authentication challenge when xform.require_auth is set. This is non-trivial because we do not know the xform until we have parsed the XML. """ raise SkipTest self.xform.require_auth = True self.xform.save() self.xform.reload() self.assertTrue(self.xform.require_auth) # create a new user username = '******' alice = self._create_user(username, username) # assign report perms to user assign_perm('report_xform', alice, self.xform) auth = DigestAuth(username, username) xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../fixtures/tutorial/instances/tutorial_2012-06-27_11-27-53.xml") self._make_submission(xml_submission_file_path, auth=auth) self.assertEqual(self.response.status_code, 201)
def test_retrieve_xform_manifest(self): self._load_metadata(self.xform) self.view = XFormListViewSet.as_view( { "get": "manifest", "head": "manifest" } ) request = self.factory.head('/') response = self.view(request, pk=self.xform.pk) auth = DigestAuth('bob', 'bobbob') request = self.factory.get('/') request.META.update(auth(request.META, response)) response = self.view(request, pk=self.xform.pk) self.assertEqual(response.status_code, 200) manifest_xml = """<?xml version="1.0" encoding="utf-8"?> <manifest xmlns="http://openrosa.org/xforms/xformsManifest"><mediaFile><filename>screenshot.png</filename><hash>%(hash)s</hash><downloadUrl>http://testserver/bob/xformsMedia/%(xform)s/%(pk)s.png</downloadUrl></mediaFile></manifest>""" # noqa data = { "hash": self.metadata.hash, "pk": self.metadata.pk, "xform": self.xform.pk } content = response.render().content.decode('utf-8').strip() self.assertEqual(content, manifest_xml % data) self.assertTrue(response.has_header('X-OpenRosa-Version')) self.assertTrue( response.has_header('X-OpenRosa-Accept-Content-Length')) self.assertTrue(response.has_header('Date')) self.assertEqual(response['Content-Type'], 'text/xml; charset=utf-8')
def test_view_submission_list(self): self._publish_xml_form() self._make_submissions() params = {'formId': self.xform.id_string} request = self.factory.get(self._submission_list_url, params) response = view_submission_list(request, self.user.username) self.assertEqual(response.status_code, 401) auth = DigestAuth(self.login_username, self.login_password) request.META.update(auth(request.META, response)) response = view_submission_list(request, self.user.username) self.assertEqual(response.status_code, 200) submission_list_path = os.path.join( self.this_directory, 'fixtures', 'transportation', 'view', 'submissionList.xml') instances = ordered_instances(self.xform) self.assertEqual(instances.count(), NUM_INSTANCES) last_index = instances[instances.count() - 1].pk with open(submission_list_path, encoding='utf-8') as f: expected_submission_list = f.read() expected_submission_list = \ expected_submission_list.replace( '{{resumptionCursor}}', '%s' % last_index) self.assertEqual(response.content.decode('utf-8'), expected_submission_list)
def test_post_submission_authenticated_bad_json(self): path = os.path.join( os.path.dirname(os.path.abspath(__file__)), '..', 'fixtures', 'transport_submission_bad.json') with open(path) as f: data = json.loads(f.read()) request = self.factory.post('/submission', data, format='json') response = self.view(request) self.assertEqual(response.status_code, 401) request = self.factory.post('/submission', data, format='json') auth = DigestAuth('bob', 'bobbob') request.META.update(auth(request.META, response)) response = self.view(request) rendered_response = response.render() self.assertTrue('error' in rendered_response.data) self.assertTrue( rendered_response.data['error'].startswith( 'Received empty submission' ) ) self.assertTrue(rendered_response.status_code == 400) self.assertTrue(rendered_response.has_header('X-OpenRosa-Version')) self.assertTrue( rendered_response.has_header('X-OpenRosa-Accept-Content-Length')) self.assertTrue(rendered_response.has_header('Date')) self.assertEqual(rendered_response['Content-Type'], 'application/json') self.assertEqual(rendered_response['Location'], 'http://testserver/submission')
def test_submission_to_require_auth_anon(self): """ test submission to a private form by non-owner without perm is forbidden. """ view = XFormViewSet.as_view({ 'patch': 'partial_update' }) data = {'require_auth': True} self.assertFalse(self.xform.require_auth) request = self.factory.patch('/', data=data, **{ 'HTTP_AUTHORIZATION': 'Token %s' % self.user.auth_token}) view(request, pk=self.xform.id) self.xform.reload() self.assertTrue(self.xform.require_auth) xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../fixtures/tutorial/instances/tutorial_2012-06-27_11-27-53.xml" ) # create a new user username = '******' self._create_user(username, username) self._make_submission(xml_submission_file_path, auth=DigestAuth('alice', 'alice')) self.assertEqual(self.response.status_code, 403)
def _make_submissions(self, username=None, add_uuid=False, should_store=True): """Make test fixture submissions to current xform. :param username: submit under this username, default None. :param add_uuid: add UUID to submission, default False. :param should_store: should submissions be save, default True. """ paths = [ os.path.join(self.main_directory, 'fixtures', 'transportation', 'instances', s, s + '.xml') for s in self.surveys ] pre_count = Instance.objects.count() xform_pre_count = self.xform.instances.count() auth = DigestAuth(self.profile_data['username'], self.profile_data['password1']) for path in paths: self._make_submission(path, username, add_uuid, auth=auth) post_count = pre_count + len(self.surveys) if should_store\ else pre_count xform_post_count = xform_pre_count + len(self.surveys) \ if should_store else xform_pre_count self.assertEqual(Instance.objects.count(), post_count) self.assertEqual(self.xform.instances.count(), xform_post_count) xform = XForm.objects.get(pk=self.xform.pk) self.assertEqual(xform.num_of_submissions, xform_post_count) self.assertEqual(xform.user.profile.num_of_submissions, xform_post_count)
def test_view_submission_list_w_soft_deleted_submission(self): view = BriefcaseViewset.as_view({'get': 'list'}) self._publish_xml_form() self._make_submissions() uuid = 'f3d8dc65-91a6-4d0f-9e97-802128083390' # soft delete submission instance = Instance.objects.filter(uuid=uuid).first() instance.set_deleted(deleted_at=timezone.now()) instance.save() request = self.factory.get( self._submission_list_url, data={'formId': self.xform.id_string}) response = view(request, username=self.user.username) self.assertEqual(response.status_code, 401) auth = DigestAuth(self.login_username, self.login_password) request.META.update(auth(request.META, response)) response = view(request, username=self.user.username) self.assertEqual(response.status_code, 200) # check that number of instances returned by response is equal to # number of instances that have not been soft deleted self.assertEqual( response.data.get('instances').count(), Instance.objects.filter( xform=self.xform, deleted_at__isnull=True).count() )
def test_submission_to_require_auth_with_perm(self): """ test submission to a private form by non-owner is forbidden. TODO send authentication challenge when xform.require_auth is set. This is non-trivial because we do not know the xform until we have parsed the XML. """ raise SkipTest view = XFormViewSet.as_view({ 'patch': 'partial_update' }) data = {'require_auth': True} self.assertFalse(self.xform.require_auth) request = self.factory.patch('/', data=data, **{ 'HTTP_AUTHORIZATION': 'Token %s' % self.user.auth_token}) view(request, pk=self.xform.id) self.xform.reload() self.assertTrue(self.xform.require_auth) # create a new user username = '******' alice = self._create_user(username, username) # assign report perms to user assign_perm('report_xform', alice, self.xform) auth = DigestAuth(username, username) xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../fixtures/tutorial/instances/tutorial_2012-06-27_11-27-53.xml" ) self._make_submission(xml_submission_file_path, auth=auth) self.assertEqual(self.response.status_code, 201)
def test_view_downloadSubmission_multiple_nodes(self, mock_get_object): view = BriefcaseViewset.as_view({'get': 'retrieve'}) self._publish_xml_form() self.maxDiff = None self._submit_transport_instance_w_attachment() instanceId = u'5b2cc313-fc09-437e-8149-fcd32f695d41' instance = Instance.objects.get(uuid=instanceId) instance.xml = u'<?xml version=\'1.0\' ?><transportation id="transportation_2011_07_25"><transport><available_transportation_types_to_referral_facility>none</available_transportation_types_to_referral_facility><available_transportation_types_to_referral_facility>none</available_transportation_types_to_referral_facility><loop_over_transport_types_frequency><ambulance /><bicycle /><boat_canoe /><bus /><donkey_mule_cart /><keke_pepe /><lorry /><motorbike /><taxi /><other /></loop_over_transport_types_frequency></transport><meta><instanceID>uuid:5b2cc313-fc09-437e-8149-fcd32f695d41</instanceID></meta></transportation>\n' # noqa mock_get_object.return_value = instance formId = u'%(formId)s[@version=null and @uiVersion=null]/' \ u'%(formId)s[@key=uuid:%(instanceId)s]' % { 'formId': self.xform.id_string, 'instanceId': instanceId} params = {'formId': formId} auth = DigestAuth(self.login_username, self.login_password) request = self.factory.get( self._download_submission_url, data=params) response = view(request, username=self.user.username) self.assertEqual(response.status_code, 401) request.META.update(auth(request.META, response)) response = view(request, username=self.user.username) text = "uuid:%s" % instanceId download_submission_path = os.path.join( self.main_directory, 'fixtures', 'transportation', 'view', 'downloadSubmission.xml') with codecs.open(download_submission_path, encoding='utf-8') as f: text = f.read() for var in ((u'{{submissionDate}}', instance.date_created.isoformat()), (u'{{form_id}}', str(self.xform.id))): text = text.replace(*var) self.assertContains(response, instanceId, status_code=200)
def test_fails_authentication_past_odk_token_expiry(self): """ Test that a Digest authenticated request using an ODK Token that has expired is not authorized """ s = self.surveys[0] xml_submission_file_path = os.path.join( self.this_directory, 'fixtures', 'transportation', 'instances', s, s + '.xml' ) self._set_require_auth() # Set email for user self.user.email = '*****@*****.**' self.user.save() odk_token = ODKToken.objects.create(user=self.user) # Set expiry date of the token to the past odk_token.expires = timezone.now() - timedelta(days=400) odk_token.save() # The value odk_token.key is hashed we need to have the raw_key # In order to authenticate with DigestAuth fernet = Fernet(getattr(settings, 'ODK_TOKEN_FERNET_KEY')) raw_key = fernet.decrypt(odk_token.key.encode('utf-8')).decode('utf-8') auth = DigestAuth(self.user.email, raw_key) self._make_submission(xml_submission_file_path, add_uuid=True, auth=auth) self.assertEqual(self.response.status_code, 401)
def test_remongo_with_username_id_string(self): self._publish_transportation_form() # submit 1 instances s = self.surveys[0] self._make_submission(os.path.join(self.this_directory, 'fixtures', 'transportation', 'instances', s, s + '.xml')) # publish and submit for a different user self._logout() self._create_user_and_login("harry", "harry") auth = DigestAuth("harry", "harry") self._publish_transportation_form() s = self.surveys[1] self._make_submission(os.path.join(self.this_directory, 'fixtures', 'transportation', 'instances', s, s + '.xml'), username="******", auth=auth) self.assertEqual(ParsedInstance.objects.count(), 2) # clear mongo settings.MONGO_DB.instances.drop() c = Command() c.handle(batchsize=3, username=self.user.username, id_string=self.xform.id_string) # mongo db should now have 2 records count = settings.MONGO_DB.instances.count() self.assertEqual(count, 1)
def test_view_submission_list(self): view = BriefcaseApi.as_view({'get': 'list'}) self._publish_xml_form() self._make_submissions() request = self.factory.get(self._submission_list_url, data={'formId': self.xform.id_string}) response = view(request, username=self.user.username) self.assertEqual(response.status_code, 401) auth = DigestAuth(self.login_username, self.login_password) request.META.update(auth(request.META, response)) response = view(request, username=self.user.username) self.assertEqual(response.status_code, 200) submission_list_path = os.path.join(self.main_directory, 'fixtures', 'transportation', 'view', 'submissionList.xml') instances = ordered_instances(self.xform) self.assertEqual(instances.count(), NUM_INSTANCES) last_index = instances[instances.count() - 1].pk with codecs.open(submission_list_path, 'rb', encoding='utf-8') as f: expected_submission_list = f.read() expected_submission_list = \ expected_submission_list.replace( '{{resumptionCursor}}', '%s' % last_index) self.assertContains(response, expected_submission_list)
def test_get_xform_list_other_user_with_no_role(self): request = self.factory.get('/') response = self.view(request) alice_data = { 'username': '******', 'password1': 'alicealice', 'password2': 'alicealice', 'email': '*****@*****.**', } alice_profile = self._create_user_profile(alice_data) self.assertFalse( alice_profile.user.has_perms([CAN_VIEW_XFORM], self.xform)) auth = DigestAuth('alice', 'alicealice') request.META.update(auth(request.META, response)) response = self.view(request) self.assertEqual(response.status_code, 200) content = response.render().content self.assertNotIn(self.xform.id_string, content) self.assertEqual( content, '<?xml version="1.0" encoding="utf-8"?>\n<xforms ' 'xmlns="http://openrosa.org/xforms/xformsList"></xforms>') self.assertTrue(response.has_header('X-OpenRosa-Version')) self.assertTrue( response.has_header('X-OpenRosa-Accept-Content-Length')) self.assertTrue(response.has_header('Date')) self.assertEqual(response['Content-Type'], 'text/xml; charset=utf-8')
def test_view_downloadSubmission(self): self._publish_xml_form() self.maxDiff = None self._submit_transport_instance_w_attachment() instanceId = u'5b2cc313-fc09-437e-8149-fcd32f695d41' instance = Instance.objects.get(uuid=instanceId) formId = u'%(formId)s[@version=null and @uiVersion=null]/' \ u'%(formId)s[@key=uuid:%(instanceId)s]' % { 'formId': self.xform.id_string, 'instanceId': instanceId} params = {'formId': formId} request = self.factory.get(self._download_submission_url, params) response = view_download_submission(request, self.user.username) self.assertEqual(response.status_code, 401) auth = DigestAuth(self.login_username, self.login_password) request.META.update(auth(request.META, response)) response = view_download_submission(request, self.user.username) text = "uuid:%s" % instanceId download_submission_path = os.path.join( self.this_directory, 'fixtures', 'transportation', 'view', 'downloadSubmission.xml') with open(download_submission_path, encoding='utf-8') as f: text = f.read() text = text.replace(u'{{submissionDate}}', instance.date_created.isoformat()) self.assertContains(response, instanceId, status_code=200) self.assertMultiLineEqual(response.content.decode('utf-8'), text)
def test_post_submission_authenticated(self): """ Test authenticated user can make a submission. """ s = self.surveys[0] media_file = "1335783522563.jpg" path = os.path.join(self.main_directory, 'fixtures', 'transportation', 'instances', s, media_file) with open(path, 'rb') as f: f = InMemoryUploadedFile(f, 'media_file', media_file, 'image/jpg', os.path.getsize(path), None) submission_path = os.path.join(self.main_directory, 'fixtures', 'transportation', 'instances', s, s + '.xml') with open(submission_path, 'rb') as sf: data = {'xml_submission_file': sf, 'media_file': f} request = self.factory.post('/submission', data) response = self.view(request) self.assertEqual(response.status_code, 401) auth = DigestAuth('bob', 'bobbob') request.META.update(auth(request.META, response)) response = self.view(request, username=self.user.username) self.assertContains(response, 'Successful submission', status_code=201) self.assertTrue(response.has_header('X-OpenRosa-Version')) self.assertTrue( response.has_header('X-OpenRosa-Accept-Content-Length')) self.assertTrue(response.has_header('Date')) self.assertEqual(response['Content-Type'], 'text/xml; charset=utf-8') self.assertEqual(response['Location'], 'http://testserver/submission')
def test_post_submission_authenticated_json(self): path = os.path.join( os.path.dirname(os.path.abspath(__file__)), '..', 'fixtures', 'transport_submission.json') with open(path, 'rb') as f: data = json.loads(f.read()) request = self.factory.post('/submission', data, format='json') response = self.view(request) self.assertEqual(response.status_code, 401) # redo the request since it were consumed request = self.factory.post('/submission', data, format='json') auth = DigestAuth('bob', 'bobbob') request.META.update(auth(request.META, response)) response = self.view(request) self.assertContains(response, 'Successful submission', status_code=201) self.assertTrue(response.has_header('X-OpenRosa-Version')) self.assertTrue( response.has_header('X-OpenRosa-Accept-Content-Length')) self.assertTrue(response.has_header('Date')) self.assertEqual(response['Content-Type'], 'application/json') self.assertEqual(response['Location'], 'http://testserver/submission')
def test_post_submission_uuid_other_user_username_not_provided(self): """ Test submission without formhub/uuid done by a different user who has no permission to the form fails. """ alice_data = {'username': '******', 'email': '*****@*****.**'} self._create_user_profile(alice_data) s = self.surveys[0] media_file = "1335783522563.jpg" path = os.path.join(self.main_directory, 'fixtures', 'transportation', 'instances', s, media_file) with open(path, 'rb') as f: f = InMemoryUploadedFile(f, 'media_file', media_file, 'image/jpg', os.path.getsize(path), None) path = os.path.join(self.main_directory, 'fixtures', 'transportation', 'instances', s, s + '.xml') path = self._add_uuid_to_submission_xml(path, self.xform) with open(path, 'rb') as sf: data = {'xml_submission_file': sf, 'media_file': f} request = self.factory.post('/submission', data) response = self.view(request) self.assertEqual(response.status_code, 401) auth = DigestAuth('alice', 'bobbob') request.META.update(auth(request.META, response)) response = self.view(request) self.assertEqual(response.status_code, 404)
def test_post_submission_uuid_other_user_username_not_provided(self): alice_data = { 'username': '******', 'password1': 'alicealice', 'password2': 'alicealice', 'email': '*****@*****.**', } self._create_user_profile(alice_data) s = self.surveys[0] media_file = "1335783522563.jpg" path = os.path.join(self.main_directory, 'fixtures', 'transportation', 'instances', s, media_file) with open(path, 'rb') as f: f = InMemoryUploadedFile(f, 'media_file', media_file, 'image/jpg', os.path.getsize(path), None) path = os.path.join( self.main_directory, 'fixtures', 'transportation', 'instances', s, s + '.xml') path = self._add_uuid_to_submission_xml(path, self.xform) with open(path, 'rb') as sf: data = {'xml_submission_file': sf, 'media_file': f} request = self.factory.post('/submission', data) response = self.view(request) self.assertEqual(response.status_code, 401) # rewind the file and redo the request since they were # consumed sf.seek(0) request = self.factory.post('/submission', data) auth = DigestAuth('alice', 'alicealice') request.META.update(auth(request.META, response)) response = self.view(request) self.assertEqual(response.status_code, 403)
def test_post_submission_authenticated_bad_json(self): """ Test authenticated user cannot make a badly formatted JSON submission. """ path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'fixtures', 'transport_submission_bad.json') with open(path, encoding='utf-8') as f: data = json.loads(f.read()) request = self.factory.post('/submission', data, format='json') response = self.view(request) self.assertEqual(response.status_code, 401) request = self.factory.post('/submission', data, format='json') auth = DigestAuth('bob', 'bobbob') request.META.update(auth(request.META, response)) response = self.view(request) self.assertContains(response, 'Received empty submission', status_code=400) self.assertTrue(response.has_header('X-OpenRosa-Version')) self.assertTrue( response.has_header('X-OpenRosa-Accept-Content-Length')) self.assertTrue(response.has_header('Date')) self.assertEqual(response['Content-Type'], 'application/json') self.assertEqual(response['Location'], 'http://testserver/submission')
def _make_submission_w_attachment(self, path, attachment_path): with open(path, encoding='utf-8') as f: data = {'xml_submission_file': f} if attachment_path is not None: if isinstance(attachment_path, list): for c in range(len(attachment_path)): data['media_file_{}'.format(c)] = open( attachment_path[c], 'rb') else: data['media_file'] = open( attachment_path, 'rb') url = '/%s/submission' % self.user.username auth = DigestAuth('bob', 'bob') self.factory = APIRequestFactory() request = self.factory.post(url, data) request.user = authenticate(username='******', password='******') self.response = submission(request, username=self.user.username) if auth and self.response.status_code == 401: request.META.update(auth(request.META, self.response)) self.response = submission(request, username=self.user.username)
def test_post_submission_require_auth(self): """ Test require_auth on submission post. """ self.user.profile.require_auth = True self.user.profile.save() submission = self.surveys[0] submission_path = os.path.join(self.main_directory, 'fixtures', 'transportation', 'instances', submission, submission + '.xml') with open(submission_path, 'rb') as submission_file: data = {'xml_submission_file': submission_file} request = self.factory.post('/submission', data) response = self.view(request) self.assertEqual(response.status_code, 401) response = self.view(request, username=self.user.username) self.assertEqual(response.status_code, 401) auth = DigestAuth('bob', 'bobbob') request.META.update(auth(request.META, response)) response = self.view(request, username=self.user.username) self.assertContains(response, 'Successful submission', status_code=201) self.assertTrue(response.has_header('X-OpenRosa-Version')) self.assertTrue( response.has_header('X-OpenRosa-Accept-Content-Length')) self.assertTrue(response.has_header('Date')) self.assertEqual(response['Content-Type'], 'text/xml; charset=utf-8') self.assertEqual(response['Location'], 'http://testserver/submission')
def test_get_xform_anonymous_user_xform_require_auth(self): self.view = XFormListViewSet.as_view( { "get": "retrieve", "head": "retrieve" } ) request = self.factory.head('/') response = self.view(request, username='******', pk=self.xform.pk) # no authentication prompted self.assertEqual(response.status_code, 200) self.assertFalse(self.xform.require_auth) self.assertFalse(self.user.profile.require_auth) self.xform.require_auth = True self.xform.save() request = self.factory.head('/') response = self.view(request, username='******', pk=self.xform.pk) # authentication prompted self.assertEqual(response.status_code, 401) auth = DigestAuth('bob', 'bobbob') request = self.factory.get('/') request.META.update(auth(request.META, response)) response = self.view(request, username='******', pk=self.xform.pk) # success with authentication self.assertEqual(response.status_code, 200)
def test_view_download_submission_other_user(self): view = BriefcaseApi.as_view({'get': 'retrieve'}) self._publish_xml_form() self.maxDiff = None self._submit_transport_instance_w_attachment() instanceId = '5b2cc313-fc09-437e-8149-fcd32f695d41' formId = '%(formId)s[@version=null and @uiVersion=null]/' \ '%(formId)s[@key=uuid:%(instanceId)s]' % { 'formId': self.xform.id_string, 'instanceId': instanceId} params = {'formId': formId} # alice cannot view bob's downloadSubmission alice_data = { 'username': '******', 'password1': 'alicealice', 'password2': 'alicealice', 'email': '*****@*****.**', } self._create_user_profile(alice_data) auth = DigestAuth('alice', 'alicealice') url = self._download_submission_url # aliasing long name request = self.factory.get(url, data=params) response = view(request, username=self.user.username) self.assertEqual(response.status_code, 401) # Rewind the file to avoid the xml parser to get an empty string # and throw and parsing error request = request = self.factory.get(url, data=params) request.META.update(auth(request.META, response)) response = view(request, username=self.user.username) self.assertEqual(response.status_code, 404)
def test_retrieve_xform_xml(self): self.view = XFormListViewSet.as_view({ "get": "retrieve" }) request = self.factory.head('/') response = self.view(request, pk=self.xform.pk) auth = DigestAuth('bob', 'bobbob') request = self.factory.get('/') request.META.update(auth(request.META, response)) response = self.view(request, pk=self.xform.pk) self.assertEqual(response.status_code, 200) path = os.path.join( os.path.dirname(__file__), '..', 'fixtures', 'Transportation Form.xml') with open(path) as f: form_xml = f.read().strip() data = {"form_uuid": self.xform.uuid} content = response.render().content.strip() content = content.replace( self.xform.version, u"20141112071722") self.assertEqual(content, form_xml % data) self.assertTrue(response.has_header('X-OpenRosa-Version')) self.assertTrue( response.has_header('X-OpenRosa-Accept-Content-Length')) self.assertTrue(response.has_header('Date')) self.assertEqual(response['Content-Type'], 'text/xml; charset=utf-8')
def test_submission_with_instance_id_on_root_node(self): view = XFormSubmissionApi.as_view({'post': 'create'}) self._publish_xml_form() message = "Successful submission." instanceId = '5b2cc313-fc09-437e-8149-fcd32f695d41' self.assertRaises(Instance.DoesNotExist, Instance.objects.get, uuid=instanceId) submission_path = os.path.join(self.main_directory, 'fixtures', 'transportation', 'view', 'submission.xml') count = Instance.objects.count() with codecs.open(submission_path, encoding='utf-8') as f: post_data = {'xml_submission_file': f} request = self.factory.post(self._submission_list_url, post_data) response = view(request) self.assertEqual(response.status_code, 401) auth = DigestAuth('bob', 'bobbob') # Rewind the file to avoid the xml parser to get an empty string # and throw and parsing error f.seek(0) # Create a new requests to avoid request.FILES to be empty request = self.factory.post(self._submission_list_url, post_data) request.META.update(auth(request.META, response)) response = view(request, username=self.user.username) self.assertContains(response, message, status_code=201) self.assertContains(response, instanceId, status_code=201) self.assertEqual(Instance.objects.count(), count + 1)
def test_json_stores_user_attribute(self, mock_time): mock_time.return_value = datetime.utcnow().replace(tzinfo=utc) self._publish_transportation_form() # make account require phone auth self.user.profile.require_auth = True self.user.profile.save() # submit instance with a request user path = os.path.join( self.this_directory, 'fixtures', 'transportation', 'instances', self.surveys[0], self.surveys[0] + '.xml') auth = DigestAuth(self.login_username, self.login_password) self._make_submission(path, auth=auth) instances = Instance.objects.filter(xform_id=self.xform).all() self.assertTrue(len(instances) > 0) for instance in instances: self.assertEqual(instance.json[SUBMITTED_BY], 'bob') # check that the parsed instance's to_dict_for_mongo also contains # the _user key, which is what's used by the JSON REST service pi = ParsedInstance.objects.get(instance=instance) self.assertEqual(pi.to_dict_for_mongo()[SUBMITTED_BY], 'bob')
def test_editor_role_submission_when_requires_auth(self): self._publish_xls_form_to_project() paths = [ os.path.join(self.main_directory, 'fixtures', 'transportation', 'instances_w_uuid', s, s + '.xml') for s in [ 'transport_2011-07-25_19-05-36', 'transport_2011-07-25_19-05-36-edited' ] ] self._make_submission(paths[0]) self.user.profile.require_auth = True self.user.profile.save() alice_data = { 'username': '******', 'email': '*****@*****.**', 'password1': 'alice', 'password2': 'alice' } self._login_user_and_profile(extra_post_data=alice_data) auth = DigestAuth('alice', 'alice') self._make_submission(paths[1], username='******', auth=auth) self.assertEqual(self.response.status_code, 403) role.EditorRole.add(self.user, self.xform) self._make_submission(paths[1], username='******', auth=auth) self.assertEqual(self.response.status_code, 201)