def test_form_clone_endpoint(self):
        self._publish_xls_form_to_project()
        alice_data = {'username': '******', 'email': '*****@*****.**'}
        alice_profile = self._create_user_profile(alice_data)
        view = XFormViewSet.as_view({
            'post': 'clone'
        })
        formid = self.xform.pk
        count = XForm.objects.count()

        data = {'username': '******'}
        request = self.factory.post('/', data=data, **self.extra)
        response = view(request, pk=formid)
        self.assertEqual(response.status_code, 400)

        data = {'username': '******'}
        request = self.factory.post('/', data=data, **self.extra)
        response = view(request, pk=formid)
        self.assertFalse(self.user.has_perm('can_add_xform', alice_profile))
        self.assertEqual(response.status_code, 403)

        ManagerRole.add(self.user, alice_profile)
        request = self.factory.post('/', data=data, **self.extra)
        response = view(request, pk=formid)
        self.assertTrue(self.user.has_perm('can_add_xform', alice_profile))
        self.assertEqual(response.status_code, 201)
        self.assertEqual(count + 1, XForm.objects.count())
    def test_form_clone_endpoint(self):
        self._publish_xls_form_to_project()
        alice_data = {"username": "******", "email": "*****@*****.**"}
        alice_profile = self._create_user_profile(alice_data)
        view = XFormViewSet.as_view({"post": "clone"})
        formid = self.xform.pk
        count = XForm.objects.count()

        data = {"username": "******"}
        request = self.factory.post("/", data=data, **self.extra)
        response = view(request, pk=formid)
        self.assertEqual(response.status_code, 400)

        data = {"username": "******"}
        request = self.factory.post("/", data=data, **self.extra)
        response = view(request, pk=formid)
        self.assertFalse(self.user.has_perm("can_add_xform", alice_profile))
        self.assertEqual(response.status_code, 403)

        ManagerRole.add(self.user, alice_profile)
        request = self.factory.post("/", data=data, **self.extra)
        response = view(request, pk=formid)
        self.assertTrue(self.user.has_perm("can_add_xform", alice_profile))
        self.assertEqual(response.status_code, 201)
        self.assertEqual(count + 1, XForm.objects.count())
Exemple #3
0
    def test_project_manager_can_assign_form_to_project_no_perm(self):
        # user must have owner/manager permissions
        view = ProjectViewSet.as_view({
            'post': 'forms',
            'get': 'retrieve'
        })
        self._publish_xls_form_to_project()
        # alice user is not manager to both projects
        alice_data = {'username': '******', 'email': '*****@*****.**'}
        alice_profile = self._create_user_profile(alice_data)
        self.assertFalse(ManagerRole.user_has_role(alice_profile.user,
                                                   self.project))

        formid = self.xform.pk
        project_name = u'another project'
        self._project_create({'name': project_name})
        self.assertTrue(self.project.name == project_name)
        ManagerRole.add(alice_profile.user, self.project)
        self.assertTrue(ManagerRole.user_has_role(alice_profile.user,
                                                  self.project))
        self._login_user_and_profile(alice_data)

        project_id = self.project.pk
        post_data = {'formid': formid}
        request = self.factory.post('/', data=post_data, **self.extra)
        response = view(request, pk=project_id)
        self.assertEqual(response.status_code, 403)
    def test_form_clone_endpoint(self):
        self._publish_xls_form_to_project()
        alice_data = {'username': '******', 'email': '*****@*****.**'}
        alice_profile = self._create_user_profile(alice_data)
        view = XFormViewSet.as_view({'post': 'clone'})
        formid = self.xform.pk
        count = XForm.objects.count()

        data = {'username': '******'}
        request = self.factory.post('/', data=data, **self.extra)
        response = view(request, pk=formid)
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.get('Last-Modified'), None)

        data = {'username': '******'}
        request = self.factory.post('/', data=data, **self.extra)
        response = view(request, pk=formid)
        self.assertFalse(self.user.has_perm('can_add_xform', alice_profile))
        self.assertEqual(response.status_code, 403)

        ManagerRole.add(self.user, alice_profile)
        request = self.factory.post('/', data=data, **self.extra)
        response = view(request, pk=formid)
        self.assertTrue(self.user.has_perm('can_add_xform', alice_profile))
        self.assertEqual(response.status_code, 201)
        self.assertEqual(count + 1, XForm.objects.count())
Exemple #5
0
    def test_manager_role_add(self):
        bob, created = UserProfile.objects.get_or_create(user=self.user)
        alice = self._create_user('alice', 'alice')
        self.assertFalse(alice.has_perm(CAN_ADD_XFORM_TO_PROFILE, bob))

        ManagerRole.add(alice, bob)

        self.assertTrue(alice.has_perm(CAN_ADD_XFORM_TO_PROFILE, bob))
    def test_manager_role_add(self):
        bob, created = UserProfile.objects.get_or_create(user=self.user)
        alice = self._create_user('alice', 'alice')
        self.assertFalse(alice.has_perm(CAN_ADD_XFORM_TO_PROFILE, bob))

        ManagerRole.add(alice, bob)

        self.assertTrue(alice.has_perm(CAN_ADD_XFORM_TO_PROFILE, bob))
Exemple #7
0
    def test_manager_has_role(self):
        bob = UserProfile.objects.create(user=self.user)
        alice = self._create_user('alice', 'alice')

        self.assertFalse(ManagerRole.has_role(alice, bob))

        ManagerRole.add(alice, bob)

        self.assertTrue(ManagerRole.has_role(alice, bob))
Exemple #8
0
    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))
Exemple #9
0
def do_publish_xlsform(user, post, files, owner, id_string=None, project=None):
    if id_string and project:
        xform = get_object_or_404(XForm, user=owner, id_string=id_string,
                                  project=project)
        if not ManagerRole.user_has_role(user, xform):
            raise exceptions.PermissionDenied(_(
                "{} has no manager/owner role to the form {}". format(
                    user, xform)))
    elif not user.has_perm('can_add_xform', owner.profile):
        raise exceptions.PermissionDenied(
            detail=_(u"User %(user)s has no permission to add xforms to "
                     "account %(account)s" % {'user': user.username,
                                              'account': owner.username}))

    def set_form():

        if project:
            args = dict({'project': project.pk}.items() + post.items())
        else:
            args = post

        form = QuickConverter(args,  files)

        return form.publish(owner, id_string=id_string, created_by=user)

    return publish_form(set_form)
Exemple #10
0
def publish_project_xform(request, project):
    def set_form():
        props = {
            'project': project.pk,
            'dropbox_xls_url': request.DATA.get('dropbox_xls_url'),
            'xls_url': request.DATA.get('xls_url'),
            'csv_url': request.DATA.get('csv_url')
        }

        form = QuickConverter(props, request.FILES)

        return form.publish(project.organization, created_by=request.user)

    xform = None

    if 'formid' in request.DATA:
        xform = get_object_or_404(XForm, pk=request.DATA.get('formid'))
        if not ManagerRole.user_has_role(request.user, xform):
            raise exceptions.PermissionDenied(
                _("{} has no manager/owner role to the form {}".format(
                    request.user, xform)))
        xform.project = project
        xform.save()
        set_project_perms_to_xform(xform, project)
    else:
        xform = publish_form(set_form)

    return xform
Exemple #11
0
def publish_project_xform(request, project):
    def set_form():
        props = {
            'project': project.pk,
            'dropbox_xls_url': request.DATA.get('dropbox_xls_url'),
            'xls_url': request.DATA.get('xls_url'),
            'csv_url': request.DATA.get('csv_url')
        }

        form = QuickConverter(props, request.FILES)

        return form.publish(project.organization, created_by=request.user)

    xform = None

    if 'formid' in request.DATA:
        xform = get_object_or_404(XForm, pk=request.DATA.get('formid'))
        if not ManagerRole.user_has_role(request.user, xform):
            raise exceptions.PermissionDenied(_(
                "{} has no manager/owner role to the form {}". format(
                    request.user, xform)))
        xform.project = project
        xform.save()
        set_project_perms_to_xform(xform, project)
    else:
        xform = publish_form(set_form)

    return xform
Exemple #12
0
def do_publish_xlsform(user, post, files, owner, id_string=None, project=None):
    if id_string and project:
        xform = get_object_or_404(XForm, user=owner, id_string=id_string,
                                  project=project)
        if not ManagerRole.user_has_role(user, xform):
            raise exceptions.PermissionDenied(_(
                "{} has no manager/owner role to the form {}". format(
                    user, xform)))
    elif not user.has_perm('can_add_xform', owner.profile):
        raise exceptions.PermissionDenied(
            detail=_(u"User %(user)s has no permission to add xforms to "
                     "account %(account)s" % {'user': user.username,
                                              'account': owner.username}))

    def set_form():

        if project:
            args = dict({'project': project.pk}.items() + post.items())
        else:
            args = post
        form = QuickConverter(args,  files)

        return form.publish(owner, id_string=id_string, created_by=user)

    return publish_form(set_form)
Exemple #13
0
    def test_owner_cannot_remove_self_if_no_other_owner(self):
        self._project_create()

        view = ProjectViewSet.as_view({
            'put': 'share'
        })

        ManagerRole.add(self.user, self.project)

        tom_data = {'username': '******', 'email': '*****@*****.**'}
        bob_profile = self._create_user_profile(tom_data)

        OwnerRole.add(bob_profile.user, self.project)

        data = {'username': '******', 'remove': True, 'role': 'owner'}

        request = self.factory.put('/', data=data, **self.extra)
        response = view(request, pk=self.project.pk)

        self.assertEqual(response.status_code, 400)
        error = {'remove': [u"Project requires at least one owner"]}
        self.assertEquals(response.data, error)

        self.assertTrue(OwnerRole.user_has_role(bob_profile.user,
                                                self.project))

        alice_data = {'username': '******', 'email': '*****@*****.**'}
        profile = self._create_user_profile(alice_data)

        OwnerRole.add(profile.user, self.project)

        view = ProjectViewSet.as_view({
            'put': 'share'
        })

        data = {'username': '******', 'remove': True, 'role': 'owner'}

        request = self.factory.put('/', data=data, **self.extra)
        response = view(request, pk=self.project.pk)

        self.assertEqual(response.status_code, 204)

        self.assertFalse(OwnerRole.user_has_role(bob_profile.user,
                                                 self.project))
Exemple #14
0
    def has_object_permission(self, request, view, obj):
        """
        Custom has_object_permission method
        """
        if (request.method == 'DELETE' and view.action == 'destroy') or (
                request.method == 'PATCH' and view.action == 'partial_update'):
            return ManagerRole.user_has_role(request.user, obj.instance.xform)

        return super(SubmissionReviewPermissions,
                     self).has_object_permission(request, view, obj)
Exemple #15
0
    def has_object_permission(self, request, view, obj):
        """
        Custom has_object_permission method
        """
        if (request.method == 'DELETE' and view.action == 'destroy') or (
                request.method == 'PATCH' and view.action == 'partial_update'):
            return ManagerRole.user_has_role(request.user, obj.instance.xform)

        return super(SubmissionReviewPermissions, self).has_object_permission(
            request, view, obj)
Exemple #16
0
def publish_project_xform(request, project):
    def set_form():
        props = {
            'project': project.pk,
            'dropbox_xls_url': request.data.get('dropbox_xls_url'),
            'xls_url': request.data.get('xls_url'),
            'csv_url': request.data.get('csv_url'),
            'text_xls_form': request.data.get('text_xls_form')
        }

        form = QuickConverter(props, request.FILES)

        return form.publish(project.organization, created_by=request.user)

    xform = None

    def id_string_exists_in_account():
        try:
            XForm.objects.get(user=project.organization,
                              id_string=xform.id_string)
        except XForm.DoesNotExist:
            return False

        return True

    if 'formid' in request.data:
        xform = get_object_or_404(XForm, pk=request.data.get('formid'))
        safe_delete('{}{}'.format(PROJ_FORMS_CACHE, xform.project.pk))
        safe_delete('{}{}'.format(PROJ_BASE_FORMS_CACHE, xform.project.pk))
        if not ManagerRole.user_has_role(request.user, xform):
            raise exceptions.PermissionDenied(
                _("{} has no manager/owner role to the form {}".format(
                    request.user, xform)))

        msg = 'Form with the same id_string already exists in this account'
        # Without this check, a user can't transfer a form to projects that
        # he/she owns because `id_string_exists_in_account` will always
        # return true
        if project.organization != xform.user and \
                id_string_exists_in_account():
            raise exceptions.ParseError(_(msg))
        xform.user = project.organization
        xform.project = project

        try:
            with transaction.atomic():
                xform.save()
        except IntegrityError:
            raise exceptions.ParseError(_(msg))
        set_project_perms_to_xform_async.delay(xform.pk, project.pk)
    else:
        xform = publish_form(set_form)

    return xform
Exemple #17
0
    def test_project_manager_can_delete_xform(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)
        alice = alice_profile.user
        projectid = self.project.pk

        self.assertFalse(ManagerRole.user_has_role(alice, self.project))

        data = {'username': '******', 'role': ManagerRole.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(ManagerRole.user_has_role(alice, self.project))
        self.assertTrue(alice.has_perm('delete_xform', self.xform))
Exemple #18
0
    def _create_submission_review(self):
        """
        Utility method creates Submission Review
        """
        instance_id = self._first_xform_instance.id
        # Ensure Managers can create a Submission Review
        self._create_user_and_login('bob', '1234')
        ManagerRole.add(self.user, self._first_xform_instance.xform)
        submission_data = {
            'note': "Supreme Overload!",
            'instance': instance_id
        }

        view = SubmissionReviewViewSet.as_view({'post': 'create'})
        request = self.factory.post('/', data=submission_data, **self.extra)
        response = view(request=request)

        self.assertEqual(201, response.status_code)
        self.assertEqual("Supreme Overload!", response.data['note'])
        self.assertEqual(instance_id, response.data['instance'])

        return response.data
Exemple #19
0
    def test_project_manager_can_assign_form_to_project(self):
        view = ProjectViewSet.as_view({
            'post': 'forms',
            'get': 'retrieve'
        })
        self._publish_xls_form_to_project()
        # alice user as manager to both projects
        alice_data = {'username': '******', 'email': '*****@*****.**'}
        alice_profile = self._create_user_profile(alice_data)
        ShareProject(self.project, 'alice', 'manager').save()
        self.assertTrue(ManagerRole.user_has_role(alice_profile.user,
                                                  self.project))

        formid = self.xform.pk
        old_project = self.project
        project_name = u'another project'
        self._project_create({'name': project_name})
        self.assertTrue(self.project.name == project_name)
        ShareProject(self.project, 'alice', 'manager').save()
        self.assertTrue(ManagerRole.user_has_role(alice_profile.user,
                                                  self.project))
        self._login_user_and_profile(alice_data)

        project_id = self.project.pk
        post_data = {'formid': formid}
        request = self.factory.post('/', data=post_data, **self.extra)
        response = view(request, pk=project_id)
        self.assertEqual(response.status_code, 201)
        self.assertTrue(self.project.xform_set.filter(pk=self.xform.pk))
        self.assertFalse(old_project.xform_set.filter(pk=self.xform.pk))

        # check if form added appears in the project details
        request = self.factory.get('/', **self.extra)
        response = view(request, pk=self.project.pk)
        self.assertIn('forms', response.data.keys())
        self.assertEqual(len(response.data['forms']), 1)
Exemple #20
0
    def test_manager_has_role(self):
        bob, created = UserProfile.objects.get_or_create(user=self.user)
        alice = self._create_user('alice', 'alice')

        self.assertFalse(ManagerRole.user_has_role(alice, bob))
        self.assertFalse(ManagerRole.has_role(perms_for(alice, bob), bob))

        ManagerRole.add(alice, bob)

        self.assertTrue(ManagerRole.user_has_role(alice, bob))
        self.assertTrue(ManagerRole.has_role(perms_for(alice, bob), bob))
    def test_manager_has_role(self):
        bob, created = UserProfile.objects.get_or_create(user=self.user)
        alice = self._create_user('alice', 'alice')

        self.assertFalse(ManagerRole.user_has_role(alice, bob))
        self.assertFalse(ManagerRole.has_role(
            perms_for(alice, bob), bob))

        ManagerRole.add(alice, bob)

        self.assertTrue(ManagerRole.user_has_role(alice, bob))
        self.assertTrue(ManagerRole.has_role(
            perms_for(alice, bob), bob))
Exemple #22
0
    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))
Exemple #23
0
 def _check_is_admin_or_manager(  # pylint: disable=no-self-use
         self, user: User, xform: XForm) -> bool:
     return OwnerRole.user_has_role(
         user, xform) or ManagerRole.user_has_role(user, xform)
Exemple #24
0
def publish_project_xform(request, project):
    """
    Publish XLSForm to a project given a request.
    """
    def set_form():
        """
        Instantiates QuickConverter form to publish a form.
        """
        props = {
            'project': project.pk,
            'dropbox_xls_url': request.data.get('dropbox_xls_url'),
            'xls_url': request.data.get('xls_url'),
            'csv_url': request.data.get('csv_url'),
            'text_xls_form': request.data.get('text_xls_form')
        }

        form = QuickConverter(props, request.FILES)

        return form.publish(project.organization, created_by=request.user)

    xform = None

    def id_string_exists_in_account():
        """
        Checks if an id_string exists in an account, returns True if it exists
        otherwise returns False.
        """
        try:
            XForm.objects.get(user=project.organization,
                              id_string=xform.id_string)
        except XForm.DoesNotExist:
            return False
        return True

    if 'formid' in request.data:
        xform = get_object_or_404(XForm, pk=request.data.get('formid'))
        safe_delete('{}{}'.format(PROJ_FORMS_CACHE, xform.project.pk))
        safe_delete('{}{}'.format(PROJ_BASE_FORMS_CACHE, xform.project.pk))
        if not ManagerRole.user_has_role(request.user, xform):
            raise exceptions.PermissionDenied(
                _("{} has no manager/owner role to the form {}".format(
                    request.user, xform)))

        msg = 'Form with the same id_string already exists in this account'
        # Without this check, a user can't transfer a form to projects that
        # he/she owns because `id_string_exists_in_account` will always
        # return true
        if project.organization != xform.user and \
                id_string_exists_in_account():
            raise exceptions.ParseError(_(msg))
        xform.user = project.organization
        xform.project = project

        try:
            with transaction.atomic():
                xform.save()
        except IntegrityError:
            raise exceptions.ParseError(_(msg))
        else:
            # First assign permissions to the person who uploaded the form
            OwnerRole.add(request.user, xform)
            try:
                # Next run async task to apply all other perms
                set_project_perms_to_xform_async.delay(xform.pk, project.pk)
            except OperationalError:
                # Apply permissions synchrounously
                set_project_perms_to_xform(xform, project)
    else:
        xform = publish_form(set_form)

    return xform
Exemple #25
0
def publish_project_xform(request, project):
    """
    Publish XLSForm to a project given a request.
    """

    def set_form():
        """
        Instantiates QuickConverter form to publish a form.
        """
        props = {
            'project': project.pk,
            'dropbox_xls_url': request.data.get('dropbox_xls_url'),
            'xls_url': request.data.get('xls_url'),
            'csv_url': request.data.get('csv_url'),
            'text_xls_form': request.data.get('text_xls_form')
        }

        form = QuickConverter(props, request.FILES)

        return form.publish(project.organization, created_by=request.user)

    xform = None

    def id_string_exists_in_account():
        """
        Checks if an id_string exists in an account, returns True if it exists
        otherwise returns False.
        """
        try:
            XForm.objects.get(
                user=project.organization, id_string=xform.id_string)
        except XForm.DoesNotExist:
            return False
        return True

    if 'formid' in request.data:
        xform = get_object_or_404(XForm, pk=request.data.get('formid'))
        safe_delete('{}{}'.format(PROJ_FORMS_CACHE, xform.project.pk))
        safe_delete('{}{}'.format(PROJ_BASE_FORMS_CACHE, xform.project.pk))
        if not ManagerRole.user_has_role(request.user, xform):
            raise exceptions.PermissionDenied(
                _("{} has no manager/owner role to the form {}".format(
                    request.user, xform)))

        msg = 'Form with the same id_string already exists in this account'
        # Without this check, a user can't transfer a form to projects that
        # he/she owns because `id_string_exists_in_account` will always
        # return true
        if project.organization != xform.user and \
                id_string_exists_in_account():
            raise exceptions.ParseError(_(msg))
        xform.user = project.organization
        xform.project = project

        try:
            with transaction.atomic():
                xform.save()
        except IntegrityError:
            raise exceptions.ParseError(_(msg))
        else:
            # First assign permissions to the person who uploaded the form
            OwnerRole.add(request.user, xform)
            try:
                # Next run async task to apply all other perms
                set_project_perms_to_xform_async.delay(xform.pk, project.pk)
            except OperationalError:
                # Apply permissions synchrounously
                set_project_perms_to_xform(xform, project)
    else:
        xform = publish_form(set_form)

    return xform