Created
October 31, 2018 14:26
-
-
Save ferndot/8938f7ab66d5f38f6f9449ea86e1c871 to your computer and use it in GitHub Desktop.
django-simple-email-confirmation-drf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.conf import settings | |
from templated_mail.mail import BaseEmailMessage | |
class VerificationEmail(BaseEmailMessage): | |
template_name = 'email/email_verification.html' | |
def get_context_data(self): | |
# Get context and user | |
context = super().get_context_data() | |
user = context.get('user') | |
# Add needed context variables | |
context['uid'] = user.pk | |
context['url'] = settings.EMAIL_VERIFICATION_URL.format(**context) | |
return context |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.conf import settings | |
from django.contrib.auth.models import AbstractUser | |
from simple_email_confirmation.models import ( | |
SimpleEmailConfirmationUserMixin, | |
EmailAddress, | |
) | |
from . import emails | |
class User( | |
SimpleEmailConfirmationUserMixin, | |
AbstractUser, | |
): | |
# Other stuff | |
def send_confirmation_email(self, email): | |
if hasattr(settings, 'EMAIL_VERIFICATION_URL'): | |
# Send email | |
token = EmailAddress.objects.get(user=self, email=email).key | |
emails.VerificationEmail(context={ | |
'user': self, | |
'token': token, | |
}).send(to=[email]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rest_framework import serializers | |
from simple_email_confirmation.models import EmailAddress | |
class EmailAddressSerializer(serializers.ModelSerializer): | |
class Meta: | |
model = EmailAddress | |
fields = ( | |
'pk', | |
'email', | |
'is_confirmed', | |
'is_primary', | |
) | |
class ConfirmEmailAddressSerializer(serializers.Serializer): | |
confirmation_key = serializers.CharField() | |
class SetPrimaryEmailAddressSerializer(serializers.Serializer): | |
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.dispatch import receiver | |
from simple_email_confirmation.signals import unconfirmed_email_created | |
@receiver(unconfirmed_email_created) | |
def send_confirmation_email(sender, email, **kwargs): | |
sender.send_confirmation_email(email) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import IntegrityError | |
from rest_framework import viewsets, status, serializers as drf_serializers | |
from rest_framework.response import Response | |
from rest_framework.decorators import action | |
from simple_email_confirmation.models import EmailAddress | |
from simple_email_confirmation.exceptions import ( | |
EmailConfirmationExpired, EmailIsPrimary, EmailNotConfirmed, | |
) | |
from . import serializers | |
class EmailViewSet(viewsets.ModelViewSet): | |
serializer_class = serializers.EmailAddressSerializer | |
def get_queryset(self): | |
return EmailAddress.objects.filter(user=self.request.user) | |
def get_serializer_class(self): | |
if self.action == 'send_confirmation': | |
return drf_serializers.Serializer() | |
elif self.action == 'confirm': | |
return serializers.ConfirmEmailAddressSerializer | |
elif self.action == 'set_primary': | |
return serializers.SetPrimaryEmailAddressSerializer | |
return super().get_serializer_class() | |
def create(self, request, *args, **kwargs): | |
try: | |
# Add the new unconfirmed email | |
request.user.add_unconfirmed_email(request.data['email']) | |
return Response({'status': 'success'}) | |
except IntegrityError: | |
return Response( | |
{'errors': ['Email already exists']}, | |
status=status.HTTP_400_BAD_REQUEST, | |
) | |
def destroy(self, request, *args, **kwargs): | |
email = self.get_object() | |
try: | |
# Delete the email | |
request.user.remove_email(email.email) | |
return Response({'status': 'success'}) | |
except EmailIsPrimary: | |
return Response( | |
{'errors': ['Cannot delete the primary email']}, | |
status=status.HTTP_400_BAD_REQUEST, | |
) | |
@action(methods=['post'], detail=True) | |
def send_confirmation(self, request, pk=None): | |
""" | |
Send a confirmation email. | |
""" | |
# Retrive email | |
email = self.get_object() | |
# Confirm email | |
email.user.reset_email_confirmation(email.email) | |
email.user.send_confirmation_email(email.email) | |
# Success! | |
return Response({'status': 'success'}) | |
@action(methods=['post'], detail=True) | |
def confirm(self, request, pk=None): | |
""" | |
Confirm an email. | |
""" | |
# Retrive email | |
email = self.get_object() | |
try: | |
# Confirm email | |
serializer = self.get_serializer(data=request.data) | |
serializer.is_valid(raise_exception=True) | |
email.user.confirm_email( | |
confirmation_key=serializer.data['confirmation_key'] | |
) | |
# Success! | |
return Response({'status': 'success'}) | |
except (EmailConfirmationExpired, EmailAddress.DoesNotExist): | |
return Response( | |
{'errors': ['Confirmation key is not valid']}, | |
status=status.HTTP_400_BAD_REQUEST, | |
) | |
@action(methods=['patch'], detail=True) | |
def set_primary(self, request, pk=None): | |
""" | |
Set an email as primary. | |
""" | |
# Retrive email | |
email = self.get_object() | |
try: | |
# Set email as primary | |
email.user.set_primary_email(email.email) | |
# Success! | |
return Response({'status': 'success'}) | |
except EmailNotConfirmed: | |
return Response( | |
{'errors': [ | |
'Email must be confirmed before it can be set as primary' | |
]}, | |
status=status.HTTP_400_BAD_REQUEST, | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment