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))
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
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()
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))
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())
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))
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))
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)
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))
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
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))
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))
def clear_cache(sender, instance, **kwargs): """ Post delete handler for clearing the dataview cache. """ safe_delete('{}{}'.format(XFORM_LINKED_DATAVIEWS, instance.xform.pk))
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
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))
def clear_cache(sender, instance, **kwargs): # clear cache safe_delete('{}{}'.format(XFORM_LINKED_DATAVIEWS, instance.xform.pk))
def dataview_post_delete_callback(sender, instance, **kwargs): if instance.project: safe_delete('{}{}'.format(PROJECT_LINKED_DATAVIEWS, instance.project.pk))
def clear_cached_metadata_instance_object(sender, instance=None, created=False, **kwargs): safe_delete('{}{}'.format(XFORM_METADATA_CACHE, instance.object_id))
def dataview_post_save_callback(sender, instance=None, created=False, **kwargs): safe_delete('{}{}'.format(PROJECT_LINKED_DATAVIEWS, instance.project.pk))
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))
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))
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))
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
def org_profile_post_delete_callback(sender, instance, **kwargs): safe_delete('{}{}'.format(IS_ORG, instance.pk))
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))