Permalink
Browse files

Add ability to add and delete email addresses.

Signed-off-by: Chris Lamb <lamby@debian.org>
  • Loading branch information...
lamby authored and rhertzog committed Sep 27, 2012
1 parent af5df7b commit dea1dc18cba51157a7aad5b4c382a6e5b8b00797
No changes.
@@ -0,0 +1,63 @@
+from email_from_template import send_mail
+
+from django import forms
+from django.core.signing import Signer, BadSignature
+
+from librement.account.models import Email
+
+class EmailForm(forms.Form):
+ email = forms.EmailField()
+
+ def __init__(self, user, *args, **kwargs):
+ self.user = user
+
+ super(EmailForm, self).__init__(*args, **kwargs)
+
+ def clean_email(self):
+ val = self.cleaned_data['email']
+
+ if Email.objects.filter(email=val).exists():
+ raise forms.ValidationError("Email address already in use.")
+
+ return val
+
+ def send_email(self):
+ email = self.cleaned_data['email']
+
+ send_mail(
+ (email,),
+ 'profile/emails/confirm.email', {
+ 'user': self.user,
+ 'signed': Signer().sign(email),
+ },
+ )
+
+class ConfirmForm(forms.Form):
+ signed = forms.CharField()
+
+ def __init__(self, user, *args, **kwargs):
+ self.user = user
+
+ super(ConfirmForm, self).__init__(*args, **kwargs)
+
+ def clean_signed(self):
+ val = self.cleaned_data['signed']
+
+ try:
+ email = Signer().unsign(val)
+ except BadSignature:
+ raise forms.ValidationError("")
+
+ if Email.objects.filter(email=email).exists():
+ # Race condition or linked clicked twice
+ raise forms.ValidationError("")
+
+ self.cleaned_data['email'] = email
+
+ return val
+
+ def save(self):
+ self.user.emails.create(
+ email=self.cleaned_data['email'],
+ )
+
No changes.
@@ -0,0 +1,12 @@
+from django.conf.urls import patterns, url
+
+urlpatterns = patterns('librement.profile.emails.views',
+ url(r'^profile/edit/emails$', 'view',
+ name='view'),
+ url(r'^profile/edit/emails/confirm$', 'confirm',
+ name='confirm'),
+ url(r'^profile/edit/emails/add$', 'add',
+ name='add'),
+ url(r'^profile/edit/emails/(?P<email_id>\d+)/delete$', 'delete',
+ name='delete'),
+)
@@ -0,0 +1,64 @@
+from django.contrib import messages
+from django.shortcuts import render, get_object_or_404, redirect
+from django.views.decorators.http import require_POST
+from django.contrib.auth.decorators import login_required
+
+from .forms import EmailForm, ConfirmForm
+
+@login_required
+def view(request):
+ return render(request, 'profile/emails/view.html')
+
+@login_required
+def confirm(request):
+ form = ConfirmForm(request.user, request.GET)
+
+ if form.is_valid():
+ form.save()
+
+ messages.success(
+ request,
+ "Your email adddress was successfully confirmed.",
+ )
+ else:
+ messages.error(
+ request,
+ "There was an error confirming your email address.",
+ )
+
+ return redirect('profile:emails:view')
+
+@login_required
+def add(request):
+ if request.method == 'POST':
+ form = EmailForm(request.user, request.POST)
+
+ if form.is_valid():
+ form.send_email()
+
+ messages.success(
+ request,
+ "Please check your email inbox to confirm your email address.",
+ )
+
+ return redirect('profile:emails:view')
+
+ else:
+ form = EmailForm(request.user)
+
+ return render(request, 'profile/emails/add.html', {
+ 'form': form,
+ })
+
+@require_POST
+@login_required
+def delete(request, email_id):
+ email = get_object_or_404(request.user.emails, pk=email_id)
+
+ if request.user.emails.count() > 1:
+ email.delete()
+ messages.success(request, "Email address deleted.")
+ else:
+ messages.error(request, "Cannot delete last remaining email address.")
+
+ return redirect('profile:emails:view')
@@ -13,6 +13,7 @@
urlpatterns = patterns('librement.profile.views',
(r'', include('librement.profile.links.urls', namespace='links')),
+ (r'', include('librement.profile.emails.urls', namespace='emails')),
url(r'^people/(?P<username>[^/]*)$', 'view',
name='view'),
@@ -122,6 +122,7 @@
'librement.registration',
'librement.passwords',
'librement.profile',
+ 'librement.profile.emails',
'librement.profile.links',
'librement.static',
'librement.utils',
@@ -8,6 +8,7 @@ <h1 class="page-header">Edit profile <small><a href="{% url "profile:view" reque
<ul class="nav nav-pills">
<li class="{% block profile_edit_basic %}{% endblock %}"><a href="{% url "profile:edit" %}">Basic information</a></li>
+ <li class="{% block profile_edit_emails %}{% endblock %}"><a href="{% url "profile:emails:view" %}">Email addresses</a></li>
<li class="{% block profile_edit_url %}{% endblock %}"><a href="{% url "profile:edit-url" %}">URL</a></li>
<li class="{% block profile_edit_links %}{% endblock %}"><a href="{% url "profile:links:view" %}">Links</a></li>
<li class="{% block profile_edit_picture %}{% endblock %}"><a href="{% url "profile:edit-picture" %}">Picture</a></li>
@@ -0,0 +1,30 @@
+{% extends "profile/emails/base.html" %}
+
+{% load url from future %}
+
+{% block edit_profile %}
+
+<h2>Add email address</h2>
+
+<form method="POST" action="" class="form-horizontal">
+ {% csrf_token %}
+
+ <div class="control-group {% if form.errors.email %}error{% endif %}">
+ <label class="control-label" for="{{ form.email.id_for_label }}">Email address</label>
+ <div class="controls">
+ <div class="input-prepend">
+ <span class="add-on">@</span>
+ <input type="text" id="{{ form.email.id_for_label }}" name="{{ form.email.html_name }}" placeholder="Email address" value="{{ form.email.value|default:"" }}">
+ </div>
+ <span class="help-inline">
+ {% for x in form.errors.email %}{{ x }}{% endfor %}
+ </span>
+ </div>
+ </div>
+
+ <div class="well">
+ <button type="submit" class="btn btn-primary">Add</button>
+ </div>
+</form>
+
+{% endblock %}
@@ -0,0 +1,3 @@
+{% extends "profile/edit/base.html" %}
+
+{% block profile_edit_emails %}active{% endblock %}
@@ -0,0 +1,16 @@
+{% extends email_from_template %}
+
+{% load url from future %}
+
+{% block subject %}
+Confirm your email address
+{% endblock %}
+
+{% block body %}
+Hi {{ user.first_name }},
+
+Click here to confirm your email address:
+
+ {{ settings.SITE_URL }}{% url "profile:emails:confirm" %}?{% automatic_login_token user %}&signed={{ signed|urlencode }}
+
+{% endblock %}
@@ -0,0 +1,27 @@
+{% extends "profile/emails/base.html" %}
+
+{% load url from future %}
+
+{% block edit_profile %}
+
+<p>
+ The following email addresses are associated with your account:
+</p>
+
+<ul>
+ {% for email in request.user.emails.all %}
+ <li>
+ <code>{{ email.email }}</code>
+ <form method="POST" action="{% url "profile:emails:delete" email.pk %}" class="inline">
+ {% csrf_token %}
+ <button class="btn btn-danger btn-small" type="submit"><i class="icon-remove icon-white"></i> Delete</button>
+ </form>
+ </li>
+ {% endfor %}
+</ul>
+
+<div class="well">
+ <a class="btn btn-primary" href="{% url "profile:emails:add" %}"><i class="icon-plus icon-white"></i> Add new email address</a>
+</div>
+
+{% endblock %}

0 comments on commit dea1dc1

Please sign in to comment.