diff --git a/api/actions/permissions.py b/api/actions/permissions.py index dec41f32c3b..9ee74565471 100644 --- a/api/actions/permissions.py +++ b/api/actions/permissions.py @@ -46,12 +46,20 @@ def has_object_permission(self, request, view, obj): else: # Moderators and node admins can trigger state changes. is_node_admin = target is not None and target.has_permission(auth.user, osf_permissions.ADMIN) - if not (is_node_admin or auth.user.has_perm('view_submissions', provider)): - return False + is_write_contributor = target is not None and target.has_permission(auth.user, osf_permissions.WRITE) - # User can trigger state changes on this reviewable, but can they use this trigger in particular? + # Validate serializer once and extract trigger serializer = view.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) trigger = serializer.validated_data.get('trigger') + + provisional_write_allowed = is_write_contributor and trigger == ReviewTriggers.SUBMIT.value + + if not (is_node_admin or auth.user.has_perm('view_submissions', provider) or provisional_write_allowed): + return False + + # User can trigger state changes on this reviewable, but can they use this trigger in particular? permission = TRIGGER_PERMISSIONS[trigger] + if permission is None and is_write_contributor and trigger == ReviewTriggers.SUBMIT.value: + return True return permission is None or request.user.has_perm(permission, target.provider)