From c537975fe00142e645d1780482909eb2913737e6 Mon Sep 17 00:00:00 2001 From: John Tordoff Date: Mon, 7 Apr 2025 12:46:48 -0400 Subject: [PATCH 1/3] [ENG-7698] Fix permission for contributor, when accepting access request #2 (#11077) ## Purpose Fix issues with addding contributors who are requested. ## Changes - makes selected permission override requested. ## Ticket https://openscience.atlassian.net/browse/ENG-7698 --- osf/utils/machines.py | 4 +-- .../test_institutional_admin_contributors.py | 30 ++++++++++++++++++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/osf/utils/machines.py b/osf/utils/machines.py index ab1c63afe49..04713b3cb26 100644 --- a/osf/utils/machines.py +++ b/osf/utils/machines.py @@ -211,9 +211,7 @@ def save_changes(self, ev): if ev.event.name == DefaultTriggers.ACCEPT.value: if not self.machineable.target.is_contributor(self.machineable.creator): - contributor_permissions = ( - self.machineable.requested_permissions or ev.kwargs.get('permissions') or permissions.READ - ) + contributor_permissions = ev.kwargs.get('permissions', self.machineable.requested_permissions) make_curator = self.machineable.request_type == NodeRequestTypes.INSTITUTIONAL_REQUEST.value visible = False if make_curator else ev.kwargs.get('visible', True) try: diff --git a/osf_tests/test_institutional_admin_contributors.py b/osf_tests/test_institutional_admin_contributors.py index a442e78565b..93ba0ac1305 100644 --- a/osf_tests/test_institutional_admin_contributors.py +++ b/osf_tests/test_institutional_admin_contributors.py @@ -146,7 +146,36 @@ def test_requested_permissions_or_default(self, app, project, institutional_admi make_curator=False, ) + def test_permissions_override_requested_permissions(self, app, project, institutional_admin): + """ + A project admin sees the requested permissions, but adds another type + """ + + node_request = project.requests.create( + creator=institutional_admin, + request_type=NodeRequestTypes.ACCESS.value, + requested_permissions=permissions.ADMIN, # Explicitly set permissions + machine_state=DefaultStates.PENDING.value, + ) + + with mock.patch('osf.models.Node.add_contributor') as mock_add_contributor: + node_request.run_accept( + user=project.creator, + comment='test comment', + ) + mock_add_contributor.assert_called_once_with( + institutional_admin, + auth=mock.ANY, + permissions=permissions.ADMIN, # `requested_permissions` should take precedence + visible=True, + send_email='access_request', + make_curator=False, + ) + def test_requested_permissions_is_used(self, app, project, institutional_admin): + """ + A project admin sees the requested permissions and doesn't override them. + """ node_request = project.requests.create( creator=institutional_admin, @@ -159,7 +188,6 @@ def test_requested_permissions_is_used(self, app, project, institutional_admin): node_request.run_accept( user=project.creator, comment='test comment', - permissions=permissions.WRITE # Default permissions to use if requested_permissions is None ) mock_add_contributor.assert_called_once_with( institutional_admin, From bd5beecf79121f098b571133f2238246682a871b Mon Sep 17 00:00:00 2001 From: "Brian J. Geiger" Date: Mon, 7 Apr 2025 17:27:20 -0400 Subject: [PATCH 2/3] Update changelog and package.json --- CHANGELOG | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 540c09878e3..5fcd0e35643 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,11 @@ We follow the CalVer (https://calver.org/) versioning scheme: YY.MINOR.MICRO. +25.06.0 (2025-04-07) +==================== + +- Bugfix and Improvements + 25.05.0 (2025-03-11) ==================== diff --git a/package.json b/package.json index 1b289a11468..e97d5265722 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "OSF", - "version": "25.05.2", + "version": "25.06.0", "description": "Facilitating Open Science", "repository": "https://github.com/CenterForOpenScience/osf.io", "author": "Center for Open Science", From 1a8d7fdcbdeeae04186a789122cd5ab3db195cb8 Mon Sep 17 00:00:00 2001 From: John Tordoff Date: Fri, 11 Apr 2025 08:06:24 -0400 Subject: [PATCH 3/3] remove DraftNodes --- api/nodes/views.py | 4 ++-- osf/models/registrations.py | 22 ++++++++-------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/api/nodes/views.py b/api/nodes/views.py index 7bc3ad929da..2c138685adb 100644 --- a/api/nodes/views.py +++ b/api/nodes/views.py @@ -212,13 +212,13 @@ class DraftMixin: def check_branched_from(self, draft): node_id = self.kwargs['node_id'] + if not draft.branched_from: + raise ValidationError('This draft registration is not created from the given node.') if not draft.branched_from._id == node_id: raise ValidationError('This draft registration is not created from the given node.') def check_resource_permissions(self, resource): # If branched from a node, use the node's contributor permissions. See [ENG-1563] - if resource.branched_from_type == 'Node': - resource = resource.branched_from return self.check_object_permissions(self.request, resource) def get_draft(self, draft_id=None, check_object_permissions=True): diff --git a/osf/models/registrations.py b/osf/models/registrations.py index f7b017d9ddf..b20236c9d8e 100644 --- a/osf/models/registrations.py +++ b/osf/models/registrations.py @@ -1269,27 +1269,21 @@ def create_from_node(cls, user, schema, node=None, data=None, provider=None): provider.validate_schema(schema) excluded_attributes = [] - if node: - branched_from = node - else: - branched_from = DraftNode.objects.create(creator=user, title=settings.DEFAULT_DRAFT_NODE_TITLE) - excluded_attributes.append('title') - - if not isinstance(branched_from, (Node, DraftNode)): - raise DraftRegistrationStateError() draft = cls( initiator=user, - branched_from=branched_from, + branched_from=node, registration_schema=schema, registration_metadata=data or {}, provider=provider, ) draft.save() - draft.copy_editable_fields( - branched_from, - excluded_attributes=excluded_attributes - ) + if node: + draft.copy_editable_fields( + node, + excluded_attributes=excluded_attributes + ) + draft.update(data, auth=Auth(user)) if not node: @@ -1501,7 +1495,7 @@ def create_django_groups_for_draft_registration(sender, instance, created, **kwa initiator = instance.initiator - if instance.branched_from.contributor_set.filter(user=initiator).exists(): + if instance.branched_from and instance.branched_from.contributor_set.filter(user=initiator).exists(): initiator_node_contributor = instance.branched_from.contributor_set.get(user=initiator) initiator_visibility = initiator_node_contributor.visible initiator_order = initiator_node_contributor._order