diff --git a/beat/web/common/serializers.py b/beat/web/common/serializers.py index cd52ad970de0a80311e674cee47c29ffbc2b8a55..e451ce0d32fe933e0d1c77dbbeab27ae52192da9 100644 --- a/beat/web/common/serializers.py +++ b/beat/web/common/serializers.py @@ -33,10 +33,12 @@ from django.contrib.auth.models import User from django.utils import six from rest_framework import serializers +from rest_framework import exceptions as drf_exceptions from ..team.models import Team from ..common.utils import ensure_html from ..common.utils import annotate_full_name +from ..common.utils import validate_restructuredtext from .models import Shareable, Versionable, Contribution from .exceptions import ContributionCreationError @@ -298,24 +300,55 @@ class ContributionSerializer(VersionableSerializer): # ---------------------------------------------------------- -class ContributionCreationSerializer(serializers.ModelSerializer): +class ContributionModSerializer(serializers.ModelSerializer): declaration = JSONSerializerField(required=False) description = serializers.CharField(required=False, allow_blank=True) + + class Meta: + fields = ["short_description", "description", "declaration"] + beat_core_class = None + + def validate_description(self, description): + if description.find("\\") >= 0: # was escaped, unescape + description = description.decode("string_escape") + validate_restructuredtext(description) + return description + + def validate_declaration(self, declaration): + decl = copy.deepcopy(declaration) + obj = self.Meta.beat_core_class(prefix=settings.PREFIX, data=decl) + if not obj.valid: + raise drf_exceptions.ValidationError(obj.errors) + return declaration + + def update(self, instance, validated_data): + declaration = validated_data.get("declaration") + + if declaration is not None and not instance.modifiable(): + raise drf_exceptions.PermissionDenied( + "The {} isn't modifiable anymore (either shared with someone else, or needed by an attestation)".format( + self.Meta.model.__name__.lower() + ) + ) + + return super().update(instance, validated_data) + + +# ---------------------------------------------------------- + + +class ContributionCreationSerializer(ContributionModSerializer): fork_of = serializers.JSONField(required=False) previous_version = serializers.CharField(required=False) version = serializers.IntegerField(min_value=1) - class Meta: - fields = [ + class Meta(ContributionModSerializer.Meta): + fields = ContributionModSerializer.Meta.fields + [ "name", - "short_description", - "description", - "declaration", "previous_version", "fork_of", "version", ] - beat_core_class = None def validate_fork_of(self, fork_of): if "previous_version" in self.initial_data: @@ -331,18 +364,6 @@ class ContributionCreationSerializer(serializers.ModelSerializer): ) return previous_version - def validate_description(self, description): - if description.find("\\") >= 0: # was escaped, unescape - description = description.decode("string_escape") - return description - - def validate_declaration(self, declaration): - decl = copy.deepcopy(declaration) - obj = self.Meta.beat_core_class(prefix=settings.PREFIX, data=decl) - if not obj.valid: - raise serializers.ValidationError(obj.errors) - return declaration - def validate_version(self, version): # If version is not one then it's necessarily a new version # forks start at one