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(self):
        self._load_metadata(self.xform)
        self.view = XFormListApi.as_view({"get": "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.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_post_submission_authenticated(self):
     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)
             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_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)
예제 #5
0
    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)
    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)
예제 #7
0
    def test_retrieve_xform_xml(self):
        self.view = XFormListViewSet.as_view(
            {
                "get": "retrieve",
                "head": "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, encoding='utf-8') as f:
            form_xml = f.read().strip()
            data = {"form_uuid": self.xform.uuid}
            content = response.render().content.decode('utf-8').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')
예제 #8
0
    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_get_xform_list_xform_pk_filter(self):
        self.user.profile.require_auth = True
        self.user.profile.save()
        request = self.factory.get('/')
        response = self.view(request,
                             username=self.user.username,
                             xform_pk=self.xform.pk)
        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,
                             xform_pk=self.xform.pk)
        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')
예제 #10
0
    def test_view_submission_list_w_deleted_submission(self):
        self._publish_xml_form()
        self._make_submissions()
        uuid = 'f3d8dc65-91a6-4d0f-9e97-802128083390'
        Instance.objects.filter(uuid=uuid).order_by('id').delete()
        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-4.xml')
        instances = ordered_instances(self.xform)

        self.assertEqual(instances.count(), NUM_INSTANCES - 1)

        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.assertEqual(response.content, expected_submission_list)

        formId = u'%(formId)s[@version=null and @uiVersion=null]/' \
                 u'%(formId)s[@key=uuid:%(instanceId)s]' % {
                     'formId': self.xform.id_string,
                     'instanceId': uuid}
        params = {'formId': formId}
        response = self.client.get(self._download_submission_url, data=params)
        self.assertTrue(response.status_code, 404)
예제 #11
0
    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 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.assertEqual(response.content, expected_submission_list)
    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)
예제 #13
0
    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()

        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
        self.assertEqual(Instance.objects.count(), post_count)
        self.assertEqual(self.xform.instances.count(), post_count)
        xform = XForm.objects.get(pk=self.xform.pk)
        self.assertEqual(xform.num_of_submissions, post_count)
        self.assertEqual(xform.user.profile.num_of_submissions, post_count)
 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()
         text = text.replace(u'{{submissionDate}}',
                             instance.date_created.isoformat())
         self.assertContains(response, instanceId, status_code=200)
예제 #15
0
 def test_view_downloadSubmission(self):
     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)
     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)
         self.assertMultiLineEqual(response.content.decode('utf-8'), text)
예제 #16
0
    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_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())
예제 #18
0
    def test_get_xform_list_of_logged_in_user_with_username_param(self):
        # publish 2 forms as bob
        xls_path = os.path.join(settings.PROJECT_ROOT, "apps", "main", "tests",
                                "fixtures", "tutorial.xls")
        self._publish_xls_form_to_project(xlsform_path=xls_path)

        xls_file_path = os.path.join(settings.PROJECT_ROOT, "apps", "logger",
                                     "fixtures",
                                     "external_choice_form_v1.xlsx")
        self._publish_xls_form_to_project(xlsform_path=xls_file_path)

        # change one of bob's forms to public
        xform = self.user.xforms.first()
        xform.shared = True
        xform.save()
        xform_id_string = xform.id_string

        # check that bob still has 2 private forms
        self.assertEqual(self.user.xforms.filter(shared=False).count(), 2)

        request = self.factory.get('/')
        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='******')
        # check that bob's request is succesful and it returns both public and
        # private forms that belong to bob
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 3)

        alice_data = {
            'username': '******',
            'email': '*****@*****.**',
        }
        self._login_user_and_profile(extra_post_data=alice_data)
        request = self.factory.get('/')
        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, username='******')
        # check that alice's request is succesful and it returns public forms
        # owned by bob
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 1)
        self.assertEqual(response.data[0].get('formID'), xform_id_string)
예제 #19
0
    def test_retrieve_xform_media_linked_xform(self):
        data_type = 'media'
        data_value = 'xform {} transportation'.format(self.xform.pk)
        self._add_form_metadata(self.xform, data_type, data_value)
        self._make_submissions()
        self.xform.refresh_from_db()

        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)
        self.assertEqual(response.data[0]['filename'], 'transportation.csv')
        self.assertEqual(
            response.data[0]['hash'],
            'md5:%s' % md5(self.xform.last_submission_time.isoformat().encode(
                'utf-8')).hexdigest())

        self.view = XFormListViewSet.as_view({"get": "media", "head": "media"})
        request = self.factory.get('/')
        response = self.view(request,
                             pk=self.xform.pk,
                             metadata=self.metadata.pk,
                             format='csv')
        self.assertEqual(response.status_code, 401)

        request = self.factory.head('/')
        response = self.view(request,
                             pk=self.xform.pk,
                             metadata=self.metadata.pk,
                             format='csv')
        auth = DigestAuth('bob', 'bobbob')
        request = self.factory.get('/')
        request.META.update(auth(request.META, response))
        response = self.view(request,
                             pk=self.xform.pk,
                             metadata=self.metadata.pk,
                             format='csv')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response['Content-Disposition'],
                         'attachment; filename=transportation.csv')
예제 #20
0
 def test_returns_200_for_owner(self):
     self._set_require_auth()
     request = self.factory.get('/')
     auth = DigestAuth('bob', 'bob')
     response = formList(request, self.user.username)
     request.META.update(auth(request.META, response))
     response = formList(request, self.user.username)
     self.assertEqual(response.status_code, 200)
예제 #21
0
    def _make_submission(self,
                         path,
                         username=None,
                         add_uuid=False,
                         forced_submission_time=None,
                         auth=None,
                         client=None):
        # store temporary file with dynamic uuid

        self.factory = APIRequestFactory()
        if auth is None:
            auth = DigestAuth('bob', 'bob')

        tmp_file = None

        if add_uuid:
            tmp_file = NamedTemporaryFile(delete=False)
            split_xml = None

            with open(path) as _file:
                split_xml = re.split(r'(<transport>)', _file.read())

            split_xml[1:1] = [
                '<formhub><uuid>%s</uuid></formhub>' % self.xform.uuid
            ]
            tmp_file.write(''.join(split_xml))
            path = tmp_file.name
            tmp_file.close()

        with open(path) as f:
            post_data = {'xml_submission_file': f}

            if username is None:
                username = self.user.username

            url_prefix = '%s/' % username if username else ''
            url = '/%ssubmission' % url_prefix

            request = self.factory.post(url, post_data)
            request.user = authenticate(username=auth.username,
                                        password=auth.password)

            self.response = submission(request, username=username)

            if auth and self.response.status_code == 401:
                request.META.update(auth(request.META, self.response))
                self.response = submission(request, username=username)

        if forced_submission_time:
            instance = Instance.objects.order_by('-pk').all()[0]
            instance.date_created = forced_submission_time
            instance.json = instance.get_full_dict()
            instance.save()
            instance.parsed_instance.save()

        # remove temporary file if stored
        if add_uuid:
            os.unlink(tmp_file.name)
예제 #22
0
    def test_retrieve_form_using_pk(self):
        """
        Test formList endpoint utilizing primary key is able to retrieve
        a form properly
        """
        # Bob submit forms
        xls_path = os.path.join(settings.PROJECT_ROOT, "apps", "main", "tests",
                                "fixtures", "tutorial.xls")
        self._publish_xls_form_to_project(xlsform_path=xls_path)

        xls_file_path = os.path.join(settings.PROJECT_ROOT, "apps", "logger",
                                     "fixtures",
                                     "external_choice_form_v1.xlsx")
        self._publish_xls_form_to_project(xlsform_path=xls_file_path)

        # Set require auth to true for form owner
        self.user.profile.require_auth = True
        self.user.profile.save()

        # Ensure that anonymous users do not have access to private forms
        self.xform.shared = False
        self.xform.save()
        request = self.factory.get(f'/enketo/{self.xform.pk}/formList')
        response = self.view(request, xform_pk=self.xform.pk)
        self.assertEqual(response.status_code, 401)

        # Set require auth to false for form owner
        self.user.profile.require_auth = False
        self.user.profile.save()

        # make form public
        self.xform.shared = True
        self.xform.save()

        # Ensure logged in users have access to the form
        alice_data = {
            'username': '******',
            'email': '*****@*****.**',
            'password1': 'alice',
            'password2': 'alice'
        }
        self._create_user_profile(alice_data)

        auth = DigestAuth('alice', 'alice')
        request = self.factory.get(f'/enketo/{self.xform.pk}/formList')
        request.META.update(auth(request.META, response))
        response = self.view(request, xform_pk=self.xform.pk)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 1)
        self.assertEqual(response.data[0]['formID'], self.xform.id_string)

        # Ensure anonymous users have access to public forms
        # when require_auth is False
        request = self.factory.get(f'/enketo/{self.xform.pk}/formList')
        response = self.view(request, xform_pk=self.xform.pk)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 1)
        self.assertEqual(response.data[0]['formID'], self.xform.id_string)
    def test_user_updates_email_wrong_password(self):
        view = ConnectViewSet.as_view(
            {'get': 'list'}, authentication_classes=(DigestAuthentication, ))

        auth = DigestAuth('*****@*****.**', 'bob')
        request = self._get_request_session_with_auth(view, auth)

        response = view(request)
        self.assertEqual(response.status_code, 401)
        self.assertEqual(response.data['detail'], u"Invalid username/password")
 def test_returns_200_for_authenticated_non_owner(self):
     self._set_require_auth()
     credentials = ('alice', 'alice',)
     self._create_user(*credentials)
     auth = DigestAuth('alice', 'alice')
     request = self.factory.get('/')
     response = formList(request, self.user.username)
     request.META.update(auth(request.META, response))
     response = formList(request, self.user.username)
     self.assertEqual(response.status_code, 200)
예제 #25
0
    def _make_submission(
        self,
        path: str,
        username: str = None,
        add_uuid: bool = False,
        forced_submission_time: bool = None,
        auth: Union[DigestAuth, bool] = None,
        media_file: 'io.BufferedReader' = None,
    ):
        """
        Pass `auth=False` for an anonymous request, or omit `auth` to perform
        the submission as 'bob'
        """
        # store temporary file with dynamic uuid
        self.factory = APIRequestFactory()
        if auth is None:
            auth = DigestAuth('bob', 'bob')

        if add_uuid:
            path = self._add_uuid_to_submission_xml(path, self.xform)

        with open(path, 'rb') as f:
            post_data = {'xml_submission_file': f}

            if media_file is not None:
                post_data['media_file'] = media_file

            if username is None:
                username = self.user.username

            url_prefix = f'{username}/' if username else ''
            url = f'/{url_prefix}submission'
            request = self.factory.post(url, post_data)
            if auth:
                request.user = authenticate(username=auth.username,
                                            password=auth.password)
            self.response = None  # Reset in case error in viewset below
            self.response = self.submission_view(request, username=username)
            if auth and self.response.status_code == 401:
                f.seek(0)
                request = self.factory.post(url, post_data)
                request.META.update(auth(request.META, self.response))
                self.response = self.submission_view(request,
                                                     username=username)

        if forced_submission_time:
            instance = Instance.objects.order_by('-pk').all()[0]
            instance.date_created = forced_submission_time
            instance.save()
            instance.parsed_instance.save()

        # remove temporary file if stored
        if add_uuid:
            os.unlink(path)
    def test_fail_authenticated_submissions_to_wrong_account(self):
        username = '******'
        # set require_auth b4 we switch user
        self._set_require_auth()
        self._create_user_and_login(username=username, password=username)
        self._set_require_auth()
        s = self.surveys[0]
        xml_submission_file_path = os.path.join(
            self.this_directory, 'fixtures',
            'transportation', 'instances', s, s + '.xml'
        )

        self._make_submission(xml_submission_file_path, add_uuid=True,
                              auth=DigestAuth('alice', 'alice'))
        # Authentication required
        self.assertEqual(self.response.status_code, 401)
        auth = DigestAuth('dennis', 'dennis')
        with self.assertRaises(Http404):
            self._make_submission(xml_submission_file_path, add_uuid=True,
                                  auth=auth)
예제 #27
0
    def test_post_submission_json_without_submission_key(self):
        data = {"id": "transportation_2011_07_25"}
        request = self.factory.post('/submission', data, format='json')
        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)
        self.assertContains(response,
                            'No submission key provided.',
                            status_code=400)
    def test_user_has_no_profile_bug(self):
        alice = User.objects.create(username='******')
        alice.set_password('alice')
        update_partial_digests(alice, "alice")
        view = ConnectViewSet.as_view(
            {'get': 'list'}, authentication_classes=(DigestAuthentication, ))

        auth = DigestAuth('alice', 'alice')
        request = self._get_request_session_with_auth(view, auth)

        response = view(request)
        self.assertEqual(response.status_code, 200)
예제 #29
0
    def test_view_submission_list_num_entries(self):
        def get_last_index(xform, last_index=None):
            instances = ordered_instances(xform)
            if not last_index and instances.count():
                return instances[instances.count() - 1].pk
            elif last_index:
                instances = instances.filter(pk__gt=last_index)
                if instances.count():
                    return instances[instances.count() - 1].pk
                else:
                    return get_last_index(xform)
            return 0

        self._publish_xml_form()
        self._make_submissions()
        params = {'formId': self.xform.id_string}
        params['numEntries'] = 2
        instances = ordered_instances(self.xform)

        self.assertEqual(instances.count(), NUM_INSTANCES)

        last_index = instances[:2][1].pk
        last_expected_submission_list = ""
        for index in range(1, 5):
            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)

            if index > 2:
                last_index = get_last_index(self.xform, last_index)
            filename = 'submissionList-%s.xml' % index

            if index == 4:
                self.assertEqual(response.content.decode('utf-8'),
                                 last_expected_submission_list)
                continue
            # set cursor for second request
            params['cursor'] = last_index
            submission_list_path = os.path.join(self.this_directory,
                                                'fixtures', 'transportation',
                                                'view', filename)
            with open(submission_list_path, encoding='utf-8') as f:
                expected_submission_list = f.read()
                last_expected_submission_list = expected_submission_list = \
                    expected_submission_list.replace(
                        '{{resumptionCursor}}', '%s' % last_index)
                self.assertEqual(response.content.decode('utf-8'),
                                 expected_submission_list)
            last_index += 2
예제 #30
0
    def _make_submission(self,
                         path,
                         username=None,
                         add_uuid=False,
                         forced_submission_time=None,
                         client=None,
                         media_file=None,
                         auth=None):
        # store temporary file with dynamic uuid
        self.factory = APIRequestFactory()
        if auth is None:
            auth = DigestAuth(self.profile_data['username'],
                              self.profile_data['password1'])

        tmp_file = None

        if add_uuid:
            path = self._add_uuid_to_submission_xml(path, self.xform)
        with open(path) as f:
            post_data = {'xml_submission_file': f}

            if media_file is not None:
                if isinstance(media_file, list):
                    for c in range(len(media_file)):
                        post_data['media_file_{}'.format(c)] = media_file[c]
                else:
                    post_data['media_file'] = media_file

            if username is None:
                username = self.user.username

            url_prefix = '%s/' % username if username else ''
            url = '/%ssubmission' % url_prefix

            request = self.factory.post(url, post_data)
            request.user = authenticate(username=auth.username,
                                        password=auth.password)
            self.response = submission(request, username=username)

            if auth and self.response.status_code == 401:
                request.META.update(auth(request.META, self.response))
                self.response = submission(request, username=username)

        if forced_submission_time:
            instance = Instance.objects.order_by('-pk').all()[0]
            instance.date_created = forced_submission_time
            instance.save()
            instance.parsed_instance.save()

        # remove temporary file if stored
        if add_uuid:
            os.unlink(tmp_file.name)