class BadgeRecipientSerializerV2(BaseSerializerV2): identity = serializers.CharField(source='recipient_identifier') hashed = serializers.NullBooleanField(default=None, required=False) type = serializers.ChoiceField( choices=BadgeInstance.RECIPIENT_TYPE_CHOICES, default=BadgeInstance.RECIPIENT_TYPE_EMAIL, required=False, source='recipient_type') plaintextIdentity = serializers.CharField(source='recipient_identifier', read_only=True, required=False) VALIDATORS = { BadgeInstance.RECIPIENT_TYPE_EMAIL: EmailValidator(), BadgeInstance.RECIPIENT_TYPE_URL: URLValidator(), BadgeInstance.RECIPIENT_TYPE_ID: URLValidator(), BadgeInstance.RECIPIENT_TYPE_TELEPHONE: TelephoneValidator(), } HASHED_DEFAULTS = { BadgeInstance.RECIPIENT_TYPE_EMAIL: True, BadgeInstance.RECIPIENT_TYPE_URL: False, BadgeInstance.RECIPIENT_TYPE_ID: False, BadgeInstance.RECIPIENT_TYPE_TELEPHONE: True, } def validate(self, attrs): recipient_type = attrs.get('recipient_type') recipient_identifier = attrs.get('recipient_identifier') hashed = attrs.get('hashed') if recipient_type in self.VALIDATORS: try: self.VALIDATORS[recipient_type](recipient_identifier) except DjangoValidationError as e: raise serializers.ValidationError(e.message) if hashed is None: attrs['hashed'] = self.HASHED_DEFAULTS.get(recipient_type, True) return attrs def to_representation(self, instance): representation = super(BadgeRecipientSerializerV2, self).to_representation(instance) if instance.hashed: representation['salt'] = instance.salt representation['identity'] = generate_sha256_hashstring( instance.recipient_identifier.lower(), instance.salt) return representation
def validate(self, data): recipient_type = data.get('recipient_type') if data.get('recipient_identifier') and data.get('email') is None: if recipient_type == RECIPIENT_TYPE_EMAIL: recipient_validator = EmailValidator() elif recipient_type in (RECIPIENT_TYPE_URL, RECIPIENT_TYPE_ID): recipient_validator = URLValidator() else: recipient_validator = TelephoneValidator() try: recipient_validator(data['recipient_identifier']) except DjangoValidationError as e: raise serializers.ValidationError(e.message) elif data.get('email') and data.get('recipient_identifier') is None: data['recipient_identifier'] = data.get('email') allow_duplicate_awards = data.pop('allow_duplicate_awards') if allow_duplicate_awards is False and self.context.get( 'badgeclass') is not None: previous_awards = BadgeInstance.objects.filter( recipient_identifier=data['recipient_identifier'], badgeclass=self.context['badgeclass']).filter( Q(expires_at__isnull=True) | Q(expires_at__lt=timezone.now())) if previous_awards.exists(): raise serializers.ValidationError( "A previous award of this badge already exists for this recipient." ) hashed = data.get('hashed', None) if hashed is None: if recipient_type in (RECIPIENT_TYPE_URL, RECIPIENT_TYPE_ID): data['hashed'] = False else: data['hashed'] = True return data
class BadgeRecipientSerializerV2(BaseSerializerV2): identity = serializers.CharField(source='recipient_identifier') hashed = serializers.NullBooleanField(default=None, required=False) type = serializers.ChoiceField( choices=BadgeInstance.RECIPIENT_TYPE_CHOICES, default=RECIPIENT_TYPE_EMAIL, required=False, source='recipient_type') plaintextIdentity = serializers.CharField(source='recipient_identifier', read_only=True, required=False) VALIDATORS = { RECIPIENT_TYPE_EMAIL: EmailValidator(), RECIPIENT_TYPE_URL: URLValidator(), RECIPIENT_TYPE_ID: URLValidator(), RECIPIENT_TYPE_TELEPHONE: TelephoneValidator(), } HASHED_DEFAULTS = { RECIPIENT_TYPE_EMAIL: True, RECIPIENT_TYPE_URL: False, RECIPIENT_TYPE_ID: False, RECIPIENT_TYPE_TELEPHONE: True, } class Meta: apispec_definition = ('BadgeRecipient', { 'properties': OrderedDict([ ('identity', { 'type': 'string', 'format': 'string', 'description': 'Either the hash of the identity or the plaintext value' }), ('type', { 'type': 'string', 'enum': [c[0] for c in BadgeInstance.RECIPIENT_TYPE_CHOICES], 'description': "Type of identifier used to identify recipient" }), ('hashed', { 'type': 'boolean', 'description': "Whether or not the identity value is hashed." }), ('plaintextIdentity', { 'type': 'string', 'description': "The plaintext identity" }), ]), }) def validate(self, attrs): recipient_type = attrs.get('recipient_type') recipient_identifier = attrs.get('recipient_identifier') hashed = attrs.get('hashed') if recipient_type in self.VALIDATORS: try: self.VALIDATORS[recipient_type](recipient_identifier) except DjangoValidationError as e: raise serializers.ValidationError(e.message) if hashed is None: attrs['hashed'] = self.HASHED_DEFAULTS.get(recipient_type, True) return attrs def to_representation(self, instance): representation = super(BadgeRecipientSerializerV2, self).to_representation(instance) if instance.hashed: representation['salt'] = instance.salt representation['identity'] = generate_sha256_hashstring( instance.recipient_identifier, instance.salt) return representation