Add alternative terms acceptance workflow.

This view lives at /accounts/accept_terms, and (after getting an acceptance
from the user) sends an email to all@ documenting the acceptance.

(imported from commit 8f64286ab02887fd6544fa274b2967f6499b6dbc)
This commit is contained in:
Luke Faraone 2013-01-08 17:26:40 -05:00
parent 39501e5a78
commit c327446537
5 changed files with 125 additions and 3 deletions

View File

@ -34,6 +34,9 @@ urlpatterns = patterns('',
url(r'^accounts/register/', 'zephyr.views.accounts_register'), url(r'^accounts/register/', 'zephyr.views.accounts_register'),
url(r'^accounts/do_confirm/(?P<confirmation_key>[\w]+)', 'confirmation.views.confirm'), url(r'^accounts/do_confirm/(?P<confirmation_key>[\w]+)', 'confirmation.views.confirm'),
# Portico-styled page used to provide email confirmation of terms acceptance.
url(r'^accounts/accept_terms', 'zephyr.views.accounts_accept_terms'),
# Terms of service and privacy policy # Terms of service and privacy policy
url(r'^terms$', 'django.views.generic.simple.direct_to_template', {'template': 'zephyr/terms.html'}), url(r'^terms$', 'django.views.generic.simple.direct_to_template', {'template': 'zephyr/terms.html'}),
url(r'^privacy$', 'django.views.generic.simple.direct_to_template', {'template': 'zephyr/privacy.html'}), url(r'^privacy$', 'django.views.generic.simple.direct_to_template', {'template': 'zephyr/privacy.html'}),

View File

@ -0,0 +1,75 @@
{% extends "zephyr/portico_signup.html" %}
{% comment %}
Allow the user to accept the terms, creating an email record of that fact.
{% endcomment %}
{% block for_you %}for {% if company_name %} {{company_name}} {% else %} __________ {% endif %} {% endblock %}
{% block portico_content %}
<p>(Welcome! We think you'll like it here.)</p>
<div class="pitch">
<hr/>
<p>You're almost there. We just need you to do one last thing.</p>
<h3>Accept the Humbug terms of service</h3>
</div>
<form method="post" class="form-horizontal" id="registration" action="{% url zephyr.views.accounts_accept_terms %}">
{% csrf_token %}
<div class="control-group">
<label for="id_email" class="control-label">Email</label>
<div class="controls fakecontrol">
<p>{{ email }}<p>
</div>
</div>
<div class="control-group">
<label for="id_full_name" class="control-label">Your name</label>
<div class="controls">
<input id="id_full_name" class="required" type="text" name="full_name"
value="{% if form.full_name.value %}{{ form.full_name.value }}{% endif %}"
maxlength="100" />
{% if form.full_name.errors %}
{% for error in form.full_name.errors %}
<div class="alert alert-error">{{ error }}</div>
{% endfor %}
{% endif %}
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
{% comment %}
This is somewhat subtle.
Checkboxes have a name and value, and when the checkbox is ticked, the form posts
with name=value. If the checkbox is unticked, the field just isn't present at all.
This is distinct from 'checked', which determines whether the checkbox appears
at all. (So, it's not symmetric to the code above.)
{% endcomment %}
<input id="id_terms" class="required" type="checkbox" name="terms"
{% if form.terms.value %}checked="checked"{% endif %} />
I agree to the <a href="/terms">Terms of Service</a>.
</label>
{% if form.terms.errors %}
{% for error in form.terms.errors %}
<div class="alert alert-error">{{ error }}</div>
{% endfor %}
{% endif %}
</div>
</div>
<br />
<div class="control-group">
<div class="controls">
<input type="submit" class="btn btn-primary" value="Register" /><br />
<input type="hidden" name="next" value="{{ next }}" />
</div>
</div>
</form>
<script type="text/javascript">
autofocus('#id_full_name');
</script>
{% endblock %}

View File

@ -0,0 +1,14 @@
{% comment %}
Mail sent to us when a user accepts the ToS
{% endcomment %}
Hello,
{{ name }} <{{ email }}> just accepted the Humbug Terms of Service.
{{ ip }} submitted /accounts/accept_tos from {{ browser }}.
Cheers,
Humbug Legal Bot

View File

@ -43,6 +43,10 @@ class RegistrationForm(forms.Form):
password = forms.CharField(widget=forms.PasswordInput, max_length=100) password = forms.CharField(widget=forms.PasswordInput, max_length=100)
terms = forms.BooleanField(required=True) terms = forms.BooleanField(required=True)
class ToSForm(forms.Form):
full_name = forms.CharField(max_length=100)
terms = forms.BooleanField(required=True)
class HomepageForm(forms.Form): class HomepageForm(forms.Form):
if settings.ALLOW_REGISTER: if settings.ALLOW_REGISTER:
email = UniqueEmailField() email = UniqueEmailField()

View File

@ -3,12 +3,13 @@ from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response from django.shortcuts import render_to_response, redirect
from django.template import RequestContext from django.template import RequestContext, loader
from django.utils.timezone import utc, now from django.utils.timezone import utc, now
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.contrib.auth.views import login as django_login_page from django.contrib.auth.views import login as django_login_page
from django.db.models import Q from django.db.models import Q
from django.core.mail import send_mail
from zephyr.models import Message, UserProfile, Stream, Subscription, \ from zephyr.models import Message, UserProfile, Stream, Subscription, \
Recipient, get_display_recipient, get_huddle, Realm, UserMessage, \ Recipient, get_display_recipient, get_huddle, Realm, UserMessage, \
do_add_subscription, do_remove_subscription, do_change_password, \ do_add_subscription, do_remove_subscription, do_change_password, \
@ -18,7 +19,7 @@ from zephyr.models import Message, UserProfile, Stream, Subscription, \
PreregistrationUser, get_client, MitUser, User, UserActivity, \ PreregistrationUser, get_client, MitUser, User, UserActivity, \
log_subscription_property_change, internal_send_message, \ log_subscription_property_change, internal_send_message, \
MAX_SUBJECT_LENGTH, MAX_MESSAGE_LENGTH MAX_SUBJECT_LENGTH, MAX_MESSAGE_LENGTH
from zephyr.forms import RegistrationForm, HomepageForm, is_unique, \ from zephyr.forms import RegistrationForm, HomepageForm, ToSForm, is_unique, \
is_active is_active
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
@ -118,6 +119,31 @@ def accounts_register(request):
{ 'form': form, 'company_name': company_name, 'email': email, 'key': key }, { 'form': form, 'company_name': company_name, 'email': email, 'key': key },
context_instance=RequestContext(request)) context_instance=RequestContext(request))
@login_required(login_url = settings.HOME_NOT_LOGGED_IN)
def accounts_accept_terms(request):
email = request.user.email
company_name = email.split('@')[-1]
if request.method == "POST":
form = ToSForm(request.POST)
if form.is_valid():
full_name = form.cleaned_data['full_name']
send_mail('Terms acceptance for ' + full_name,
loader.render_to_string('zephyr/tos_accept_body.txt',
{'name': full_name,
'email': email,
'ip': request.META['REMOTE_ADDR'],
'browser': request.META['HTTP_USER_AGENT']}),
"humbug@humbughq.com",
["all@humbughq.com"])
do_change_full_name(request.user.userprofile, full_name)
return redirect(home)
else:
form = ToSForm()
return render_to_response('zephyr/accounts_accept_terms.html',
{ 'form': form, 'company_name': company_name, 'email': email },
context_instance=RequestContext(request))
def login_page(request, **kwargs): def login_page(request, **kwargs):
template_response = django_login_page(request, **kwargs) template_response = django_login_page(request, **kwargs)
try: try: