From ed13cca2613be9aa5b708ead5efb6f9c9075f93c Mon Sep 17 00:00:00 2001
From: Wookey <wookey@wookware.org>
Date: Tue, 2 Jul 2013 18:10:45 +0100
Subject: [PATCH] Add CSRF protection to registration form (and remove annoying
 second password)

---
 registration/forms.py                         | 13 +++++--------
 registration/views.py                         | 17 +++++++++++++----
 templates/registration/registration_form.html | 11 +----------
 3 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/registration/forms.py b/registration/forms.py
index 2f591d4..9b68279 100644
--- a/registration/forms.py
+++ b/registration/forms.py
@@ -15,15 +15,15 @@ from registration.models import RegistrationProfile
 # on them with CSS or JavaScript if they have a class of "required"
 # in the HTML. Your mileage may vary. If/when Django ticket #3515
 # lands in trunk, this will no longer be necessary.
-attrs_dict = { 'class': 'required' }
+# This was fixed in 2007, so I guess we don't need this any more. [W]
+#attrs_dict = { 'class': 'required' }
 
 
 class RegistrationForm(forms.Form):
     """
     Form for registering a new user account.
     
-    Validates that the requested username is not already in use, and
-    requires the password to be entered twice to catch typos.
+    Validates that the requested username is not already in use.
     
     Subclasses should feel free to add any additional validation they
     need, but should either preserve the base ``save()`` or implement
@@ -39,8 +39,7 @@ class RegistrationForm(forms.Form):
                              label=_(u'email address'))
     password1 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False),
                                 label=_(u'password'))
-    password2 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False),
-                                label=_(u'password (again)'))
+    
     
     def clean_username(self):
         """
@@ -62,9 +61,7 @@ class RegistrationForm(forms.Form):
         field.
         
         """
-        if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:
-            if self.cleaned_data['password1'] != self.cleaned_data['password2']:
-                raise forms.ValidationError(_(u'You must type the same password each time'))
+        if 'password1' in self.cleaned_data:
             if len(self.cleaned_data['password1']) < 6:
                 raise forms.ValidationError(_(u'Your password must be at least 6 characters'))
         return self.cleaned_data
diff --git a/registration/views.py b/registration/views.py
index 2d4373a..9603b56 100644
--- a/registration/views.py
+++ b/registration/views.py
@@ -11,7 +11,9 @@ from django.http import HttpResponseRedirect
 from django.shortcuts import render_to_response
 from django.template import RequestContext
 from django.contrib.auth import login
-
+#Add CSRF protection:
+from django.core.context_processors import csrf
+from django.shortcuts import render_to_response
 
 from registration.forms import RegistrationForm
 from registration.models import RegistrationProfile
@@ -64,7 +66,10 @@ def activate(request, activation_key,
     
     """
 
-    
+    # Generate CSRF token
+    c = {}
+    c.update(csrf(request))
+
     activation_key = activation_key.lower() # Normalize before trying anything with it.
     account = RegistrationProfile.objects.activate_user(activation_key)
     try:
@@ -79,7 +84,7 @@ def activate(request, activation_key,
     return render_to_response(template_name,
                               { 'account': account,
                                 'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS, 'settings':settings},
-                              context_instance=context)
+                              context_instance=context, c)
 
 
 def register(request, success_url=None,
@@ -140,6 +145,10 @@ def register(request, success_url=None,
     argument.
     
     """
+    # Generate CSRF token
+    c = {}
+    c.update(csrf(request))
+
     if request.method == 'POST':
         form = form_class(data=request.POST, files=request.FILES)
         if form.is_valid():
@@ -160,4 +169,4 @@ def register(request, success_url=None,
         context[key] = callable(value) and value() or value
     return render_to_response(template_name,
                               { 'form': form,'settings':settings },
-                              context_instance=context)
+                              context_instance=context, c)
diff --git a/templates/registration/registration_form.html b/templates/registration/registration_form.html
index 5720a8b..f82c6cb 100644
--- a/templates/registration/registration_form.html
+++ b/templates/registration/registration_form.html
@@ -9,7 +9,7 @@ registration_form.html | {{ block.super }}
 {% endblock %}
 
 {% block content %}
-<form action="{% url registration_register %}" method="POST">
+<form action="{% url registration_register %}" method="POST">{% csrf_token %}
         {% for error in form.non_field_errors %}
         <span style="color:red">{{ error }}</span>
         {% endfor %}
@@ -41,15 +41,6 @@ registration_form.html | {{ block.super }}
         {% endfor %}
     </td>
 </tr>
-<tr>
-    <td align="right" valign="top">Password (again):</td>
-    <td>
-        {{ form.password2 }} <br/>
-        {% for error in form.password2.errors %}
-        <span style="color:red">{{ error }}</span>
-        {% endfor %}
-    </td>
-</tr>
 <tr>
     <td>&nbsp;</td>
     <td><input type="submit" value="Register" /></td>