Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions admin/preprints/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

from osf.exceptions import PreprintStateError
from rest_framework.exceptions import PermissionDenied as DrfPermissionDenied
from framework.exceptions import PermissionsError

from osf.management.commands.fix_preprints_has_data_links_and_why_no_data import process_wrong_why_not_data_preprints
from osf.models import (
Expand Down Expand Up @@ -212,18 +213,25 @@ def post(self, request, *args, **kwargs):
assign_version_number=1,
auth=request,
ignore_permission=True,
ignore_existing_versions=True,
)
data_to_update = data_to_update or dict()

primary_file = copy_files(preprint.primary_file, target_node=new_preprint, identifier__in=file_versions)
if primary_file is None:
raise ValueError(f"Primary file {preprint.primary_file.id} doesn't have following versions: {file_versions}") # rollback changes
data_to_update['primary_file'] = primary_file

# FIXME: currently it's not possible to ignore permission when update subjects
# via serializer, remove this logic if deprecated
subjects = data_to_update.pop('subjects', None)
if subjects:
new_preprint.set_subjects([subjects], auth=request, ignore_permission=True)
new_preprint.set_subjects_from_relationships(subjects, auth=request, ignore_permission=True)

PreprintSerializer(new_preprint, context={'request': request, 'ignore_permission': True}).update(new_preprint, data_to_update)
except DrfPermissionDenied as exc:
except ValueError as exc:
return HttpResponse(str(exc), status=400)
except (PermissionsError, DrfPermissionDenied) as exc:
return HttpResponse(f'Not enough permissions to perform this action : {str(exc)}', status=400)

return JsonResponse({'redirect': self.get_success_url(new_preprint._id)})
Expand Down
2 changes: 1 addition & 1 deletion api/preprints/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ def update(self, preprint, validated_data):

if 'node' in validated_data:
node = validated_data.pop('node', None)
self.set_field(preprint.set_supplemental_node, node, auth, ignore_permission=ignore_permission)
self.set_field(preprint.set_supplemental_node, node, auth, ignore_node_permissions=ignore_permission, ignore_permission=ignore_permission)

if 'subjects' in validated_data:
subjects = validated_data.pop('subjects', None)
Expand Down
4 changes: 2 additions & 2 deletions osf/models/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -1191,7 +1191,7 @@ def set_subjects(self, new_subjects, auth, add_log=True, **kwargs):
if hasattr(self, 'update_search'):
self.update_search()

def set_subjects_from_relationships(self, subjects_list, auth, add_log=True):
def set_subjects_from_relationships(self, subjects_list, auth, add_log=True, **kwargs):
""" Helper for setting M2M subjects field from list of flattened subjects received from UI.
Only authorized admins may set subjects.

Expand All @@ -1201,7 +1201,7 @@ def set_subjects_from_relationships(self, subjects_list, auth, add_log=True):

:return: None
"""
self.check_subject_perms(auth)
self.check_subject_perms(auth, **kwargs)
self.assert_subject_format(subjects_list, expect_list=True, error_msg='Expecting a list of subjects.')
if subjects_list:
self.assert_subject_format(subjects_list[0], expect_list=False, error_msg='Expecting a list of subjects.')
Expand Down
38 changes: 23 additions & 15 deletions osf/models/preprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ def check_unfinished_or_unpublished_version(self):
return None, None

@classmethod
def create_version(cls, create_from_guid, auth, assign_version_number=None, ignore_permission=False):
def create_version(cls, create_from_guid, auth, assign_version_number=None, ignore_permission=False, ignore_existing_versions=False):
"""Create a new version for a given preprint. `create_from_guid` can be any existing versions of the preprint
but `create_version` always finds the latest version and creates a new version from it. In addition, this
creates an "incomplete" new preprint version object using the model class and returns both the new object and
Expand All @@ -425,19 +425,21 @@ def create_version(cls, create_from_guid, auth, assign_version_number=None, igno
sentry.log_message(f'ADMIN permission for the latest version is required to create a new version: '
f'[user={auth.user._id}, guid={guid_obj._id}, latest_version={latest_version._id}]')
raise PermissionsError
unfinished_version, unpublished_version = latest_version.check_unfinished_or_unpublished_version()
if unpublished_version:
logger.error('Failed to create a new version due to unpublished pending version already exists: '
f'[version={unpublished_version.version}, '
f'_id={unpublished_version._id}, '
f'state={unpublished_version.machine_state}].')
raise UnpublishedPendingPreprintVersionExists
if unfinished_version:
logger.warning(f'Use existing initiated but unfinished version instead of creating a new one: '
f'[version={unfinished_version.version}, '
f'_id={unfinished_version._id}, '
f'state={unfinished_version.machine_state}].')
return unfinished_version, None
if not ignore_existing_versions:
unfinished_version, unpublished_version = latest_version.check_unfinished_or_unpublished_version()
if unpublished_version:
message = ('Failed to create a new version due to unpublished pending version already exists: '
f'[version={unpublished_version.version}, '
f'_id={unpublished_version._id}, '
f'state={unpublished_version.machine_state}].')
logger.error(message)
raise UnpublishedPendingPreprintVersionExists(message)
if unfinished_version:
logger.warning(f'Use existing initiated but unfinished version instead of creating a new one: '
f'[version={unfinished_version.version}, '
f'_id={unfinished_version._id}, '
f'state={unfinished_version.machine_state}].')
return unfinished_version, None

# Prepare the data to clone/update
data_to_update = {
Expand Down Expand Up @@ -536,7 +538,13 @@ def create_version(cls, create_from_guid, auth, assign_version_number=None, igno
guid_obj.save()

if latest_version.node:
preprint.set_supplemental_node(latest_version.node, auth, save=False, ignore_node_permissions=True)
preprint.set_supplemental_node(
latest_version.node,
auth,
save=False,
ignore_node_permissions=True,
ignore_permission=ignore_permission
)

return preprint, data_to_update

Expand Down
Loading