12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- from rest_framework import serializers
- from rest_framework.validators import UniqueTogetherValidator
- from desecapi.models import BaseFactor, TOTPFactor
- class TOTPFactorSerializer(serializers.ModelSerializer):
- user = serializers.HiddenField(default=serializers.CurrentUserDefault())
- class Meta:
- model = TOTPFactor
- fields = ("id", "created", "last_used", "name", "secret", "uri", "user")
- read_only_fields = ("id", "created", "last_used", "secret", "uri", "user")
- extra_kwargs = {
- # needed for uniqueness, https://github.com/encode/django-rest-framework/issues/7489
- "name": {"default": ""}
- }
- validators = [
- UniqueTogetherValidator(
- queryset=BaseFactor.objects.all(),
- fields=["user", "name"],
- message="An authentication factor with this name already exists.",
- )
- ]
- def __init__(self, *args, include_secret=False, **kwargs):
- self.include_secret = include_secret
- return super().__init__(*args, **kwargs)
- def get_fields(self):
- fields = super().get_fields()
- if not self.include_secret:
- fields.pop("secret")
- fields.pop("uri")
- return fields
- def to_representation(self, instance):
- ret = super().to_representation(instance)
- if "secret" in ret:
- ret["secret"] = instance.base32_secret
- return ret
- class TOTPCodeSerializer(serializers.Serializer):
- # length requirements preserve leading zeros
- code = serializers.RegexField("^[0-9]+$", max_length=6, min_length=6)
- class Meta:
- fields = ("code",)
- def validate_code(self, value):
- factor = self.context["view"].get_object()
- if not factor.verify(value):
- raise serializers.ValidationError("Invalid code.")
- return value
|