Ejemplo n.º 1
0
def org_profile_post_delete_callback(sender, instance, **kwargs):
    """
    Signal handler to delete the organization user object.
    """
    # delete the org_user too
    instance.user.delete()
    safe_delete('{}{}'.format(IS_ORG, instance.pk))
Ejemplo n.º 2
0
    def restore_object(self, attrs, instance=None):
        if instance:
            metadata = JsonField.to_json(attrs.get("metadata"))
            owner = attrs.get("organization")

            if self.partial and metadata:
                if not isinstance(instance.metadata, dict):
                    instance.metadata = {}

                instance.metadata.update(metadata)
                attrs["metadata"] = instance.metadata

            if self.partial and owner:
                # give the new owner permissions
                set_owners_permission(owner, instance)

                # clear cache
                safe_delete("{}{}".format(PROJ_PERM_CACHE, self.object.pk))

            return super(ProjectSerializer, self).restore_object(attrs, instance)

        if "request" in self.context:
            created_by = self.context["request"].user

            return Project(
                name=attrs.get("name"),
                organization=attrs.get("organization"),
                created_by=created_by,
                metadata=attrs.get("metadata"),
            )

        return attrs
Ejemplo n.º 3
0
def update_xform_submission_count_delete(sender, instance, **kwargs):
    try:
        xform = XForm.objects.select_for_update().get(pk=instance.xform.pk)
    except XForm.DoesNotExist:
        pass
    else:
        xform.num_of_submissions -= 1
        if xform.num_of_submissions < 0:
            xform.num_of_submissions = 0
        xform.save(update_fields=['num_of_submissions'])
        profile_qs = User.profile.get_queryset()
        try:
            profile = profile_qs.select_for_update()\
                .get(pk=xform.user.profile.pk)
        except profile_qs.model.DoesNotExist:
            pass
        else:
            profile.num_of_submissions -= 1
            if profile.num_of_submissions < 0:
                profile.num_of_submissions = 0
            profile.save()

        for a in [PROJ_NUM_DATASET_CACHE, PROJ_SUB_DATE_CACHE]:
            safe_delete('{}{}'.format(a, xform.project.pk))

        safe_delete('{}{}'.format(IS_ORG, xform.pk))
        safe_delete('{}{}'.format(XFORM_DATA_VERSIONS, xform.pk))
        safe_delete('{}{}'.format(DATAVIEW_COUNT, xform.pk))
        safe_delete('{}{}'.format(XFORM_COUNT, xform.pk))

        if xform.instances.exclude(geom=None).count() < 1:
            xform.instances_with_geopoints = False
            xform.save()
Ejemplo n.º 4
0
    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)

                # apply same role to forms under the project
                for xform in self.project.xform_set.all():
                    # check if there is xform meta perms set
                    meta_perms = xform.metadata_set \
                        .filter(data_type='xform_meta_perms')
                    if meta_perms:
                        meta_perm = meta_perms[0].data_value.split("|")

                        if len(meta_perm) > 1:
                            if role in [EditorRole, EditorMinorRole]:
                                role = ROLES.get(meta_perm[0])

                            elif role in [DataEntryRole, DataEntryMinorRole,
                                          DataEntryOnlyRole]:
                                role = ROLES.get(meta_perm[1])
                    role.add(self.user, xform)

                for dataview in self.project.dataview_set.all():
                    if dataview.matches_parent:
                        role.add(self.user, dataview.xform)

        # clear cache
        safe_delete('{}{}'.format(PROJ_PERM_CACHE, self.project.pk))
Ejemplo n.º 5
0
    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 test_delete_organization(self):
        profile = tools.create_organization_object("modilabs", self.user)
        profile.save()
        profile_id = profile.pk
        count = OrganizationProfile.objects.all().count()
        cache.set('{}{}'.format(IS_ORG, profile_id), True)

        profile.delete()
        safe_delete('{}{}'.format(IS_ORG, profile_id))
        self.assertIsNone(cache.get('{}{}'.format(IS_ORG, profile_id)))
        self.assertEqual(count - 1,
                         OrganizationProfile.objects.all().count())
Ejemplo n.º 7
0
def set_object_permissions(sender, instance=None, created=False, **kwargs):
    if created:
        from onadata.libs.permissions import OwnerRole
        OwnerRole.add(instance.user, instance)

        if instance.created_by and instance.user != instance.created_by:
            OwnerRole.add(instance.created_by, instance)

        from onadata.libs.utils.project_utils import set_project_perms_to_xform
        set_project_perms_to_xform(instance, instance.project)

        # clear cache
        safe_delete('{}{}'.format(PROJ_FORMS_CACHE, instance.project.pk))
        safe_delete('{}{}'.format(IS_ORG, instance.pk))
Ejemplo n.º 8
0
    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)

                # apply same role to forms under the project
                for xform in self.project.xform_set.all():
                    role.add(self.user, xform)
        # clear cache
        safe_delete('{}{}'.format(PROJ_PERM_CACHE, self.project.pk))
Ejemplo n.º 9
0
def set_object_permissions(sender, instance=None, created=False, **kwargs):
    """
    Apply the relevant object permissions for the form to all users who should
    have access to it.
    """
    if instance.project:
        # clear cache
        safe_delete('{}{}'.format(PROJ_FORMS_CACHE, instance.project.pk))
        safe_delete('{}{}'.format(PROJ_BASE_FORMS_CACHE, instance.project.pk))

    # seems the super is not called, have to get xform from here
    xform = XForm.objects.get(pk=instance.pk)

    if created:
        from onadata.libs.permissions import OwnerRole

        OwnerRole.add(instance.user, xform)

        if instance.created_by and instance.user != instance.created_by:
            OwnerRole.add(instance.created_by, xform)

        from onadata.libs.utils.project_utils import set_project_perms_to_xform_async  # noqa
        try:
            set_project_perms_to_xform_async.delay(xform.pk,
                                                   instance.project.pk)
        except OperationalError:
            from onadata.libs.utils.project_utils import set_project_perms_to_xform  # noqa
            set_project_perms_to_xform(xform, instance.project)

    if hasattr(instance, 'has_external_choices') \
            and instance.has_external_choices:
        instance.xls.seek(0)
        f = sheet_to_csv(instance.xls.read(), 'external_choices')
        f.seek(0, os.SEEK_END)
        size = f.tell()
        f.seek(0)

        from onadata.apps.main.models.meta_data import MetaData
        data_file = InMemoryUploadedFile(
            file=f,
            field_name='data_file',
            name='itemsets.csv',
            content_type='text/csv',
            size=size,
            charset=None
        )

        MetaData.media_upload(xform, data_file)
Ejemplo n.º 10
0
def update_xform_submission_count(sender, instance, created, **kwargs):
    if created:
        xform = XForm.objects.select_related().select_for_update().get(pk=instance.xform.pk)
        xform.num_of_submissions += 1
        xform.last_submission_time = instance.date_created
        xform.save()
        profile_qs = User.profile.get_query_set()
        try:
            profile = profile_qs.select_for_update().get(pk=xform.user.profile.pk)
        except profile_qs.model.DoesNotExist:
            pass
        else:
            profile.num_of_submissions += 1
            profile.save()

        safe_delete("{}{}".format(XFORM_DATA_VERSIONS, xform.pk))
Ejemplo n.º 11
0
    def submission_count(self, force_update=False):
        if self.num_of_submissions == 0 or force_update:
            if self.is_merged_dataset:
                count = self.mergedxform.xforms.aggregate(
                    num=Sum('num_of_submissions')).get('num') or 0
            else:
                count = self.instances.filter(deleted_at__isnull=True).count()

            if count != self.num_of_submissions:
                self.num_of_submissions = count
                self.save(update_fields=['num_of_submissions'])

                # clear cache
                key = '{}{}'.format(XFORM_COUNT, self.pk)
                safe_delete(key)

        return self.num_of_submissions
Ejemplo n.º 12
0
def update_xform_submission_count(instance_id, created):
    if created:
        try:
            instance = Instance.objects.select_related('xform').only(
                'xform__user_id', 'date_created').get(pk=instance_id)
        except Instance.DoesNotExist:
            pass
        else:
            # update xform.num_of_submissions
            cursor = connection.cursor()
            sql = (
                'UPDATE logger_xform SET '
                'num_of_submissions = num_of_submissions + 1, '
                'last_submission_time = %s '
                'WHERE id = %s'
            )
            params = [instance.date_created, instance.xform_id]

            # update user profile.num_of_submissions
            cursor.execute(sql, params)
            sql = (
                'UPDATE main_userprofile SET '
                'num_of_submissions = num_of_submissions + 1 '
                'WHERE user_id = %s'
            )
            cursor.execute(sql, [instance.xform.user_id])

            safe_delete('{}{}'.format(XFORM_DATA_VERSIONS, instance.xform_id))
            safe_delete('{}{}'.format(DATAVIEW_COUNT, instance.xform_id))
            safe_delete('{}{}'.format(XFORM_COUNT, instance.xform_id))
Ejemplo n.º 13
0
def clear_dataview_cache(sender, instance, **kwargs):
    """ Post Save handler for clearing dataview cache on serialized fields.
    """
    safe_delete('{}{}'.format(DATAVIEW_COUNT, instance.xform.pk))
    safe_delete(
        '{}{}'.format(DATAVIEW_LAST_SUBMISSION_TIME, instance.xform.pk))
    safe_delete('{}{}'.format(XFORM_LINKED_DATAVIEWS, instance.xform.pk))
Ejemplo n.º 14
0
def clear_cache(sender, instance, **kwargs):
    """ Post delete handler for clearing the dataview cache.
    """
    safe_delete('{}{}'.format(XFORM_LINKED_DATAVIEWS, instance.xform.pk))
Ejemplo n.º 15
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
Ejemplo n.º 16
0
def clear_dataview_cache(sender, instance, **kwargs):
    safe_delete('{}{}'.format(DATAVIEW_COUNT, instance.xform.pk))
    safe_delete('{}{}'.format(DATAVIEW_LAST_SUBMISSION_TIME,
                              instance.xform.pk))
Ejemplo n.º 17
0
def clear_cache(sender, instance, **kwargs):
    # clear cache
    safe_delete('{}{}'.format(XFORM_LINKED_DATAVIEWS, instance.xform.pk))
Ejemplo n.º 18
0
def dataview_post_delete_callback(sender, instance, **kwargs):
    if instance.project:
        safe_delete('{}{}'.format(PROJECT_LINKED_DATAVIEWS,
                                  instance.project.pk))
Ejemplo n.º 19
0
def clear_cached_metadata_instance_object(sender,
                                          instance=None,
                                          created=False,
                                          **kwargs):
    safe_delete('{}{}'.format(XFORM_METADATA_CACHE, instance.object_id))
Ejemplo n.º 20
0
def dataview_post_save_callback(sender, instance=None, created=False,
                                **kwargs):
    safe_delete('{}{}'.format(PROJECT_LINKED_DATAVIEWS, instance.project.pk))
Ejemplo n.º 21
0
def clear_project_cache(project_id):
    safe_delete('{}{}'.format(PROJ_OWNER_CACHE, project_id))
    safe_delete('{}{}'.format(PROJ_FORMS_CACHE, project_id))
    safe_delete('{}{}'.format(PROJ_BASE_FORMS_CACHE, project_id))
    safe_delete('{}{}'.format(PROJ_SUB_DATE_CACHE, project_id))
    safe_delete('{}{}'.format(PROJ_NUM_DATASET_CACHE, project_id))
Ejemplo n.º 22
0
def xform_post_delete_callback(sender, instance, **kwargs):
    if instance.project_id:
        safe_delete('{}{}'.format(PROJ_FORMS_CACHE, instance.project_id))
        safe_delete('{}{}'.format(PROJ_BASE_FORMS_CACHE, instance.project.pk))
        safe_delete('{}{}'.format(PROJ_SUB_DATE_CACHE, instance.project_id))
        safe_delete('{}{}'.format(PROJ_NUM_DATASET_CACHE, instance.project_id))
Ejemplo n.º 23
0
def clear_cached_metadata_instance_object(
        sender, instance=None, created=False, **kwargs):
    safe_delete('{}{}'.format(
        XFORM_METADATA_CACHE, instance.xform.pk))
def org_profile_post_delete_callback(sender, instance, **kwargs):
    # delete the org_user too
    instance.user.delete()
    safe_delete('{}{}'.format(IS_ORG, instance.pk))
Ejemplo n.º 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
Ejemplo n.º 26
0
def dataview_post_delete_callback(sender, instance, **kwargs):
    if instance.project:
        safe_delete('{}{}'.format(PROJECT_LINKED_DATAVIEWS,
                                  instance.project.pk))
Ejemplo n.º 27
0
def org_profile_post_delete_callback(sender, instance, **kwargs):
    safe_delete('{}{}'.format(IS_ORG, instance.pk))
Ejemplo n.º 28
0
def dataview_post_save_callback(sender,
                                instance=None,
                                created=False,
                                **kwargs):
    safe_delete('{}{}'.format(PROJECT_LINKED_DATAVIEWS, instance.project.pk))
Ejemplo n.º 29
0
def clear_cache(sender, instance, **kwargs):
    """ Post delete handler for clearing the dataview cache.
    """
    safe_delete('{}{}'.format(XFORM_LINKED_DATAVIEWS, instance.xform.pk))
Ejemplo n.º 30
0
def xform_post_delete_callback(sender, instance, **kwargs):
    if instance.project_id:
        safe_delete('{}{}'.format(PROJ_FORMS_CACHE, instance.project_id))
        safe_delete('{}{}'.format(PROJ_SUB_DATE_CACHE, instance.project_id))
        safe_delete('{}{}'.format(PROJ_NUM_DATASET_CACHE, instance.project_id))