def migrate_dmp_html_to_text(apps, schema_editor): DmpFormData = apps.get_model('dmp', 'DmpFormData') with disable_permission_checks(DmpFormData): for data in DmpFormData.objects.all(): if data.type == 'TXA': # only TextAreas were HTML data.value = convert_html_to_text(data.value) data.save()
def delete_locks_one_by_one(): for lock in ElementLock.objects.all(): try: with disable_permission_checks(ElementLock): lock.delete() except Exception as e: logger.error('Could not delete lock:') logger.error(e)
def opt_users_out_of_meeting_reminders(apps, schema_editor): NotificationConfiguration = apps.get_model("notifications", "NotificationConfiguration") with disable_permission_checks(NotificationConfiguration): for config in NotificationConfiguration.objects.all(): if REMINDER_KEY in config.allowed_notifications: config.allowed_notifications.remove(REMINDER_KEY) config.save()
def fix_privileges_up(apps, schema_editor): RevisionModelMixin.set_enabled(False) with disable_permission_checks(ModelPrivilege): privileges = ModelPrivilege.objects.all() for privilege in privileges: fix_privileges(privilege) RevisionModelMixin.set_enabled(True)
def opt_out(apps, schema_editor): NotificationConfiguration = apps.get_model("notifications", "NotificationConfiguration") with disable_permission_checks(NotificationConfiguration): for config in NotificationConfiguration.objects.all(): if NOTIFICATION_KEY in config.allowed_notifications: config.allowed_notifications.remove(NOTIFICATION_KEY) config.save()
def reference_latest_uploaded_file(apps, schema_editor): File = apps.get_model('shared_elements', 'File') UploadedFileEntry = apps.get_model('shared_elements', 'UploadedFileEntry') with disable_permission_checks(File): with disable_permission_checks(UploadedFileEntry): for file in File.objects.all(): # use latest UploadedFileEntry file.uploaded_file_entry = UploadedFileEntry.objects \ .filter(file=file) \ .order_by('created_at') \ .last() # no UploadedFileEntry exists -> report error if file.uploaded_file_entry is None: raise IntegrityError( "There is no UploadedFileEntry for file " + str(file)) file.save()
def opt_users_out_of_project_comment_notifications(apps, schema_editor): NotificationConfiguration = apps.get_model("notifications", "NotificationConfiguration") with disable_permission_checks(NotificationConfiguration): for config in NotificationConfiguration.objects.all(): for reminder_key in REMINDER_KEYS: if reminder_key in config.allowed_notifications: config.allowed_notifications.remove(reminder_key) config.save()
def refactor_general_usage_setting(apps, schema_editor): RevisionModelMixin.set_enabled(False) db_alias = schema_editor.connection.alias Resource = apps.get_model("projects", "Resource") with disable_permission_checks(Resource): for item in Resource.objects.using(db_alias).all(): if item.general_usage_setting == 'NST': item.general_usage_setting = None item.save() RevisionModelMixin.set_enabled(True)
def grant_full_access_privilege(cls, obj, user): privileges = obj.model_privileges.filter(user=user).first() if not privileges: privileges = ModelPrivilege(user=user, content_type=obj.get_content_type(), object_id=obj.pk) privileges.full_access_privilege = ModelPrivilege.ALLOW with disable_permission_checks(ModelPrivilege): privileges.save()
def remove_maintenance_text(apps, schema_editor): db_alias = schema_editor.connection.alias Content = apps.get_model("cms", "Content") with disable_permission_checks(Content): # first check if an entry exists maintenance_text = Content.objects.using(db_alias).filter( slug="maintenance" ).first() # if an entry exists, we delete it if maintenance_text: maintenance_text.delete()
def refactor_general_usage_settings(apps, schema_editor): RevisionModelMixin.set_enabled(False) db_alias = schema_editor.connection.alias Resource = apps.get_model("projects", "Resource") with disable_permission_checks(Resource): for item in Resource.objects.using(db_alias).all(): if item.general_usage_setting != 'GLB': if item.usage_setting_selected_user_groups.exists(): item.general_usage_setting = 'GRP' else: item.general_usage_setting = 'NST' item.save() RevisionModelMixin.set_enabled(True)
def convert_task_state_from_new_to_old(apps, schema_editor): RevisionModelMixin.set_enabled(False) db_alias = schema_editor.connection.alias Task = apps.get_model("shared_elements", "Task") with disable_permission_checks(Task): for task in Task.objects.all(): task.state = TASK_STATE_MAPPING_NEW_TO_OLD[task.state] task.save() RevisionModelMixin.set_enabled(True)
def handle(self, *args, **options): # monkey patch File save method File.save = Model.save with RevisionModelMixin.enabled(False): with disable_permission_checks(File): with disable_permission_checks(UploadedFileEntry): # get all files files = File.objects.all().prefetch_related('file_entries') # and iterate over them for file in files: file.path = convert_absolute_path_to_relative_path_of_media_root( file.path.path) file.save() # check if the file has a file entries file_entries = file.file_entries.all() for entry in file_entries: entry.path = convert_absolute_path_to_relative_path_of_media_root( entry.path.path) entry.save()
def remove_virtual_root_directory(apps, schema_editor): RevisionModelMixin.set_enabled(False) db_alias = schema_editor.connection.alias Directory = apps.get_model("drives", "Directory") Drive = apps.get_model("drives", "Drive") with disable_permission_checks(Directory): with disable_permission_checks(Drive): # iterate over all drives for drive in Drive.objects.all(): # get all virtual root directories of this drive virtual_root_directories = Directory.objects.filter( drive=drive, directory=None, is_virtual_root=True) # get all directories that have one of those virtual root directories as parent sub_root_directories = Directory.objects.filter( directory__in=virtual_root_directories) # update their parents sub_root_directories.update(directory=None) # and delete virtual root directories virtual_root_directories.delete() RevisionModelMixin.set_enabled(True)
def set_meeting_resource_null(apps, schema_editor): """ Sets all resources in meetings to null to avoid problems with booking rule validation :param apps: :param schema_editor: :return: """ RevisionModelMixin.set_enabled(False) Meeting = apps.get_model('shared_elements', 'Meeting') with disable_permission_checks(Meeting): Meeting.objects.update(resource=None) RevisionModelMixin.set_enabled(True)
def forwards_func(apps, schema_editor): """ Iterates over all files and sets the new title field to the value of the current name field :param apps: :param schema_editor: :return: """ RevisionModelMixin.set_enabled(False) db_alias = schema_editor.connection.alias File = apps.get_model('shared_elements', 'File') with disable_permission_checks(File): with disable_permission_checks(Version): # iterate over all files for file in File.objects.using(db_alias).all(): # set the title to the content of name file.title = file.name # set the name to the original_filename file.name = file.original_filename file.save() # get all versions for this file RevisionModelMixin.set_enabled(True)
def on_delete_labbook_element(sender, instance, *args, **kwargs): """ Followup on a delete of a model that is used in a labbook All labbook child elements that use this object need to be deleted too This is to ensure that when deleting a note/file/picture/plugin within the workbench, we also delete all related labbook child elements """ # check if the current instance is relatable (sanity check) if hasattr(instance._meta, "is_relatable") and instance._meta.is_relatable: # delete all labbook child elements that use this instance (filtered by content type and object id) with disable_permission_checks(LabBookChildElement): LabBookChildElement.objects.filter( child_object_id=instance.pk, child_object_content_type=instance.get_content_type()).delete( )
def set_full_day_according_to_times_for_tasks(apps, schema_editor): RevisionModelMixin.set_enabled(False) db_alias = schema_editor.connection.alias Task = apps.get_model("shared_elements", "Task") with disable_permission_checks(Task): # first get all entries that are full days all_full_day_entries = Task.objects.using(db_alias).filter( start_date__hour=0, start_date__minute=0, due_date__hour=23, due_date__minute=59, ) # then update them all_full_day_entries.update(full_day=True) RevisionModelMixin.set_enabled(True)
def requeue_hanging_files_to_import(): """ If a FileToImport is still in progress and has not been imported, then set import_in_progress to false, so it is tried again in another import queue """ delta = 60 * 60 * 3 # 3 hours hanging_files_to_import = DSSFilesToImport.objects.filter( import_in_progress=True, imported=False, import_attempts__lte=3, created_at__lte=timezone.now() - timedelta(seconds=delta), ) if hanging_files_to_import: count = hanging_files_to_import.count() logger.info(f'Found {count} hanging files to requeue') with disable_permission_checks(DSSFilesToImport): hanging_files_to_import.update(import_in_progress=False)
def populate_project_fts_parent_index(instance, *args, **kwargs): """ Rewrites the FTS index for parents of projects. This happens recursively for the whole parent-tree as this function is subsequently called for the parents parent on updating the index This needs to happen post_save, since the current project wouldn't be registered by parent_project._get_search_vector(), as it isn't persisted if this would be triggered by a pre_save-receiver """ # populate the project parent's FTS index with the `SearchVector` containing the # rendered search document with disable_permission_checks(Project): if instance.parent_project: instance.parent_project.fts_index = instance.parent_project._get_search_vector( ) instance.parent_project.save()
def set_full_day_according_to_times(apps, schema_editor): RevisionModelMixin.set_enabled(False) db_alias = schema_editor.connection.alias ResourceBookingRuleBookableHours = apps.get_model( "projects", "ResourceBookingRuleBookableHours") with disable_permission_checks(ResourceBookingRuleBookableHours): zero_time = time(0, 0, 0) # first get all entries that are not full days all_non_full_day_entries = ResourceBookingRuleBookableHours.objects.using( db_alias).exclude( time_start=zero_time, time_end=zero_time, ) all_non_full_day_entries.update(full_day=False) RevisionModelMixin.set_enabled(True)
def create_maintenance_text(apps, schema_editor): RevisionModelMixin.set_enabled(False) db_alias = schema_editor.connection.alias Content = apps.get_model("cms", "Content") with disable_permission_checks(Content): # first check if an entry exists maintenance_text = Content.objects.using(db_alias).filter( slug="maintenance" ).first() # if no entry exists, we create an "empty" one if not maintenance_text: Content.objects.using(db_alias).create( slug="maintenance", title="Maintenance" ) RevisionModelMixin.set_enabled(True)
def on_delete_relations(sender, instance, *args, **kwargs): """ Followup on a delete of a model that is relatable All relations that use this object need to be deleted too !!! Note: objects should never be deleted; !!! This receiver is only meant as a fallback, to make sure database relations are kept intact when a superuser deletes anything in the database (via django admin) """ # check if the current instance is relatable if hasattr(instance._meta, "is_relatable") and instance._meta.is_relatable: with disable_permission_checks(Relation): # find all Relations where this instance is used as left or right object, and delete those relations Relation.objects.filter( left_object_id=instance.pk, left_content_type=instance.get_content_type()).delete() Relation.objects.filter( right_object_id=instance.pk, right_content_type=instance.get_content_type()).delete()
def forwards_func(apps, schema_editor): """ Iterates over all dmps and converts the ForeignKey relationship to project into a many to many relationship for projects :param apps: :param schema_editor: :return: """ RevisionModelMixin.set_enabled(False) db_alias = schema_editor.connection.alias Dmp = apps.get_model('dmp', 'Dmp') with disable_permission_checks(Dmp): # iterate over all tasks for dmp in Dmp.objects.using(db_alias).all(): if dmp.project: dmp.projects.add(dmp.project) RevisionModelMixin.set_enabled(True)
def reverse_func(apps, schema_editor): """ Iterate over all dmps and take the first projects element from each element and set it on the foreign key relationship :param apps: :param schema_editor: :return: """ RevisionModelMixin.set_enabled(False) db_alias = schema_editor.connection.alias Dmp = apps.get_model('dmp', 'Dmp') with disable_permission_checks(Dmp): # iterate over all dmps for dmp in Dmp.objects.using(db_alias).all(): if dmp.projects.all().count() > 0: dmp.project = dmp.projects.all().first() dmp.save() RevisionModelMixin.set_enabled(True)
def on_delete_element_delete_favourites(sender, instance, *args, **kwargs): """ Signal that handles delete of an object All favourites that use this object need to be deleted too !!! Note: objects should never be deleted; !!! This receiver is only meant as a fallback, to make sure database favourites are kept intact when a superuser deletes anything in the database (via django admin) """ # ignore all non-favouritable models meta_class = instance._meta if not hasattr(meta_class, 'is_favouritable') or not meta_class.is_favouritable: return favourites = Favourite.objects.filter( object_id=instance.pk, content_type=instance.get_content_type()) if favourites.exists(): with disable_permission_checks(Favourite): favourites.delete()
def remove_dss_how_to_texts(apps, schema_editor): db_alias = schema_editor.connection.alias Content = apps.get_model("cms", "Content") with disable_permission_checks(Content): # first check if an entry exists dss_container_list_how_to = Content.objects.using(db_alias).filter( slug="dss_container_list_how_to" ).first() # if an entry exists, we delete it if dss_container_list_how_to: dss_container_list_how_to.delete() # first check if an entry exists dss_container_detail_how_to = Content.objects.using(db_alias).filter( slug="dss_container_detail_how_to" ).first() # if an entry exists, we delete it if dss_container_detail_how_to: dss_container_detail_how_to.delete()
def convert_from_allowdenyneutral_to_truefalse(apps, schema_editor): RevisionModelMixin.set_enabled(False) db_alias = schema_editor.connection.alias ModelPrivilege = apps.get_model('model_privileges', 'ModelPrivilege') with disable_permission_checks(ModelPrivilege): # iterate over all model privileges and fill the new allow/deny/neutral privileges for model_privilege in ModelPrivilege.objects.using(db_alias).all(): if model_privilege.view_privilege == PRIVILEGE_CHOICES_ALLOW: model_privilege.can_view = True if model_privilege.edit_privilege == PRIVILEGE_CHOICES_ALLOW: model_privilege.can_edit = True if model_privilege.delete_privilege == PRIVILEGE_CHOICES_ALLOW: model_privilege.can_delete = True if model_privilege.restore_privilege == PRIVILEGE_CHOICES_ALLOW: model_privilege.can_restore = True model_privilege.save() RevisionModelMixin.set_enabled(True)
def on_project_create_add_project_manager_role_for_current_user( sender, instance, created, *args, **kwargs): """ When a new project is created, assign the role 'Project Manager' (default_role_on_project_create = True) to the current user """ # ignore raw inserts (e.g. from fixtures) and updates (not created) if kwargs.get('raw') or not created: return from eric.core.models import disable_permission_checks # create a new project role user assignment for this user and the current project # we have to disable permission checks for this model temporarily with disable_permission_checks(ProjectRoleUserAssignment): assignment = ProjectRoleUserAssignment() assignment.user = get_current_user() assignment.project = instance assignment.role = Role.objects.filter( default_role_on_project_create=True).first() assignment.save()
def handle(self, *args, **options): with disable_permission_checks(ElementLock): timedelta = timezone.timedelta(minutes=site_preferences.element_lock_time_in_minutes) timedelta_webdav = timezone.timedelta(minutes=site_preferences.element_lock_webdav_time_in_minutes) element_locks = ElementLock.objects.filter( locked_at__lte=timezone.now() - timedelta, webdav_lock=False, ) webdav_element_locks = ElementLock.objects.filter( locked_at__lte=timezone.now() - timedelta_webdav, webdav_lock=True, ) if element_locks.count() > 0: logger.debug("{}: Deleting {}/{} ElementLocks".format( timezone.now(), element_locks.count(), ElementLock.objects.all().count() )) if webdav_element_locks.count() > 0: logger.debug("{}: Deleting {}/{} Webdav ElementLocks".format( timezone.now(), element_locks.count(), ElementLock.objects.all().count() )) # deleting element locks might fail, if the model does not exist anymore # but there are still some instances of that model in the database # (should only ever happen in development environments where the database was not cleaned up) # So we clean up as much as we can, one by one, as fallback, and ignore non-deletable locks try: element_locks.delete() webdav_element_locks.delete() except Exception as e: logger.error(e) self.delete_locks_one_by_one()