def update(self, instance, validated_data): metadata = JsonField.to_json(validated_data.get('metadata')) if metadata is None: metadata = dict() owner = validated_data.get('organization') if self.partial and metadata: if not isinstance(instance.metadata, dict): instance.metadata = {} instance.metadata.update(metadata) validated_data['metadata'] = instance.metadata if self.partial and owner: # give the new owner permissions set_owners_permission(owner, instance) if is_organization(owner.profile): owners_team = get_organization_owners_team(owner.profile) members_team = get_organization_members_team(owner.profile) OwnerRole.add(owners_team, instance) ReadOnlyRole.add(members_team, instance) # clear cache safe_delete('{}{}'.format(PROJ_PERM_CACHE, instance.pk)) project = super(ProjectSerializer, self)\ .update(instance, validated_data) project.xform_set.exclude(shared=project.shared)\ .update(shared=project.shared, shared_data=project.shared) return instance
def add_xform_to_project(xform, project, creator): """Adds an xform to a project""" # remove xform from any previous relation to a project xform.projectxform_set.all().delete() # make new connection instance = ProjectXForm.objects.create(xform=xform, project=project, created_by=creator) instance.save() # check if the project is a public and make the form public if project.shared != xform.shared: xform.shared = project.shared xform.shared_data = project.shared xform.save() for perm in get_object_users_with_permissions(project): user = perm['user'] if user != creator: ReadOnlyRole.add(user, xform) else: OwnerRole.add(user, xform) return instance
def test_widget_permission_change(self): self._create_widget() alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(alice_data) data = { 'title': "Widget those", } OwnerRole.add(self.user, self.project) OwnerRole.add(self.user, self.xform) request = self.factory.patch('/', data=data, **self.extra) response = self.view(request, pk=self.widget.pk) self.assertEquals(response.status_code, 200) self.assertEquals(response.data['title'], 'Widget those') ReadOnlyRole.add(self.user, self.project) ReadOnlyRole.add(self.user, self.xform) request = self.factory.patch('/', data=data, **self.extra) response = self.view(request, pk=self.widget.pk) self.assertEquals(response.status_code, 200) self.assertEquals(response.data['title'], 'Widget those')
def test_get_xform_list_other_user_with_readonly_role(self): request = self.factory.get('/') response = self.view(request) alice_data = {'username': '******', 'email': '*****@*****.**'} alice_profile = self._create_user_profile(alice_data) ReadOnlyRole.add(alice_profile.user, self.xform) self.assertTrue( ReadOnlyRole.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) 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 update(self, instance, validated_data): metadata = JsonField.to_json(validated_data.get('metadata')) if metadata is None: metadata = dict() owner = validated_data.get('organization') if self.partial and metadata: if not isinstance(instance.metadata, dict): instance.metadata = {} instance.metadata.update(metadata) validated_data['metadata'] = instance.metadata if self.partial and owner: # give the new owner permissions set_owners_permission(owner, instance) if is_organization(owner.profile): owners_team = get_or_create_organization_owners_team( owner.profile) members_team = get_organization_members_team(owner.profile) OwnerRole.add(owners_team, instance) ReadOnlyRole.add(members_team, instance) # clear cache safe_delete('{}{}'.format(PROJ_PERM_CACHE, instance.pk)) project = super(ProjectSerializer, self)\ .update(instance, validated_data) project.xform_set.exclude(shared=project.shared)\ .update(shared=project.shared, shared_data=project.shared) return instance
def add_xform_to_project(xform, project, creator): """Adds an xform to a project""" # remove xform from any previous relation to a project xform.projectxform_set.all().delete() # make new connection instance = ProjectXForm.objects.create( xform=xform, project=project, created_by=creator) instance.save() # check if the project is a public and make the form public if project.shared != xform.shared: xform.shared = project.shared xform.shared_data = project.shared xform.save() for perm in get_object_users_with_permissions(project): user = perm['user'] if user != creator: ReadOnlyRole.add(user, xform) else: OwnerRole.add(user, xform) return instance
def test_project_share_inactive_user(self): # create project and publish form to project self._publish_xls_form_to_project() alice_data = {'username': '******', 'email': '*****@*****.**'} alice_profile = self._create_user_profile(alice_data) # set the user inactive self.assertTrue(alice_profile.user.is_active) alice_profile.user.is_active = False alice_profile.user.save() projectid = self.project.pk self.assertFalse(ReadOnlyRole.user_has_role(alice_profile.user, self.project)) data = {'username': '******', 'role': ReadOnlyRole.name} request = self.factory.put('/', data=data, **self.extra) view = ProjectViewSet.as_view({ 'put': 'share' }) response = view(request, pk=projectid) self.assertEqual(response.status_code, 400) self.assertEqual(response.data, {'username': [u'User is not active']}) self.assertFalse(ReadOnlyRole.user_has_role(alice_profile.user, self.project)) self.assertFalse(ReadOnlyRole.user_has_role(alice_profile.user, self.xform))
def test_project_share_readonly(self): # create project and publish form to project self._publish_xls_form_to_project() alice_data = {'username': '******', 'email': '*****@*****.**'} alice_profile = self._create_user_profile(alice_data) projectid = self.project.pk self.assertFalse(ReadOnlyRole.user_has_role(alice_profile.user, self.project)) data = {'username': '******', 'role': ReadOnlyRole.name} request = self.factory.put('/', data=data, **self.extra) view = ProjectViewSet.as_view({ 'put': 'share' }) response = view(request, pk=projectid) self.assertEqual(response.status_code, 204) self.assertTrue(ReadOnlyRole.user_has_role(alice_profile.user, self.project)) self.assertTrue(ReadOnlyRole.user_has_role(alice_profile.user, self.xform)) perms = role.get_object_users_with_permissions(self.project) for p in perms: user = p.get('user') if user == alice_profile.user: r = p.get('role') self.assertEquals(r, ReadOnlyRole.name)
def test_shares_project(self): """ Test that the ShareProjectSerializer shares the projects to users """ self._publish_xls_form_to_project() project = Project.objects.last() user_joe = self._create_user('joe', 'joe') self.assertFalse(ReadOnlyRole.user_has_role(user_joe, project)) data = { 'project': project.id, 'username': '******', 'role': ReadOnlyRole.name } serializer = ShareProjectSerializer(data=data) self.assertTrue(serializer.is_valid()) serializer.save() self.assertTrue(ReadOnlyRole.user_has_role(user_joe, project)) # Test that it can share to multiple users user_dave = self._create_user('dave', 'dave') user_jake = self._create_user('jake', 'jake') self.assertFalse(ReadOnlyRole.user_has_role(user_dave, project)) self.assertFalse(ReadOnlyRole.user_has_role(user_jake, project)) data = { 'project': project.id, 'username': '******', 'role': ReadOnlyRole.name } serializer = ShareProjectSerializer(data=data) self.assertTrue(serializer.is_valid()) serializer.save() self.assertTrue(ReadOnlyRole.user_has_role(user_dave, project)) self.assertTrue(ReadOnlyRole.user_has_role(user_jake, project)) # Test strips spaces between commas user_sam = self._create_user('sam', 'sam') user_joy = self._create_user('joy', 'joy') self.assertFalse(ReadOnlyRole.user_has_role(user_sam, project)) self.assertFalse(ReadOnlyRole.user_has_role(user_joy, project)) data = { 'project': project.id, 'username': '******', 'role': ReadOnlyRole.name } serializer = ShareProjectSerializer(data=data) self.assertTrue(serializer.is_valid()) serializer.save() self.assertTrue(ReadOnlyRole.user_has_role(user_sam, project)) self.assertTrue(ReadOnlyRole.user_has_role(user_joy, project))
def save(self, **kwargs): role = ROLES.get(self.role) if role and self.user and self.project: role.add(self.user, self.project) # add readonly role to forms under the project for px in self.project.projectxform_set.all(): ReadOnlyRole.add(self.user, px.xform)
def test_data_list_filter_by_user(self): view = DataViewSet.as_view({'get': 'list'}) formid = self.xform.pk bobs_data = { u'id': formid, u'id_string': u'transportation_2011_07_25', u'title': 'transportation_2011_07_25', u'description': 'transportation_2011_07_25', u'url': u'http://testserver/api/v1/data/%s' % formid } previous_user = self.user self._create_user_and_login('alice', 'alice') self.assertEqual(self.user.username, 'alice') self.assertNotEqual(previous_user, self.user) ReadOnlyRole.add(self.user, self.xform) # publish alice's form self._publish_transportation_form() self.extra = { 'HTTP_AUTHORIZATION': 'Token %s' % self.user.auth_token} formid = self.xform.pk alice_data = { u'id': formid, u'id_string': u'transportation_2011_07_25', u'title': 'transportation_2011_07_25', u'description': 'transportation_2011_07_25', u'url': u'http://testserver/api/v1/data/%s' % formid } request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, 200) # should be both bob's and alice's form self.assertEqual(sorted(response.data), sorted([bobs_data, alice_data])) # apply filter, see only bob's forms request = self.factory.get('/', data={'owner': 'bob'}, **self.extra) response = view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [bobs_data]) # apply filter, see only alice's forms request = self.factory.get('/', data={'owner': 'alice'}, **self.extra) response = view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [alice_data]) # apply filter, see a non existent user request = self.factory.get('/', data={'owner': 'noone'}, **self.extra) response = view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [])
def test_read_only_users_get_non_empty_formlist_using_preview_formlist( self, mock_send_mail): alice_data = { 'username': '******', 'email': '*****@*****.**', 'password1': 'alice', 'password2': 'alice' } alice_profile = self._create_user_profile(alice_data) self.assertFalse( ReadOnlyRole.user_has_role(alice_profile.user, self.project)) # share bob's project with alice data = { 'username': '******', 'role': ReadOnlyRole.name, 'email_msg': 'I have shared the project with you' } request = self.factory.post('/', data=data, **self.extra) share_view = ProjectViewSet.as_view({'post': 'share'}) projectid = self.project.pk response = share_view(request, pk=projectid) self.assertEqual(response.status_code, 204) self.assertTrue(mock_send_mail.called) self.assertTrue( ReadOnlyRole.user_has_role(alice_profile.user, self.project)) # check that she can authenticate successfully request = self.factory.get('/') response = self.view(request) self.assertEqual(response.status_code, 401) auth = DigestAuth('alice', 'alice') request.META.update(auth(request.META, response)) response = self.view(request, username='******') self.assertEqual(response.status_code, 200) # check that alice gets an empty response when requesting bob's # formlist self.assertEqual(response.data, []) # set endpoint to preview formList self.view = PreviewXFormListViewSet.as_view({"get": "list"}) request = self.factory.get('/') response = self.view(request) self.assertEqual(response.status_code, 401) self.assertNotEqual(response.data, []) auth = DigestAuth('alice', 'alice') request.META.update(auth(request.META, response)) response = self.view(request, username='******') self.assertEqual(response.status_code, 200) # check that alice does NOT get an empty response when requesting bob's # formlist when using the preview formlist endpoint self.assertNotEqual(response.data, [])
def test_widget_permission_create(self): alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(alice_data) view = WidgetViewSet.as_view({'post': 'create'}) data = { 'title': "Widget that", 'content_object': 'http://testserver/api/v1/forms/%s' % self.xform.pk, 'description': "Test widget", 'aggregation': "Sum", 'widget_type': "charts", 'view_type': "horizontal-bar", 'column': "age", 'group_by': '' } # to do: test random user with auth but no perms request = self.factory.post('/', data=json.dumps(data), content_type="application/json", **self.extra) response = view(request) self.assertEquals(response.status_code, 400) # owner OwnerRole.add(self.user, self.project) request = self.factory.post('/', data=json.dumps(data), content_type="application/json", **self.extra) response = view(request) self.assertEquals(response.status_code, 201) # readonly ReadOnlyRole.add(self.user, self.project) request = self.factory.post('/', data=json.dumps(data), content_type="application/json", **self.extra) response = view(request) self.assertEquals(response.status_code, 201) # dataentryonlyrole DataEntryOnlyRole.add(self.user, self.project) request = self.factory.post('/', data=json.dumps(data), content_type="application/json", **self.extra) response = view(request) self.assertEquals(response.status_code, 201)
def test_project_users_get_readonly_role_on_add_form(self): self._project_create() alice_data = {'username': '******', 'email': '*****@*****.**'} alice_profile = self._create_user_profile(alice_data) ReadOnlyRole.add(alice_profile.user, self.project) self.assertTrue(ReadOnlyRole.user_has_role(alice_profile.user, self.project)) self._publish_xls_form_to_project() self.assertTrue(ReadOnlyRole.user_has_role(alice_profile.user, self.xform)) self.assertFalse(OwnerRole.user_has_role(alice_profile.user, self.xform))
def test_project_users_get_readonly_role_on_add_form(self): self._project_create() alice_data = {'username': '******', 'email': '*****@*****.**'} alice_profile = self._create_user_profile(alice_data) ReadOnlyRole.add(alice_profile.user, self.project) self.assertTrue( ReadOnlyRole.user_has_role(alice_profile.user, self.project)) self._publish_xls_form_to_project() self.assertTrue( ReadOnlyRole.user_has_role(alice_profile.user, self.xform)) self.assertFalse( OwnerRole.user_has_role(alice_profile.user, self.xform))
def test_widget_permission_create(self): alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(alice_data) view = WidgetViewSet.as_view({ 'post': 'create' }) data = { 'title': "Widget that", 'content_object': 'http://testserver/api/v1/forms/%s' % self.xform.pk, 'description': "Test widget", 'aggregation': "Sum", 'widget_type': "charts", 'view_type': "horizontal-bar", 'column': "age", 'group_by': '' } # to do: test random user with auth but no perms request = self.factory.post('/', data=json.dumps(data), content_type="application/json", **self.extra) response = view(request) self.assertEquals(response.status_code, 400) # owner OwnerRole.add(self.user, self.project) request = self.factory.post('/', data=json.dumps(data), content_type="application/json", **self.extra) response = view(request) self.assertEquals(response.status_code, 201) # readonly ReadOnlyRole.add(self.user, self.project) request = self.factory.post('/', data=json.dumps(data), content_type="application/json", **self.extra) response = view(request) self.assertEquals(response.status_code, 201) # dataentryonlyrole DataEntryOnlyRole.add(self.user, self.project) request = self.factory.post('/', data=json.dumps(data), content_type="application/json", **self.extra) response = view(request) self.assertEquals(response.status_code, 201)
def set_project_perms_to_xform(xform, project): if project.shared != xform.shared: xform.shared = project.shared xform.shared_data = project.shared xform.save() for perm in get_object_users_with_permissions(project): user = perm["user"] if user != xform.created_by: ReadOnlyRole.add(user, xform) else: OwnerRole.add(user, xform)
def save(self, **kwargs): if self.remove: self.remove_user() else: role = ROLES.get(self.role) if role and self.user and self.project: role.add(self.user, self.project) # add readonly role to forms under the project for xform in self.project.xform_set.all(): ReadOnlyRole.add(self.user, xform)
def test_reassign_role(self): self._publish_transportation_form() alice = self._create_user('alice', 'alice') self.assertFalse(ManagerRole.has_role(alice, self.xform)) ManagerRole.add(alice, self.xform) self.assertTrue(ManagerRole.has_role(alice, self.xform)) ReadOnlyRole.add(alice, self.xform) self.assertFalse(ManagerRole.has_role(alice, self.xform)) self.assertTrue(ReadOnlyRole.has_role(alice, self.xform))
def test_form_list_filter_by_user(self): # publish bob's form self._publish_xls_form_to_project() previous_user = self.user alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(extra_post_data=alice_data) self.assertEqual(self.user.username, 'alice') self.assertNotEqual(previous_user, self.user) ReadOnlyRole.add(self.user, self.xform) view = XFormViewSet.as_view({ 'get': 'retrieve' }) request = self.factory.get('/', **self.extra) response = view(request, pk=self.xform.pk) bobs_form_data = response.data # publish alice's form self._publish_xls_form_to_project() request = self.factory.get('/', **self.extra) response = self.view(request) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(response.status_code, 200) # should be both bob's and alice's form self.assertEqual(sorted(response.data), sorted([bobs_form_data, self.form_data])) # apply filter, see only bob's forms request = self.factory.get('/', data={'owner': 'bob'}, **self.extra) response = self.view(request) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [bobs_form_data]) # apply filter, see only alice's forms request = self.factory.get('/', data={'owner': 'alice'}, **self.extra) response = self.view(request) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [self.form_data]) # apply filter, see a non existent user request = self.factory.get('/', data={'owner': 'noone'}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(response.data, [])
def test_form_list_filter_by_user(self): # publish bob's form self._publish_xls_form_to_project() previous_user = self.user alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(extra_post_data=alice_data) self.assertEqual(self.user.username, 'alice') self.assertNotEqual(previous_user, self.user) ReadOnlyRole.add(self.user, self.xform) view = XFormViewSet.as_view({'get': 'retrieve'}) request = self.factory.get('/', **self.extra) response = view(request, pk=self.xform.pk) bobs_form_data = response.data # publish alice's form self._publish_xls_form_to_project() request = self.factory.get('/', **self.extra) response = self.view(request) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(response.status_code, 200) # should be both bob's and alice's form self.assertEqual(sorted(response.data), sorted([bobs_form_data, self.form_data])) # apply filter, see only bob's forms request = self.factory.get('/', data={'owner': 'bob'}, **self.extra) response = self.view(request) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [bobs_form_data]) # apply filter, see only alice's forms request = self.factory.get('/', data={'owner': 'alice'}, **self.extra) response = self.view(request) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [self.form_data]) # apply filter, see a non existent user request = self.factory.get('/', data={'owner': 'noone'}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(response.data, [])
def test_data_list_filter_by_user(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) formid = self.xform.pk bobs_data = _data_list(formid)[0] previous_user = self.user self._create_user_and_login('alice', 'alice') self.assertEqual(self.user.username, 'alice') self.assertNotEqual(previous_user, self.user) ReadOnlyRole.add(self.user, self.xform) # publish alice's form self._publish_transportation_form() self.extra = { 'HTTP_AUTHORIZATION': 'Token %s' % self.user.auth_token} formid = self.xform.pk alice_data = _data_list(formid)[0] request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, 200) # should be both bob's and alice's form self.assertEqual(sorted(response.data), sorted([bobs_data, alice_data])) # apply filter, see only bob's forms request = self.factory.get('/', data={'owner': 'bob'}, **self.extra) response = view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [bobs_data]) # apply filter, see only alice's forms request = self.factory.get('/', data={'owner': 'alice'}, **self.extra) response = view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [alice_data]) # apply filter, see a non existent user request = self.factory.get('/', data={'owner': 'noone'}, **self.extra) response = view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [])
def test_get_dataview_no_perms(self): self._create_dataview() alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(alice_data) request = self.factory.get('/', **self.extra) response = self.view(request, pk=self.data_view.pk) self.assertEquals(response.status_code, 404) # assign alice the perms ReadOnlyRole.add(self.user, self.data_view.project) request = self.factory.get('/', **self.extra) response = self.view(request, pk=self.data_view.pk) self.assertEquals(response.status_code, 200)
def test_data_list_filter_by_user(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) formid = self.xform.pk bobs_data = _data_list(formid)[0] previous_user = self.user self._create_user_and_login('alice', 'alice') self.assertEqual(self.user.username, 'alice') self.assertNotEqual(previous_user, self.user) ReadOnlyRole.add(self.user, self.xform) # publish alice's form self._publish_transportation_form() self.extra = {'HTTP_AUTHORIZATION': 'Token %s' % self.user.auth_token} formid = self.xform.pk alice_data = _data_list(formid)[0] request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, 200) # should be both bob's and alice's form self.assertEqual(sorted(response.data), sorted([bobs_data, alice_data])) # apply filter, see only bob's forms request = self.factory.get('/', data={'owner': 'bob'}, **self.extra) response = view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [bobs_data]) # apply filter, see only alice's forms request = self.factory.get('/', data={'owner': 'alice'}, **self.extra) response = view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [alice_data]) # apply filter, see a non existent user request = self.factory.get('/', data={'owner': 'noone'}, **self.extra) response = view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [])
def test_widget_permission_get(self): self._create_widget() alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(alice_data) request = self.factory.get('/', **self.extra) response = self.view(request, pk=self.widget.pk) self.assertEquals(response.status_code, 404) # assign alice the perms ReadOnlyRole.add(self.user, self.project) request = self.factory.get('/', **self.extra) response = self.view(request, formid=self.xform.pk, pk=self.widget.pk) self.assertEquals(response.status_code, 200)
def test_project_filter_by_owner(self): self._project_create() alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(alice_data) ReadOnlyRole.add(self.user, self.project) view = ProjectViewSet.as_view({ 'get': 'retrieve' }) request = self.factory.get('/', **self.extra) response = view(request, pk=self.project.pk) updated_project_data = response.data self._project_create({'name': 'another project'}) # both bob's and alice's projects request = self.factory.get('/', **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertIn(updated_project_data, response.data) self.assertIn(self.project_data, response.data) # only bob's project request = self.factory.get('/', {'owner': 'bob'}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertIn(updated_project_data, response.data) self.assertNotIn(self.project_data, response.data) # only alice's project request = self.factory.get('/', {'owner': 'alice'}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertNotIn(updated_project_data, response.data) self.assertIn(self.project_data, response.data) # none existent user request = self.factory.get('/', {'owner': 'noone'}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [])
def test_form_list_filter_by_user(self): # publish bob's form self._publish_xls_form_to_project() previous_user = self.user alice_data = {"username": "******", "email": "*****@*****.**"} self._login_user_and_profile(extra_post_data=alice_data) self.assertEqual(self.user.username, "alice") self.assertNotEqual(previous_user, self.user) ReadOnlyRole.add(self.user, self.xform) view = XFormViewSet.as_view({"get": "retrieve"}) request = self.factory.get("/", **self.extra) response = view(request, pk=self.xform.pk) bobs_form_data = response.data # publish alice's form self._publish_xls_form_to_project() request = self.factory.get("/", **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) # should be both bob's and alice's form self.assertEqual(sorted(response.data), sorted([bobs_form_data, self.form_data])) # apply filter, see only bob's forms request = self.factory.get("/", data={"owner": "bob"}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [bobs_form_data]) # apply filter, see only alice's forms request = self.factory.get("/", data={"owner": "alice"}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [self.form_data]) # apply filter, see a non existent user request = self.factory.get("/", data={"owner": "noone"}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [])
def test_reassign_role(self): self._publish_transportation_form() alice = self._create_user('alice', 'alice') self.assertFalse(ManagerRole.user_has_role(alice, self.xform)) ManagerRole.add(alice, self.xform) self.assertTrue(ManagerRole.user_has_role(alice, self.xform)) self.assertTrue( ManagerRole.has_role(perms_for(alice, self.xform), self.xform)) ReadOnlyRole.add(alice, self.xform) self.assertFalse(ManagerRole.user_has_role(alice, self.xform)) self.assertTrue(ReadOnlyRole.user_has_role(alice, self.xform)) self.assertFalse( ManagerRole.has_role(perms_for(alice, self.xform), self.xform)) self.assertTrue( ReadOnlyRole.has_role(perms_for(alice, self.xform), self.xform))
def test_widget_permission_list(self): self._create_widget() alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(alice_data) view = WidgetViewSet.as_view({ 'get': 'list', }) request = self.factory.get('/', **self.extra) response = view(request) self.assertEquals(response.status_code, 200) self.assertEquals(len(response.data), 0) # assign alice the perms ReadOnlyRole.add(self.user, self.xform) request = self.factory.get('/', **self.extra) response = view(request) self.assertEquals(response.status_code, 200) self.assertEquals(len(response.data), 1)
def test_project_share_endpoint(self, mock_send_mail): # create project and publish form to project self._publish_xls_form_to_project() alice_data = {'username': '******', 'email': '*****@*****.**'} alice_profile = self._create_user_profile(alice_data) projectid = self.project.pk ROLES = [ReadOnlyRole, DataEntryRole, EditorRole, ManagerRole, OwnerRole] for role_class in ROLES: self.assertFalse(role_class.user_has_role(alice_profile.user, self.project)) data = {'username': '******', 'role': role_class.name, 'email_msg': 'I have shared the project with you'} request = self.factory.post('/', data=data, **self.extra) view = ProjectViewSet.as_view({ 'post': 'share' }) response = view(request, pk=projectid) self.assertEqual(response.status_code, 204) self.assertTrue(mock_send_mail.called) self.assertTrue(role_class.user_has_role(alice_profile.user, self.project)) self.assertTrue(ReadOnlyRole.user_has_role(alice_profile.user, self.xform)) # Reset the mock called value to False mock_send_mail.called = False data = {'username': '******', 'role': ''} request = self.factory.post('/', data=data, **self.extra) response = view(request, pk=projectid) self.assertEqual(response.status_code, 400) self.assertEqual(response.get('Last-Modified'), None) self.assertFalse(mock_send_mail.called) role_class._remove_obj_permissions(alice_profile.user, self.project)
def test_project_share_endpoint(self, mock_send_mail): # create project and publish form to project self._publish_xls_form_to_project() alice_data = {'username': '******', 'email': '*****@*****.**'} alice_profile = self._create_user_profile(alice_data) projectid = self.project.pk ROLES = [ ReadOnlyRole, DataEntryRole, EditorRole, ManagerRole, OwnerRole ] for role_class in ROLES: self.assertFalse( role_class.user_has_role(alice_profile.user, self.project)) data = { 'username': '******', 'role': role_class.name, 'email_msg': 'I have shared the project with you' } request = self.factory.post('/', data=data, **self.extra) view = ProjectViewSet.as_view({'post': 'share'}) response = view(request, pk=projectid) self.assertEqual(response.status_code, 204) self.assertTrue(mock_send_mail.called) self.assertTrue( role_class.user_has_role(alice_profile.user, self.project)) self.assertTrue( ReadOnlyRole.user_has_role(alice_profile.user, self.xform)) # Reset the mock called value to False mock_send_mail.called = False data = {'username': '******', 'role': ''} request = self.factory.post('/', data=data, **self.extra) response = view(request, pk=projectid) self.assertEqual(response.status_code, 400) self.assertEqual(response.get('Last-Modified'), None) self.assertFalse(mock_send_mail.called) role_class._remove_obj_permissions(alice_profile.user, self.project)
def test_export_readonly_with_meta_perms(self): """ Test export list for forms with meta permissions on export_async. """ with HTTMock(enketo_mock): self._publish_transportation_form() for survey in self.surveys: self._make_submission(os.path.join( settings.PROJECT_ROOT, 'apps', 'main', 'tests', 'fixtures', 'transportation', 'instances', survey, survey + '.xml'), forced_submission_time=parse_datetime( '2013-02-18 15:54:01Z')) alice = self._create_user('alice', 'alice', True) MetaData.xform_meta_permission(self.xform, data_value="editor|dataentry-minor") ReadOnlyRole.add(alice, self.xform) export_view = XFormViewSet.as_view({ 'get': 'export_async', }) alices_extra = { 'HTTP_AUTHORIZATION': 'Token %s' % alice.auth_token.key } # Alice creates an export with her own submissions request = self.factory.get('/', data={"format": 'csv'}, **alices_extra) response = export_view(request, pk=self.xform.pk) self.assertEqual(response.status_code, 202) exports = Export.objects.filter(xform=self.xform) view = ExportViewSet.as_view({'get': 'list'}) request = self.factory.get('/export', data={'xform': self.xform.id}) force_authenticate(request, user=alice) response = view(request) self.assertEqual(len(exports), len(response.data)) self.assertEqual(len(exports), 1) # Mary should not have access to the export with Alice's # submissions. self._create_user_and_login(username='******', password='******') self.assertEqual(self.user.username, 'mary') # Mary should only view their own submissions. DataEntryMinorRole.add(self.user, self.xform) request = self.factory.get('/export', data={'xform': self.xform.id}) force_authenticate(request, user=self.user) response = view(request) self.assertFalse(bool(response.data), response.data) self.assertEqual(status.HTTP_200_OK, response.status_code) # assign some submissions to Mary for i in self.xform.instances.all()[:2]: i.user = self.user i.save() # Mary creates an export with her own submissions request = self.factory.get('/', data={"format": 'csv'}) force_authenticate(request, user=self.user) response = export_view(request, pk=self.xform.pk) self.assertEqual(response.status_code, 202) request = self.factory.get('/export', data={'xform': self.xform.id}) force_authenticate(request, user=self.user) response = view(request) self.assertTrue(bool(response.data), response.data) self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertEqual(len(response.data), 1) self.assertEqual( Export.objects.filter(xform=self.xform).count(), 2) # Alice does not have access to the submitter only export request = self.factory.get('/export', data={'xform': self.xform.id}) force_authenticate(request, user=alice) response = view(request) self.assertEqual(len(exports), len(response.data)) self.assertEqual(len(exports), 1)
def test_form_id_filter_for_require_auth_account(self): """ Test formList formID filter for account that requires authentication """ # 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 self.user.profile.require_auth = True self.user.profile.save() request = self.factory.get('/', {'formID': self.xform.id_string}) response = self.view(request, username=self.user.username) self.assertEqual(response.status_code, 401) # Test for authenticated user but unrecognized formID auth = DigestAuth('bob', 'bobbob') request = self.factory.get('/', {'formID': 'unrecognizedID'}) request.META.update(auth(request.META, response)) response = self.view(request, username=self.user.username) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, []) # Test for authenticated user and valid formID request = self.factory.get('/', {'formID': self.xform.id_string}) self.assertTrue(self.user.profile.require_auth) 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.assertEqual(response.status_code, 200) path = os.path.join( os.path.dirname(__file__), '..', 'fixtures', 'formList2.xml') with open(path, encoding='utf-8') as f: form_list = f.read().strip() data = {"hash": self.xform.hash, "pk": self.xform.pk, 'version': self.xform.version} content = response.render().content.decode('utf-8') self.assertEqual(content, form_list % data) # Test for shared forms # Create user Alice alice_data = { 'username': '******', 'email': '*****@*****.**', 'password1': 'alice', 'password2': 'alice' } alice_profile = self._create_user_profile(alice_data) # check that she can authenticate successfully request = self.factory.get('/') response = self.view(request) self.assertEqual(response.status_code, 401) auth = DigestAuth('alice', 'alice') request.META.update(auth(request.META, response)) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertFalse( ReadOnlyRole.user_has_role(alice_profile.user, self.project)) # share Bob's project with Alice data = { 'username': '******', 'role': ReadOnlyRole.name } request = self.factory.post('/', data=data, **self.extra) share_view = ProjectViewSet.as_view({'post': 'share'}) project_id = self.project.pk response = share_view(request, pk=project_id) self.assertEqual(response.status_code, 204) self.assertTrue( ReadOnlyRole.user_has_role(alice_profile.user, self.project)) request = self.factory.get('/', {'formID': self.xform.id_string}) response = self.view(request) self.assertEqual(response.status_code, 401) auth = DigestAuth('alice', 'alice') request.META.update(auth(request.META, response)) response = self.view(request, username='******') self.assertEqual(response.status_code, 200) path = os.path.join( os.path.dirname(__file__), '..', 'fixtures', 'formList2.xml') with open(path, encoding='utf-8') as f: form_list = f.read().strip() data = {"hash": self.xform.hash, "pk": self.xform.pk, "version": self.xform.version} content = response.render().content.decode('utf-8') self.assertEqual(content, form_list % data) # Bob's profile bob_profile = self.user # Submit form as Alice self._login_user_and_profile(extra_post_data=alice_data) self.assertEqual(self.user.username, 'alice') path = os.path.join( settings.PROJECT_ROOT, "apps", "main", "tests", "fixtures", "good_eats_multilang", "good_eats_multilang.xls") self._publish_xls_form_to_project(xlsform_path=path) self.assertTrue(OwnerRole.user_has_role(alice_profile.user, self.xform)) # Share Alice's form with Bob ReadOnlyRole.add(bob_profile, self.xform) self.assertTrue(ReadOnlyRole.user_has_role(bob_profile, self.xform)) # Get unrecognized formID as bob request = self.factory.get('/', {'formID': 'unrecognizedID'}) response = self.view(request, username=bob_profile.username) self.assertEqual(response.status_code, 401) auth = DigestAuth('bob', 'bobbob') request.META.update(auth(request.META, response)) response = self.view(request, username=bob_profile.username) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, []) # Get Alice's form as Bob request = self.factory.get('/', {'formID': 'good_eats_multilang'}) response = self.view(request, username=bob_profile.username) self.assertEqual(response.status_code, 401) auth = DigestAuth('bob', 'bobbob') request.META.update(auth(request.META, response)) response = self.view(request, username=bob_profile.username) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]['formID'], 'good_eats_multilang')
def test_get_xform_list_with_shared_forms(self, mock_send_mail): # create user alice alice_data = { 'username': '******', 'email': '*****@*****.**', 'password1': 'alice', 'password2': 'alice' } alice_profile = self._create_user_profile(alice_data) # check that she can authenticate successfully request = self.factory.get('/') response = self.view(request) self.assertEqual(response.status_code, 401) auth = DigestAuth('alice', 'alice') request.META.update(auth(request.META, response)) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertFalse( ReadOnlyRole.user_has_role(alice_profile.user, self.project)) # share bob's project with her data = { 'username': '******', 'role': ReadOnlyRole.name, 'email_msg': 'I have shared the project with you' } request = self.factory.post('/', data=data, **self.extra) share_view = ProjectViewSet.as_view({'post': 'share'}) projectid = self.project.pk response = share_view(request, pk=projectid) self.assertEqual(response.status_code, 204) self.assertTrue(mock_send_mail.called) self.assertTrue( ReadOnlyRole.user_has_role(alice_profile.user, self.project)) request = self.factory.get('/') response = self.view(request) self.assertEqual(response.status_code, 401) auth = DigestAuth('alice', 'alice') request.META.update(auth(request.META, response)) response = self.view(request, username='******') self.assertEqual(response.status_code, 200) path = os.path.join( os.path.dirname(__file__), '..', 'fixtures', 'formList.xml') with open(path, encoding='utf-8') as f: form_list_xml = f.read().strip() data = {"hash": self.xform.hash, "pk": self.xform.pk} content = response.render().content.decode('utf-8') self.assertEqual(content, form_list_xml % data) download_url = ('<downloadUrl>http://testserver/%s/' 'forms/%s/form.xml</downloadUrl>') % ( self.user.username, self.xform.id) # check that bob's form exists in alice's formList self.assertTrue(download_url in content) 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_project_filter_by_owner(self): self._project_create() alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(alice_data) ReadOnlyRole.add(self.user, self.project) view = ProjectViewSet.as_view({ 'get': 'retrieve' }) request = self.factory.get('/', **self.extra) response = view(request, pk=self.project.pk) updated_project_data = response.data self._project_create({'name': 'another project'}) # both bob's and alice's projects request = self.factory.get('/', **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertIn(updated_project_data, response.data) self.assertIn(self.project_data, response.data) # only bob's project request = self.factory.get('/', {'owner': 'bob'}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertIn(updated_project_data, response.data) self.assertNotIn(self.project_data, response.data) # only alice's project request = self.factory.get('/', {'owner': 'alice'}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertNotIn(updated_project_data, response.data) self.assertIn(self.project_data, response.data) # none existent user request = self.factory.get('/', {'owner': 'noone'}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, []) # authenticated user can view public project joe_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(joe_data) # should not show private projects when filtered by owner request = self.factory.get('/', {'owner': 'alice'}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertNotIn(updated_project_data, response.data) self.assertNotIn(self.project_data, response.data) # should show public project when filtered by owner self.project.shared = True self.project.save() request.user = self.user self.project_data = ProjectSerializer( self.project, context={'request': request}).data request = self.factory.get('/', {'owner': 'alice'}, **self.extra) response = self.view(request) self.assertEqual(response.status_code, 200) self.assertIn(self.project_data, response.data)