Skip to content
This repository has been archived by the owner on Oct 22, 2019. It is now read-only.

Commit

Permalink
Added signup redirect url parameter
Browse files Browse the repository at this point in the history
This works the same as the signin redirect. If a user was trying
to access a page and gets redirected to sign in or sign up,
after succeeding they will be redirected from where they came.

Since a user can only be redirected to either the signin or signup
page, it is beyond the scope of this feature to pass the query
parameter in the url to the other page when requested.

Updated signup redirect to work like signin

Added signup redirect for SIGNIN_AFTER_SIGNUP
  • Loading branch information
Rsgm committed Aug 29, 2016
1 parent c301ab5 commit 2f35219
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 20 deletions.
7 changes: 6 additions & 1 deletion userena/forms.py
Expand Up @@ -45,6 +45,10 @@ class SignupForm(forms.Form):
render_value=False),
label=_("Repeat password"))

def __init__(self, redirect=None, *args, **kwargs):
self.redirect = redirect
super(SignupForm, self).__init__(*args, **kwargs)

def clean_username(self):
"""
Validate that the username is alphanumeric and is not already in use.
Expand Down Expand Up @@ -94,7 +98,8 @@ def save(self):
email,
password,
not userena_settings.USERENA_ACTIVATION_REQUIRED,
userena_settings.USERENA_ACTIVATION_REQUIRED)
userena_settings.USERENA_ACTIVATION_REQUIRED,
redirect=self.redirect)
return new_user

class SignupFormOnlyEmail(SignupForm):
Expand Down
4 changes: 2 additions & 2 deletions userena/managers.py
Expand Up @@ -36,7 +36,7 @@ class UserenaManager(UserManager):
""" Extra functionality for the Userena model. """

def create_user(self, username, email, password, active=False,
send_email=True):
send_email=True, redirect=None):
"""
A simple wrapper that creates a new :class:`User`.
Expand Down Expand Up @@ -78,7 +78,7 @@ def create_user(self, username, email, password, active=False,
userena_profile = self.create_userena_profile(new_user)

if send_email:
userena_profile.send_activation_email()
userena_profile.send_activation_email(redirect=redirect)

return new_user

Expand Down
7 changes: 4 additions & 3 deletions userena/models.py
Expand Up @@ -156,11 +156,11 @@ def activation_key_expired(self):
return True
return False

def send_activation_email(self):
def send_activation_email(self, redirect=None):
"""
Sends a activation email to the user.
This email is send when the user wants to activate their newly created
This email is sent when the user wants to activate their newly created
user.
"""
Expand All @@ -169,7 +169,8 @@ def send_activation_email(self):
'protocol': get_protocol(),
'activation_days': userena_settings.USERENA_ACTIVATION_DAYS,
'activation_key': self.activation_key,
'site': Site.objects.get_current()}
'site': Site.objects.get_current(),
'redirect': redirect}

mailer = UserenaConfirmationMail(context=context)
mailer.generate_mail("activation")
Expand Down
Expand Up @@ -5,7 +5,7 @@
{% blocktrans with site.name as site %}<p>Thank you for signing up at {{ site }}.</p>{% endblocktrans %}
<p>
{% trans "To activate your account you should click on the link below:" %}<br />
{{ protocol }}://{{ site.domain }}{% url 'userena_activate' activation_key %}
{{ protocol }}://{{ site.domain }}{% url 'userena_activate' activation_key %}{% if redirect %}?next={{redirect}}{% endif %}
</p>
<p>
{% trans "Thanks for using our site!" %}<br />
Expand Down
Expand Up @@ -5,7 +5,7 @@

{% trans "To activate your account you should click on the link below:" %}

{{ protocol }}://{{ site.domain }}{% url 'userena_activate' activation_key %}
{{ protocol }}://{{ site.domain }}{% url 'userena_activate' activation_key %}{% if redirect %}?next={{redirect}}{% endif %}

{% trans "Thanks for using our site!" %}

Expand Down
1 change: 1 addition & 0 deletions userena/templates/userena/signup_form.html
Expand Up @@ -25,5 +25,6 @@
{% endfor %}
</fieldset>
<input type="submit" value="{% trans "Signup"%}" />
{% if next %}<input type="hidden" name="next" value="{{ next }}" />{% endif %}
</form>
{% endblock %}
26 changes: 25 additions & 1 deletion userena/tests/tests_views.py
@@ -1,7 +1,7 @@
import re

from datetime import datetime, timedelta
from django.contrib.auth import get_user_model
from django.contrib.auth import get_user_model, REDIRECT_FIELD_NAME
from django.core.urlresolvers import reverse
from django.core import mail
from django.contrib.auth.forms import PasswordChangeForm
Expand Down Expand Up @@ -36,6 +36,30 @@ def test_valid_activation(self):
user = User.objects.get(email='alice@example.com')
self.assertTrue(user.is_active)

def test_activation_redirect(self):
""" A ``GET`` to the activation view with redirect parameter """

redirect = '/some/url/'

# First, register an account.
self.client.post('%s?%s=%s' % (reverse('userena_signup'), REDIRECT_FIELD_NAME, redirect),
data={'username': 'alice',
'email': 'alice@example.com',
'password1': 'swordfish',
'password2': 'swordfish',
'tos': 'on'})
user = User.objects.get(email='alice@example.com')

# Send a GET request with the redirect parameter to the url
response = self.client.get(
'%s?%s=%s' % (reverse('userena_activate', kwargs={'activation_key': user.userena_signup.activation_key}),
REDIRECT_FIELD_NAME, redirect))

self.assertTrue(response.get('Location').endswith(redirect))

if hasattr(response, 'url'):
self.assertTrue(response.url.endswith(redirect))

def test_activation_expired_retry(self):
""" A ``GET`` to the activation view when activation link is expired """
# First, register an account.
Expand Down
44 changes: 33 additions & 11 deletions userena/views.py
Expand Up @@ -75,13 +75,14 @@ def get_queryset(self):
@secure_required
def signup(request, signup_form=SignupForm,
template_name='userena/signup_form.html', success_url=None,
extra_context=None):
extra_context=None, redirect_field_name=REDIRECT_FIELD_NAME):
"""
Signup of an account.
Signup requiring a username, email and password. After signup a user gets
an email with an activation link used to activate their account. After
successful signup redirects to ``success_url``.
successful signup redirects to the ``REDIRECT_FIELD_NAME`` query parameter
if provided, otherwise ``success_url``.
:param signup_form:
Form that will be used to sign a user. Defaults to userena's
Expand All @@ -101,10 +102,16 @@ def signup(request, signup_form=SignupForm,
context. Defaults to a dictionary with a ``form`` key containing the
``signup_form``.
:param redirect_field_name:
String containing the name of the field that contains a redirect url.
Defaults to ``next``.
**Context**
``form``
Form supplied by ``signup_form``.
``next``
Next supplied by a query parameter.
"""
# If signup is disabled, return 403
Expand All @@ -118,16 +125,18 @@ def signup(request, signup_form=SignupForm,

form = signup_form()

redirect_url = request.GET.get(redirect_field_name, request.POST.get(redirect_field_name, None))

if request.method == 'POST':
form = signup_form(request.POST, request.FILES)
form = signup_form(redirect=redirect_url, data=request.POST, files=request.FILES)

if form.is_valid():
user = form.save()

# Send the signup complete signal
userena_signals.signup_complete.send(sender=None,
user=user)


if success_url: redirect_to = success_url
else: redirect_to = reverse('userena_signup_complete',
kwargs={'username': user.username})
Expand All @@ -141,28 +150,38 @@ def signup(request, signup_form=SignupForm,
user = authenticate(identification=user.email, check_password=False)
login(request, user)

# since we signed in the user and have no more information to display,
# we can redirect the user to a requested page
if redirect_url:
redirect_to = redirect_url

return redirect(redirect_to)

if not extra_context: extra_context = dict()
extra_context['form'] = form
extra_context.update({
'form': form,
'next': redirect_url,
})
return ExtraContextTemplateView.as_view(template_name=template_name,
extra_context=extra_context)(request)

@secure_required
def activate(request, activation_key,
template_name='userena/activate_fail.html',
retry_template_name='userena/activate_retry.html',
success_url=None, extra_context=None):
success_url=None, extra_context=None,
redirect_field_name=REDIRECT_FIELD_NAME):
"""
Activate a user with an activation key.
The key is a SHA1 string. When the SHA1 is found with an
:class:`UserenaSignup`, the :class:`User` of that account will be
activated. After a successful activation the view will redirect to
``success_url``. If the SHA1 is not found, the user will be shown the
``template_name`` template displaying a fail message.
If the SHA1 is found but expired, ``retry_template_name`` is used instead,
so the user can proceed to :func:`activate_retry` to get a new activation key.
the ``REDIRECT_FIELD_NAME`` query parameter if provided, otherwise
``success_url``. If the SHA1 is not found, the user will be shown the
``template_name`` template displaying a fail message. If the SHA1 is found
but expired, ``retry_template_name`` is used instead, so the user can
proceed to :func:`activate_retry` to get a new activation key.
:param activation_key:
String of a SHA1 string of 40 characters long. A SHA1 is always 160bit
Expand Down Expand Up @@ -204,7 +223,10 @@ def activate(request, activation_key,
messages.success(request, _('Your account has been activated and you have been signed in.'),
fail_silently=True)

if success_url: redirect_to = success_url % {'username': user.username }
redirect_to = request.GET.get(redirect_field_name, None)

if redirect_to: pass
elif success_url: redirect_to = success_url % {'username': user.username }
else: redirect_to = reverse('userena_profile_detail',
kwargs={'username': user.username})
return redirect(redirect_to)
Expand Down

0 comments on commit 2f35219

Please sign in to comment.