Commit 9fd580f7 authored by Simon Hanna's avatar Simon Hanna

Allow anonymous subscriptions

parent 6c54484e
......@@ -219,6 +219,24 @@ class ListSubscribe(forms.Form):
for address in user_emails)
class ListAnonymousSubscribe(forms.Form):
"""Form fields to join an existing list as an anonymous user.
"""
email = forms.CharField(
label=_('Your email address'),
validators=[validate_email],
error_messages={
'required': _('Please enter an email address.'),
'invalid': _('Please enter a valid email address.')})
display_name = forms.CharField(
label=_('Your name (optional)'), required=False)
def __init__(self, *args, **kwargs):
super(ListAnonymousSubscribe, self).__init__(*args, **kwargs)
class ListSettingsForm(forms.Form):
"""
Base class for list settings forms.
......
......@@ -70,8 +70,23 @@
</form>
{% endif %}
{% else %}
<p>{% trans 'If you want to subscribe to this list, you have to log in first.' %}</p>
<div>
<p>{% trans 'If you want to subscribe to this list and you have an account, please log in first.' %}</p>
<p><a href="{% url LOGIN_URL %}?next={{ next|default:request.path|urlencode }}" class="btn btn-primary">{% trans 'Log In' %}</a></p>
</div>
<hr />
<div>
<p>
{% blocktrans %}
However you can also subscribe without creating an account.
If you wish to to so, please use the form below.
{% endblocktrans%}
</p>
<form action="{% url 'list_anonymous_subscribe' list.list_id %}"
method="post" class="form-horizontal">
{% bootstrap_form_horizontal anonymous_subscription_form 2 8 'Subscribe' %}
</form>
</div>
{% endif %}
{# List metrics #}
......
......@@ -22,6 +22,7 @@ from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from postorius.tests.utils import ViewTestCase
from postorius.forms import ListAnonymousSubscribe
class ListSummaryPageTest(ViewTestCase):
......@@ -41,13 +42,15 @@ class ListSummaryPageTest(ViewTestCase):
user=self.user, email=self.user.email, verified=True)
def test_list_summary_logged_out(self):
# Response must contain list obj but not the form.
# Response must contain list obj and anonymous subscribe form.
response = self.client.get(reverse('list_summary',
args=('foo@example.com', )))
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['list'].fqdn_listname,
'foo@example.com')
self.assertNotContains(response, '<form ')
self.assertIsInstance(response.context['anonymous_subscription_form'],
ListAnonymousSubscribe)
self.assertContains(response, '<form ')
def test_list_summary_logged_in(self):
# Response must contain list obj and the form.
......
......@@ -20,6 +20,7 @@ from __future__ import absolute_import, print_function, unicode_literals
from allauth.account.models import EmailAddress
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from mock import patch
from postorius.tests.utils import ViewTestCase
......@@ -61,6 +62,20 @@ class TestSubscription(ViewTestCase):
self.mod_list.moderate_request(req['token'], 'discard')
super(TestSubscription, self).tearDown()
@patch('mailmanclient._client.MailingList.subscribe')
def test_anonymous_subscribe(self, mock_subscribe):
response = self.client.post(
reverse('list_anonymous_subscribe',
args=('open_list.example.com', )),
{'email': 'test@example.com'})
mock_subscribe.assert_called_once()
mock_subscribe.assert_called_with(
'test@example.com', pre_verified=False, pre_confirmed=False)
self.assertRedirects(
response, reverse('list_summary',
args=('open_list.example.com', )))
self.assertHasSuccessMessage(response)
def test_subscribe_open(self):
# The subscription goes straight through.
self.client.login(username='testuser', password='pwd')
......
......@@ -36,6 +36,9 @@ list_patterns = [
name='list_summary'),
url(r'^subscribe$', list_views.ListSubscribeView.as_view(),
name='list_subscribe'),
url(r'^anonymous_subscribe$',
list_views.ListAnonymousSubscribeView.as_view(),
name='list_anonymous_subscribe'),
url(r'^change_subscription$', list_views.ChangeSubscriptionView.as_view(),
name='change_subscription'),
url(r'^unsubscribe/$', list_views.ListUnsubscribeView.as_view(),
......
......@@ -45,7 +45,7 @@ from postorius.forms import (
DigestSettingsForm, AlterMessagesForm, ListAutomaticResponsesForm,
ListIdentityForm, ListMassSubscription, ListMassRemoval, ListAddBanForm,
ListHeaderMatchForm, ListHeaderMatchFormset, MemberModeration,
DMARCMitigationsForm)
DMARCMitigationsForm, ListAnonymousSubscribe)
from postorius.models import Domain, List, MailmanApiError, Mailman404Error
from postorius.auth.decorators import (
list_owner_required, list_moderator_required, superuser_required)
......@@ -233,6 +233,7 @@ class ListSummaryView(MailingListView):
data['subscribe_form'] = ListSubscribe(user_emails)
else:
user_emails = None
data['anonymous_subscription_form'] = ListAnonymousSubscribe()
return render(request, 'postorius/lists/summary.html', data)
......@@ -319,6 +320,34 @@ class ListSubscribeView(MailingListView):
return redirect('list_summary', self.mailing_list.list_id)
class ListAnonymousSubscribeView(MailingListView):
"""
view name: `list_anonymous_subscribe`
"""
def post(self, request, list_id):
"""
Subscribes an email address to a mailing list via POST and
redirects to the `list_summary` view.
This view is used for unauthenticated users and asks Mailman core to
verify the supplied email address.
"""
try:
form = ListAnonymousSubscribe(request.POST)
if form.is_valid():
email = form.cleaned_data.get('email')
self.mailing_list.subscribe(email, pre_verified=False,
pre_confirmed=False)
messages.success(request, _('Please check your inbox for '
'further instructions'))
else:
messages.error(request,
_('Something went wrong. Please try again.'))
except HTTPError as e:
messages.error(request, e.msg)
return redirect('list_summary', self.mailing_list.list_id)
class ListUnsubscribeView(MailingListView):
"""Unsubscribe from a mailing list."""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment