diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 73704b88f8..e6efcf3609 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -29,6 +29,7 @@ from django.utils.functional import cached_property # Django REST Framework from rest_framework.exceptions import ValidationError, PermissionDenied +from rest_framework.relations import ManyRelatedField from rest_framework import fields from rest_framework import serializers from rest_framework import validators @@ -277,6 +278,16 @@ class BaseSerializer(serializers.ModelSerializer): created = serializers.SerializerMethodField() modified = serializers.SerializerMethodField() + def __init__(self, *args, **kwargs): + super(BaseSerializer, self).__init__(*args, **kwargs) + # The following lines fix the problem of being able to pass JSON dict into PrimaryKeyRelatedField. + data = kwargs.get('data', False) + if data: + for field_name, field_instance in six.iteritems(self.fields): + if isinstance(field_instance, ManyRelatedField) and not field_instance.read_only: + if isinstance(data.get(field_name, False), dict): + raise serializers.ValidationError(_('Cannot use dictionary for %s' % field_name)) + @property def version(self): """ diff --git a/awx/main/tests/unit/api/serializers/test_primary_key_related_field.py b/awx/main/tests/unit/api/serializers/test_primary_key_related_field.py new file mode 100644 index 0000000000..0be6d3312e --- /dev/null +++ b/awx/main/tests/unit/api/serializers/test_primary_key_related_field.py @@ -0,0 +1,16 @@ +# Python +import pytest + +# Django Rest Framework +from rest_framework.exceptions import ValidationError + +# AWX +from awx.api.serializers import JobLaunchSerializer + + +def test_primary_key_related_field(): + # We are testing if the PrimaryKeyRelatedField in this serializer can take dictionary. + # PrimaryKeyRelatedField should not be able to take dictionary as input, and should raise a ValidationError. + data = {'credentials' : {'1': '2', '3':'4'}} + with pytest.raises(ValidationError): + JobLaunchSerializer(data=data)