Skip to content

Commit

Permalink
Issue #56: Add signals in all views
Browse files Browse the repository at this point in the history
  • Loading branch information
apragacz committed Jun 25, 2019
1 parent dd7a2a5 commit 71575fd
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 22 deletions.
8 changes: 7 additions & 1 deletion rest_registration/api/views/change_password.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from rest_framework import permissions, serializers
from rest_framework.decorators import api_view, permission_classes

from rest_registration import signals
from rest_registration.decorators import api_view_serializer_class
from rest_registration.settings import registration_settings
from rest_registration.utils.responses import get_ok_response
Expand Down Expand Up @@ -53,6 +54,11 @@ def change_password(request):
serializer.is_valid(raise_exception=True)

user = request.user
user.set_password(serializer.validated_data['password'])
password = serializer.validated_data['password']
user.set_password(password)
user.save()

signals.user_password_changed.send(
sender=change_password, user=user, password=password, request=request)

return get_ok_response('Password changed successfully')
5 changes: 5 additions & 0 deletions rest_registration/api/views/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.settings import api_settings

from rest_registration import signals
from rest_registration.decorators import (
api_view_serializer_class,
api_view_serializer_class_getter
Expand Down Expand Up @@ -39,6 +40,8 @@ def login(request):

extra_data = perform_login(request, user)

signals.user_logged_in.send(sender=login, user=user, request=request)

return get_ok_response('Login successful', extra_data=extra_data)


Expand Down Expand Up @@ -70,6 +73,8 @@ def logout(request):
except Token.DoesNotExist:
raise BadRequest('Cannot remove non-existent token')

signals.user_logged_out.send(sender=logout, user=user, request=request)

return get_ok_response('Logout successful')


Expand Down
4 changes: 4 additions & 0 deletions rest_registration/api/views/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from rest_registration import signals
from rest_registration.decorators import api_view_serializer_class_getter
from rest_registration.settings import registration_settings

Expand All @@ -25,6 +26,9 @@ def profile(request):
)
serializer.is_valid(raise_exception=True)
serializer.save()
signals.user_profile_updated.send(
sender=profile, changed_data=serializer.validated_data,
request=request)
else: # request.method == 'GET':
serializer = serializer_class(
instance=request.user,
Expand Down
30 changes: 24 additions & 6 deletions rest_registration/api/views/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,23 @@ def register(request):

kwargs = {}

email = None

if registration_settings.REGISTER_VERIFICATION_ENABLED:
verification_flag_field = get_user_setting('VERIFICATION_FLAG_FIELD')
kwargs[verification_flag_field] = False
email_field = get_user_setting('EMAIL_FIELD')
if (email_field not in serializer.validated_data
or not serializer.validated_data[email_field]):
email = serializer.validated_data.get(email_field)
if not email:
raise BadRequest("User without email cannot be verified")

user = serializer.save(**kwargs)

signals.user_registered.send(sender=None, user=user, request=request)
signals.user_registered.send(sender=register, user=user, request=request)
if email:
signals.user_email_registered.send(
sender=register, user=user, email=email, old_emails=[],
request=request)
output_serializer_class = registration_settings.REGISTER_OUTPUT_SERIALIZER_CLASS # noqa: E501
output_serializer = output_serializer_class(
instance=user,
Expand Down Expand Up @@ -111,9 +117,10 @@ def verify_registration(request):
"""
Verify registration via signature.
"""
user = process_verify_registration_data(
result = process_verify_registration_data(
request.data, serializer_context={'request': request})
signals.user_activated.send(sender=None, user=user, request=request)
signal_verify_registration(request, result)
user, _ = result
extra_data = None
if registration_settings.REGISTER_VERIFICATION_AUTO_LOGIN:
extra_data = perform_login(request, user)
Expand All @@ -139,5 +146,16 @@ def process_verify_registration_data(input_data, serializer_context=None):
user = get_user_by_verification_id(data['user_id'], require_verified=False)
setattr(user, verification_flag_field, True)
user.save()
email_field = get_user_setting('EMAIL_FIELD')
email = getattr(user, email_field)

return user, email


return user
def signal_verify_registration(request, processor_data):
user, email = processor_data
signals.user_verified.send(
sender=verify_registration, user=user, request=request)
signals.user_email_verified.send(
sender=verify_registration, user=user, email=email, old_emails=[],
request=request)
23 changes: 20 additions & 3 deletions rest_registration/api/views/register_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny, IsAuthenticated

from rest_registration import signals
from rest_registration.decorators import (
api_view_serializer_class,
api_view_serializer_class_getter
Expand Down Expand Up @@ -51,6 +52,8 @@ def register_email(request):

template_config = (
registration_settings.REGISTER_EMAIL_VERIFICATION_EMAIL_TEMPLATES)
email_field = get_user_setting('EMAIL_FIELD')
old_email = getattr(user, email_field)
if registration_settings.REGISTER_EMAIL_VERIFICATION_ENABLED:
signer = RegisterEmailSigner({
'user_id': get_user_verification_id(user),
Expand All @@ -59,10 +62,13 @@ def register_email(request):
send_verification_notification(
user, signer, template_config, email=email)
else:
email_field = get_user_setting('EMAIL_FIELD')
setattr(user, email_field, email)
user.save()

signals.user_email_registered.send(
sender=register_email, user=user, email=email, old_emails=[old_email],
request=request)

return get_ok_response('Register email link email sent')


Expand All @@ -80,8 +86,9 @@ def verify_email(request):
'''
Verify email via signature.
'''
process_verify_email_data(
result = process_verify_email_data(
request.data, serializer_context={'request': request})
signal_verify_email(request, result)
return get_ok_response('Email verified successfully')


Expand All @@ -102,5 +109,15 @@ def process_verify_email_data(input_data, serializer_context=None):

email_field = get_user_setting('EMAIL_FIELD')
user = get_user_by_verification_id(data['user_id'])
setattr(user, email_field, data['email'])
email = data['email']
old_email = getattr(user, email_field)
setattr(user, email_field, email)
user.save()
return user, email, [old_email]


def signal_verify_email(request, processor_result):
user, email, old_emails = processor_result
signals.user_email_verified.send(
sender=verify_email, user=user, email=email, old_emails=old_emails,
request=request)
16 changes: 15 additions & 1 deletion rest_registration/api/views/reset_password.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny

from rest_registration import signals
from rest_registration.decorators import (
api_view_serializer_class,
api_view_serializer_class_getter
Expand Down Expand Up @@ -74,6 +75,9 @@ def send_reset_password_link(request):
registration_settings.RESET_PASSWORD_VERIFICATION_EMAIL_TEMPLATES)
send_verification_notification(user, signer, template_config)

signals.user_password_reset_requested.send(
sender=send_reset_password_link, user=user, request=request)

return get_ok_response('Reset link sent')


Expand All @@ -91,8 +95,9 @@ def reset_password(request):
'''
Reset password, given the signature and timestamp from the link.
'''
process_reset_password_data(
result = process_reset_password_data(
request.data, serializer_context={'request': request})
signal_reset_password(request, result)
return get_ok_response('Reset password successful')


Expand All @@ -119,3 +124,12 @@ def process_reset_password_data(input_data, serializer_context=None):
raise serializers.ValidationError(exc.messages[0])
user.set_password(password)
user.save()

return user, password


def signal_reset_password(request, processor_result):
user, password = processor_result
signals.user_password_changed.send(
sender=reset_password, user=user, password=password,
request=request)
21 changes: 13 additions & 8 deletions rest_registration/contrib/verification_redirects/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
from django.views.decorators.http import require_http_methods

from rest_registration.api.views.register import (
process_verify_registration_data
process_verify_registration_data,
signal_verify_registration
)
from rest_registration.api.views.register_email import (
process_verify_email_data
process_verify_email_data,
signal_verify_email
)
from rest_registration.api.views.reset_password import (
process_reset_password_data
process_reset_password_data,
signal_reset_password
)
from rest_registration.contrib.verification_redirects.settings import \
verification_redirects_settings as vr_settings
Expand All @@ -17,7 +20,7 @@
@require_http_methods(['GET'])
def verify_registration(request):
return _generic_redirect_view(
request, process_verify_registration_data,
request, process_verify_registration_data, signal_verify_registration,
['user_id', 'signature', 'timestamp'],
vr_settings.VERIFY_REGISTRATION_SUCCESS_URL,
vr_settings.VERIFY_REGISTRATION_FAILURE_URL)
Expand All @@ -26,7 +29,7 @@ def verify_registration(request):
@require_http_methods(['GET'])
def verify_email(request):
return _generic_redirect_view(
request, process_verify_email_data,
request, process_verify_email_data, signal_verify_email,
['user_id', 'email', 'signature', 'timestamp'],
vr_settings.VERIFY_EMAIL_SUCCESS_URL,
vr_settings.VERIFY_EMAIL_FAILURE_URL)
Expand All @@ -35,22 +38,24 @@ def verify_email(request):
@require_http_methods(['POST'])
def reset_password(request):
return _generic_redirect_view(
request, process_reset_password_data,
request, process_reset_password_data, signal_reset_password,
['user_id', 'signature', 'timestamp', 'password'],
vr_settings.RESET_PASSWORD_SUCCESS_URL,
vr_settings.RESET_PASSWORD_FAILURE_URL,
use_post_method=True)


def _generic_redirect_view(
request, data_processor, data_keys, success_url, failure_url,
request, data_processor, signal_sender, data_keys,
success_url, failure_url,
use_post_method=False):
query_dict = request.POST if use_post_method else request.GET
data = {}
for key in data_keys:
data[key] = query_dict.get(key)
try:
request = data_processor(data)
processor_result = data_processor(data)
signal_sender(request, processor_result)
return redirect(success_url)
except Exception:
return redirect(failure_url)
22 changes: 19 additions & 3 deletions rest_registration/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,23 @@
from django.dispatch import Signal

# A new user has registered.
user_registered = Signal(providing_args=["user", "request"])
user_registered = Signal(providing_args=['user', 'request'])
# A user has verified / activated his or her account.
user_verified = Signal(providing_args=['user', 'request'])
# Alias for backward compatibility
user_activated = user_verified

# A user has activated his or her account.
user_activated = Signal(providing_args=["user", "request"])
user_logged_in = Signal(providing_args=['user', 'request'])
user_logged_out = Signal(providing_args=['user', 'request'])

user_password_reset_requested = Signal(providing_args=['user', 'request'])
user_password_changed = Signal(
providing_args=['user', 'password', 'request'])

user_profile_updated = Signal(
providing_args=['user', 'changed_data', 'request'])

user_email_registered = Signal(
providing_args=['user', 'email', 'old_emails', 'request'])
user_email_verified = Signal(
providing_args=['user', 'email', 'old_emails', 'request'])

0 comments on commit 71575fd

Please sign in to comment.