Skip to content

Instantly share code, notes, and snippets.

@mauroeparis
Last active August 13, 2018 18:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mauroeparis/1f457ed5edab2d15b0efd6f5e1439dab to your computer and use it in GitHub Desktop.
Save mauroeparis/1f457ed5edab2d15b0efd6f5e1439dab to your computer and use it in GitHub Desktop.
# Settings
DJOSER = {
'SEND_ACTIVATION_EMAIL': True,
'SEND_CONFIRMATION_EMAIL': True,
'SERIALIZERS': {
'user_create': 'APP_NAME.serializers.CustomUserCreateSerializer',
'activation': 'APP_NAME.serializers.CustomActivationSerializer',
},
'EMAIL': {
'activation': 'APP_NAME.email.CustomActivationEmail',
}
}
# Views
class CustomActivationView(ActivationView):
"""
Customized Djoser view in order to set `email_checked = True`
and clear the `email_activation_code` field
"""
token_generator = ActivationTokenGenerator()
def _action(self, serializer):
user = serializer.user
user.email_checked = True
user.email_activation_code = None
user.save()
signals.user_activated.send(
sender=self.__class__, user=user, request=self.request
)
if settings.SEND_CONFIRMATION_EMAIL:
context = {'user': user}
to = [get_user_email(user)]
settings.EMAIL.confirmation(self.request, context).send(to)
return Response(status=status.HTTP_204_NO_CONTENT)
# Serializers
class CustomUserCreateSerializer(UserCreateSerializer):
"""
Custom CreateSerializer from Djoser that sets `is_active = True`.
"""
def perform_create(self, validated_data):
with transaction.atomic():
user = User.objects.create_user(**validated_data)
user.is_active = True
user.save(update_fields=['is_active'])
return user
class CustomActivationSerializer(ActivationSerializer):
"""
Custom ActivationSerializer from Djoser that does not let a user
check its email twice.
"""
def validate(self, attrs):
attrs = super(ActivationSerializer, self).validate(attrs)
if not self.user.email_checked:
return attrs
raise exceptions.PermissionDenied(self.error_messages['stale_token'])
# Email
class CustomActivationEmail(BaseEmailMessage):
"""
Custom Djoser email handler that uses `ActivationTokenGenerator` in order to
activate the email after a user logs in.
"""
template_name = 'email/activation.html'
def get_context_data(self):
context = super(CustomActivationEmail, self).get_context_data()
user = context.get('user')
context['uid'] = utils.encode_uid(user.pk)
context['token'] = ActivationTokenGenerator().make_token(user)
context['url'] = settings.ACTIVATION_URL.format(**context)
return context
#Token Generator
class ActivationTokenGenerator(object):
"""
Generates and checks the Email Activation Token of a user
"""
def make_token(self, user):
"""
Generate Token, save in User model and return it
"""
token = uuid.uuid4().hex
user.email_activation_code = token
user.save()
return token
def check_token(self, user, token):
"""
Check if token is correct for a given user.
"""
if not (user and token):
return False
if user.email_activation_code == token:
return True
return False
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment