diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index 950c5ad53..8deb1c1f0 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -14,6 +14,7 @@ Unreleased Added ----- - Allow overriding docker image prefix via environment variable +- Allow staff users to create new ``Variant`` objects through the API endpoint Changed ------- diff --git a/resolwe_bio/variants/serializers.py b/resolwe_bio/variants/serializers.py index e94f97d39..c6fc1e98b 100644 --- a/resolwe_bio/variants/serializers.py +++ b/resolwe_bio/variants/serializers.py @@ -27,6 +27,7 @@ class Meta: """Serializer configuration.""" model = Variant + optional_fields = ["annotation"] fields = [ "id", "species", @@ -37,6 +38,7 @@ class Meta: "alternative", "annotation", ] + extra_kwargs = {"annotation": {"required": False}} class VariantTranscriptSerializer(SelectiveFieldMixin, serializers.ModelSerializer): diff --git a/resolwe_bio/variants/tests/test_variant.py b/resolwe_bio/variants/tests/test_variant.py index d52f5d1bc..849f731b6 100644 --- a/resolwe_bio/variants/tests/test_variant.py +++ b/resolwe_bio/variants/tests/test_variant.py @@ -562,9 +562,54 @@ def test_add_variant_annotations(self): class VariantTest(PrepareDataMixin, TestCase): def setUp(self) -> None: - self.view = VariantViewSet.as_view({"get": "list"}) + self.view = VariantViewSet.as_view({"get": "list", "post": "create"}) return super().setUp() + def test_create(self): + """Test the Variant creation. + + Only users with staff status are allowed to create Variant objects. + """ + variant_data = { + "species": "Homo Sapiens", + "genome_assembly": "test_create", + "chromosome": "CHR_test_create", + "position": 1, + "reference": "test_create", + "alternative": "alt_test_create", + } + + # Test creation as unauthenticated user. + request = APIRequestFactory().post("/variant", variant_data, format="json") + response = self.view(request) + self.assertContains( + response, + "Authentication credentials were not provided.", + status_code=status.HTTP_403_FORBIDDEN, + ) + + # Test creation as non-staff user. + request = APIRequestFactory().post("/variant", variant_data, format="json") + force_authenticate(request, self.contributor) + response = self.view(request) + self.assertContains( + response, + "You do not have permission to perform this action.", + status_code=status.HTTP_403_FORBIDDEN, + ) + + # Test creation as staff user. + self.contributor.is_staff = True + self.contributor.save(update_fields=["is_staff"]) + request = APIRequestFactory().post("/variant", variant_data, format="json") + force_authenticate(request, self.contributor) + response = self.view(request) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # Check that the created object exists. + Variant.objects.get(**response.data) + self.contributor.is_staff = False + self.contributor.save(update_fields=["is_staff"]) + def test_filter(self): """Test the Variant filter.""" request = APIRequestFactory().get("/variant") diff --git a/resolwe_bio/variants/views.py b/resolwe_bio/variants/views.py index b322120b0..dca5e0c66 100644 --- a/resolwe_bio/variants/views.py +++ b/resolwe_bio/variants/views.py @@ -9,11 +9,6 @@ import logging import django_filters as filters -from rest_framework import mixins, viewsets - -from resolwe.flow.filters import OrderingFilter -from resolwe.flow.views.mixins import ResolweCreateModelMixin - from resolwe_bio.variants.filters import ( VariantAnnotationFilter, VariantCallFilter, @@ -26,6 +21,11 @@ VariantExperimentSerializer, VariantSerializer, ) +from rest_framework import mixins, viewsets + +from resolwe.flow.filters import OrderingFilter +from resolwe.flow.views.mixins import ResolweCreateModelMixin +from resolwe.flow.views.utils import IsStaffOrReadOnly from .models import Variant, VariantAnnotation, VariantCall, VariantExperiment @@ -40,6 +40,7 @@ class VariantViewSet( queryset = Variant.objects.all() serializer_class = VariantSerializer filter_backends = [filters.rest_framework.DjangoFilterBackend, OrderingFilter] + permission_classes = (IsStaffOrReadOnly,) filterset_class = VariantFilter ordering_fields = ("species", "genome_assembly", "position", "chromosome")