serializers.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. from django.conf import settings
  2. from django.utils.translation import gettext_lazy as _
  3. from rest_framework import serializers, exceptions
  4. from dj_rest_auth.serializers import PasswordResetSerializer
  5. from dj_rest_auth.registration.serializers import (
  6. SocialAccountSerializer as BaseSocialAccountSerializer,
  7. )
  8. from allauth.socialaccount.models import SocialApp
  9. from allauth.account.adapter import get_adapter
  10. from allauth.account import app_settings
  11. from allauth.account.utils import filter_users_by_email
  12. from allauth.account.models import EmailAddress
  13. from .utils import is_user_registration_open
  14. from .models import User
  15. from .forms import PasswordSetAndResetForm
  16. class SocialAccountSerializer(BaseSocialAccountSerializer):
  17. email = serializers.SerializerMethodField()
  18. username = serializers.SerializerMethodField()
  19. class Meta(BaseSocialAccountSerializer.Meta):
  20. fields = (
  21. "id",
  22. "provider",
  23. "uid",
  24. "last_login",
  25. "date_joined",
  26. "email",
  27. "username",
  28. )
  29. def get_email(self, obj):
  30. if obj.extra_data:
  31. if "email" in obj.extra_data:
  32. return obj.extra_data.get("email")
  33. return obj.extra_data.get("userPrincipalName") # MS oauth uses this
  34. def get_username(self, obj):
  35. if obj.extra_data:
  36. return obj.extra_data.get("username")
  37. class SocialAppSerializer(serializers.ModelSerializer):
  38. class Meta:
  39. model = SocialApp
  40. fields = ("provider", "name", "client_id")
  41. class ConfirmEmailAddressSerializer(serializers.Serializer):
  42. email = serializers.EmailField()
  43. class EmailAddressSerializer(serializers.ModelSerializer):
  44. isPrimary = serializers.BooleanField(source="primary", read_only=True)
  45. email = serializers.EmailField() # Remove default unique validation
  46. isVerified = serializers.BooleanField(source="verified", read_only=True)
  47. class Meta:
  48. model = EmailAddress
  49. fields = ("isPrimary", "email", "isVerified")
  50. def clean_email(self):
  51. """ Validate email as done in allauth.account.forms.AddEmailForm """
  52. value = self.cleaned_data["email"]
  53. value = get_adapter().clean_email(value)
  54. errors = {
  55. "this_account": _(
  56. "This e-mail address is already associated" " with this account."
  57. ),
  58. "different_account": _(
  59. "This e-mail address is already associated" " with another account."
  60. ),
  61. }
  62. users = filter_users_by_email(value)
  63. on_this_account = [u for u in users if u.pk == self.user.pk]
  64. on_diff_account = [u for u in users if u.pk != self.user.pk]
  65. if on_this_account:
  66. raise serializers.ValidationError(errors["this_account"])
  67. if on_diff_account and app_settings.UNIQUE_EMAIL:
  68. raise serializers.ValidationError(errors["different_account"])
  69. return value
  70. def validate(self, data):
  71. if self.context["request"].method == "POST":
  72. # Run extra validation on create
  73. self.user = self.context["request"].user
  74. self.cleaned_data = data
  75. data["email"] = self.clean_email()
  76. return data
  77. def create(self, validated_data):
  78. return EmailAddress.objects.add_email(
  79. self.context["request"], self.user, validated_data["email"], confirm=True
  80. )
  81. def update(self, instance, validated_data):
  82. instance.primary = True
  83. instance.save()
  84. return instance
  85. class UserSerializer(serializers.ModelSerializer):
  86. username = serializers.CharField(source="email", read_only=True)
  87. lastLogin = serializers.DateTimeField(source="last_login", read_only=True)
  88. isSuperuser = serializers.BooleanField(source="is_superuser")
  89. emails = EmailAddressSerializer(many=True, default=[])
  90. identities = SocialAccountSerializer(
  91. source="socialaccount_set", many=True, read_only=True
  92. )
  93. id = serializers.CharField()
  94. isActive = serializers.BooleanField(source="is_active")
  95. dateJoined = serializers.DateTimeField(source="created", read_only=True)
  96. hasPasswordAuth = serializers.BooleanField(
  97. source="has_usable_password", read_only=True
  98. )
  99. class Meta:
  100. model = User
  101. fields = (
  102. "username",
  103. "lastLogin",
  104. "isSuperuser",
  105. "emails",
  106. "identities",
  107. "id",
  108. "isActive",
  109. "name",
  110. "dateJoined",
  111. "hasPasswordAuth",
  112. "email",
  113. )
  114. class UserNotificationsSerializer(serializers.ModelSerializer):
  115. subscribeByDefault = serializers.BooleanField(source="subscribe_by_default")
  116. class Meta:
  117. model = User
  118. fields = ("subscribeByDefault",)
  119. class NoopTokenSerializer(serializers.Serializer):
  120. """ dj-rest-auth requires tokens, but we don't use them. """
  121. class PasswordSetResetSerializer(PasswordResetSerializer):
  122. password_reset_form_class = PasswordSetAndResetForm
  123. def save(self):
  124. request = self.context.get("request")
  125. opts = {
  126. "use_https": request.is_secure(),
  127. "from_email": getattr(settings, "DEFAULT_FROM_EMAIL"),
  128. "request": request,
  129. "subject_template_name": "registration/password_reset_subject.txt",
  130. "email_template_name": "registration/password_reset_email.txt",
  131. "html_email_template_name": "registration/password_reset_email.html",
  132. }
  133. opts.update(self.get_email_options())
  134. self.reset_form.save(**opts)