Skip to content

Commit

Permalink
standardize Triggers and States
Browse files Browse the repository at this point in the history
  • Loading branch information
John Tordoff committed Jul 18, 2024
1 parent 3690750 commit 1983681
Show file tree
Hide file tree
Showing 28 changed files with 159 additions and 229 deletions.
14 changes: 7 additions & 7 deletions api/actions/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ class BaseActionSerializer(JSONAPISerializer):

id = ser.CharField(source='_id', read_only=True)

trigger = ser.ChoiceField(choices=DefaultTriggers.char_field_choices())
trigger = ser.ChoiceField(choices=DefaultTriggers.choices())

comment = ser.CharField(max_length=65535, required=False, allow_blank=True, allow_null=True)

from_state = ser.ChoiceField(choices=DefaultStates.char_field_choices(), read_only=True)
to_state = ser.ChoiceField(choices=DefaultStates.char_field_choices(), read_only=True)
from_state = ser.ChoiceField(choices=DefaultStates.choices(), read_only=True)
to_state = ser.ChoiceField(choices=DefaultStates.choices(), read_only=True)

date_created = ser.DateTimeField(source='created', read_only=True)
date_modified = ser.DateTimeField(source='modified', read_only=True)
Expand Down Expand Up @@ -149,13 +149,13 @@ def create(self, validated_data):
visible = validated_data.get('visible', '')
try:
if trigger == DefaultTriggers.ACCEPT.db_name:
target.accept(user=user, comment=comment, permissions=permissions, visible=visible)
target.run_accept(user=user, comment=comment, permissions=permissions, visible=visible)
if trigger == DefaultTriggers.REJECT.db_name:
target.reject(user=user, comment=comment)
target.run_reject(user=user, comment=comment)
if trigger == DefaultTriggers.EDIT_COMMENT.db_name:
target.edit_comment(user=user, comment=comment)
target.run_edit_comment(user=user, comment=comment)
if trigger == DefaultTriggers.SUBMIT.db_name:
target.submit(user=user, comment=comment)
target.run_submit(user=user, comment=comment)
except InvalidTriggerError as e:
# Invalid transition from the current state
raise Conflict(str(e))
Expand Down
10 changes: 5 additions & 5 deletions api/custom_metadata/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ class CustomMetadataPermission(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
assert isinstance(obj, GuidMetadataRecord)

resource = obj.guid.referent
if isinstance(resource, BaseFileNode):
resource = resource.target
delegate_obj = obj.guid.referent
if isinstance(delegate_obj, BaseFileNode):
delegate_obj = delegate_obj.target
auth = get_user_auth(request)

if request.method in permissions.SAFE_METHODS:
return resource.is_public or resource.can_view(auth)
return delegate_obj.is_public or delegate_obj.can_view(auth)
else:
return resource.can_edit(auth)
return delegate_obj.can_edit(auth)
49 changes: 8 additions & 41 deletions api/preprints/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,10 @@
)
from osf.models import Preprint, OSFUser, PreprintContributor, Identifier
from addons.osfstorage.models import OsfStorageFolder
from osf.utils.workflows import DefaultStates
from osf.utils import permissions as osf_permissions


class CitationCanView(permissions.BasePermission):

acceptable_models = (Preprint,)

def has_object_permission(self, request, view, obj):
assert_resource_type(obj, self.acceptable_models)
auth = get_user_auth(request)
if not obj.is_published:
return obj.has_permission(auth.user, osf_permissions.ADMIN)

if not obj.is_public:
return obj.has_permission(auth.user, osf_permissions.WRITE)

if obj.is_published and obj.is_public:
return True
else:
if obj.has_permission(auth.user, osf_permissions.ADMIN):
return True

if not auth.user:
return False

return False


class PreprintPublishedOrAdmin(permissions.BasePermission):

acceptable_models = (Preprint,)
Expand All @@ -49,22 +25,13 @@ def has_object_permission(self, request, view, obj):
if auth.user is None:
return obj.verified_publishable
else:
if obj.verified_publishable:
return True

if obj.is_public and auth.user.has_perm('view_submissions', obj.provider):
return True

if obj.has_permission(auth.user, osf_permissions.ADMIN):
return True

if obj.is_contributor(auth.user):
return True

if not obj.primary_file:
return False

return False
user_has_permissions = (
obj.verified_publishable or
(obj.is_public and auth.user.has_perm('view_submissions', obj.provider)) or
obj.has_permission(auth.user, osf_permissions.ADMIN) or
(obj.is_contributor(auth.user) and obj.machine_state != DefaultStates.INITIAL.value)
)
return user_has_permissions
else:
if not obj.has_permission(auth.user, osf_permissions.ADMIN):
raise exceptions.PermissionDenied(detail='User must be an admin to make these preprint edits.')
Expand Down
28 changes: 17 additions & 11 deletions api/preprints/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from distutils.version import StrictVersion

from rest_framework import generics
from rest_framework.exceptions import MethodNotAllowed, NotFound
from rest_framework.exceptions import MethodNotAllowed, NotFound, PermissionDenied, NotAuthenticated
from rest_framework import permissions as drf_permissions

from framework.auth.oauth_scopes import CoreScopes
Expand Down Expand Up @@ -51,7 +51,6 @@
AdminOrPublic,
ContributorDetailPermissions,
PreprintFilesPermissions,
CitationCanView,
)
from api.nodes.permissions import (
ContributorOrPublic,
Expand Down Expand Up @@ -233,7 +232,6 @@ class PreprintCitationDetail(JSONAPIBaseView, generics.RetrieveAPIView, Preprint
permission_classes = (
drf_permissions.IsAuthenticatedOrReadOnly,
base_permissions.TokenHasScope,
CitationCanView,
)

required_read_scopes = [CoreScopes.PREPRINT_CITATIONS_READ]
Expand All @@ -245,7 +243,12 @@ class PreprintCitationDetail(JSONAPIBaseView, generics.RetrieveAPIView, Preprint

def get_object(self):
preprint = self.get_preprint()
return preprint.csl
auth = get_user_auth(self.request)

if preprint.can_view(auth):
return preprint.csl

raise PermissionDenied if auth.user else NotAuthenticated


class PreprintCitationStyleDetail(JSONAPIBaseView, generics.RetrieveAPIView, PreprintMixin):
Expand All @@ -254,7 +257,6 @@ class PreprintCitationStyleDetail(JSONAPIBaseView, generics.RetrieveAPIView, Pre
permission_classes = (
drf_permissions.IsAuthenticatedOrReadOnly,
base_permissions.TokenHasScope,
CitationCanView,
)

required_read_scopes = [CoreScopes.PREPRINT_CITATIONS_READ]
Expand All @@ -266,15 +268,19 @@ class PreprintCitationStyleDetail(JSONAPIBaseView, generics.RetrieveAPIView, Pre

def get_object(self):
preprint = self.get_preprint()
auth = get_user_auth(self.request)
style = self.kwargs.get('style_id')

try:
citation = render_citation(node=preprint, style=style)
except ValueError as err: # style requested could not be found
csl_name = re.findall(r'[a-zA-Z]+\.csl', str(err))[0]
raise NotFound('{} is not a known style.'.format(csl_name))
if preprint.can_view(auth):
try:
citation = render_citation(node=preprint, style=style)
except ValueError as err: # style requested could not be found
csl_name = re.findall(r'[a-zA-Z]+\.csl', str(err))[0]
raise NotFound('{} is not a known style.'.format(csl_name))

return {'citation': citation, 'id': style}

return {'citation': citation, 'id': style}
raise PermissionDenied if auth.user else NotAuthenticated


class PreprintIdentifierList(IdentifierList, PreprintMixin):
Expand Down
8 changes: 4 additions & 4 deletions api/providers/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from api.nodes.serializers import RegistrationProviderRelationshipField
from api.collections_providers.fields import CollectionProviderRelationshipField
from api.preprints.serializers import PreprintProviderRelationshipField
from api.providers.workflows import Workflows
from osf.utils.workflows import ModerationWorkflows
from api.base.metrics import MetricsSerializerMixin
from osf.models import CitationStyle
from osf.models.user import Email, OSFUser
Expand Down Expand Up @@ -115,7 +115,7 @@ class Meta:
related_view='providers:collection-providers:provider-moderator-list',
related_view_kwargs={'provider_id': '<_id>'},
)
reviews_workflow = ser.ChoiceField(choices=Workflows.choices(), read_only=True)
reviews_workflow = ser.ChoiceField(choices=ModerationWorkflows.choices(), read_only=True)

subscriptions = RelationshipField(
related_view='providers:collection-providers:notification-subscription-list',
Expand Down Expand Up @@ -166,7 +166,7 @@ class Meta:
'permissions',
])

reviews_workflow = ser.ChoiceField(choices=Workflows.choices(), read_only=True)
reviews_workflow = ser.ChoiceField(choices=ModerationWorkflows.choices(), read_only=True)
reviews_comments_anonymous = ser.BooleanField(read_only=True)
allow_updates = ser.BooleanField(read_only=True)
allow_bulk_uploads = ser.BooleanField(read_only=True)
Expand Down Expand Up @@ -216,7 +216,7 @@ class Meta:
advertise_on_discover_page = ser.BooleanField(read_only=True)

# Reviews settings are the only writable fields
reviews_workflow = ser.ChoiceField(choices=Workflows.choices())
reviews_workflow = ser.ChoiceField(choices=ModerationWorkflows.choices())
reviews_comments_private = ser.BooleanField()
reviews_comments_anonymous = ser.BooleanField()

Expand Down
30 changes: 0 additions & 30 deletions api/providers/workflows.py

This file was deleted.

2 changes: 1 addition & 1 deletion api/requests/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Meta:
])
id = ser.CharField(source='_id', read_only=True)
request_type = ser.ChoiceField(read_only=True, required=False, choices=RequestTypes.choices())
machine_state = ser.ChoiceField(read_only=True, required=False, choices=DefaultStates.char_field_choices())
machine_state = ser.ChoiceField(read_only=True, required=False, choices=DefaultStates.choices())
comment = ser.CharField(required=False, allow_blank=True, max_length=65535)
created = VersionedDateTimeField(read_only=True)
modified = VersionedDateTimeField(read_only=True)
Expand Down
3 changes: 0 additions & 3 deletions api_tests/actions/views/test_action_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,6 @@ def test_valid_transitions(
assert action.trigger == trigger

preprint.refresh_from_db()
print(trigger, preprint.provider.reviews_workflow)
print(preprint.provider.reviews_workflow)
print(preprint.machine_state)
assert preprint.machine_state == to_state
if preprint.in_public_reviews_state:
if trigger != 'edit_comment':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from django.utils import timezone

from api.providers.workflows import Workflows as ModerationWorkflows
from osf.utils.workflows import ModerationWorkflows
from osf.utils.workflows import ApprovalStates, SchemaResponseTriggers
from osf_tests.factories import (
AuthUserFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from django.utils import timezone

from api.providers.workflows import Workflows as ModerationWorkflows
from osf.utils.workflows import ModerationWorkflows

from osf.models import OSFUser
from osf.utils.workflows import ApprovalStates, SchemaResponseTriggers as Triggers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from api.base.settings.defaults import API_BASE
from api_tests.providers.mixins import ProviderListViewTestBaseMixin
from api.providers.workflows import Workflows
from osf.utils.workflows import ModerationWorkflows


from osf_tests.factories import (
Expand All @@ -20,7 +20,7 @@ def url(self, request):
@pytest.fixture
def moderated_provider(self):
provider = RegistrationProviderFactory()
provider.reviews_workflow = Workflows.PRE_MODERATION.value
provider.reviews_workflow = ModerationWorkflows.PRE_MODERATION.value
provider.save()
return provider

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from django.utils import timezone

from api.providers.workflows import Workflows as ModerationWorkflows
from osf.utils.workflows import ModerationWorkflows
from api_tests.resources.utils import configure_test_preconditions
from api_tests.utils import UserRoles
from osf.models import Outcome
Expand Down
4 changes: 2 additions & 2 deletions api_tests/registries_moderation/test_submissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from api.base.settings.defaults import API_BASE

from api.providers.workflows import Workflows
from osf.utils.workflows import ModerationWorkflows
from osf.utils.workflows import RequestTypes, RegistrationModerationTriggers, RegistrationModerationStates


Expand Down Expand Up @@ -48,7 +48,7 @@ def provider(self, moderator):
update_provider_auth_groups()
provider.schemas.add(get_default_metaschema())
provider.get_group('moderator').user_set.add(moderator)
provider.reviews_workflow = Workflows.PRE_MODERATION.value
provider.reviews_workflow = ModerationWorkflows.PRE_MODERATION.value

provider.save()

Expand Down
2 changes: 1 addition & 1 deletion api_tests/resources/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.utils import timezone

from api.providers.workflows import Workflows as ModerationWorkflows
from osf.utils.workflows import ModerationWorkflows
from api_tests.utils import UserRoles
from osf.models import Outcome
from osf.utils.outcomes import ArtifactTypes
Expand Down
2 changes: 1 addition & 1 deletion api_tests/resources/views/test_resource_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest
import responses

from api.providers.workflows import Workflows as ModerationWorkflows
from osf.utils.workflows import ModerationWorkflows
from api_tests.resources.utils import configure_test_preconditions
from api_tests.utils import UserRoles
from osf.models import NodeLog, OutcomeArtifact
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from django.utils import timezone

from api.providers.workflows import Workflows as ModerationWorkflows
from osf.utils.workflows import ModerationWorkflows

from osf.models import SchemaResponse
from osf.utils.workflows import ApprovalStates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from django.utils import timezone

from api.providers.workflows import Workflows as ModerationWorkflows
from osf.utils.workflows import ModerationWorkflows

from osf.models import SchemaResponse
from osf.utils.workflows import ApprovalStates
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
from django.utils import timezone

from api.providers.workflows import Workflows as ModerationWorkflows
from osf.utils.workflows import ModerationWorkflows
from osf_tests.factories import (
AuthUserFactory,
ProjectFactory,
Expand Down
6 changes: 3 additions & 3 deletions osf/models/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ class Meta:

creator = models.ForeignKey('OSFUser', related_name='+', on_delete=models.CASCADE)

trigger = models.CharField(max_length=31, choices=DefaultTriggers.char_field_choices())
from_state = models.CharField(max_length=31, choices=DefaultStates.char_field_choices())
to_state = models.CharField(max_length=31, choices=DefaultStates.char_field_choices())
trigger = models.CharField(max_length=31, choices=DefaultTriggers.choices())
from_state = models.CharField(max_length=31, choices=DefaultStates.choices())
to_state = models.CharField(max_length=31, choices=DefaultStates.choices())

comment = models.TextField(blank=True)

Expand Down
Loading

0 comments on commit 1983681

Please sign in to comment.