From 48fd26494ac95c95a1237d1d16e32e1a3943a666 Mon Sep 17 00:00:00 2001 From: Alex Parmentier Date: Thu, 11 May 2017 15:04:31 -0400 Subject: [PATCH] New: Enforece unique emails with forms. It's too late to enforce unique emails at the database level. These new checks on the forms ensure that no new accounts are created with emails that are already attached to some other account. --- elvis/forms/__init__.py | 2 +- elvis/forms/user.py | 35 +++++++++++++++++++++++++++-------- elvis/urls.py | 1 - elvis/views/user.py | 17 ++++------------- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/elvis/forms/__init__.py b/elvis/forms/__init__.py index 6be2f4fb..81f2e728 100644 --- a/elvis/forms/__init__.py +++ b/elvis/forms/__init__.py @@ -1,2 +1,2 @@ -from elvis.forms.user import UserForm, InviteUserForm, UserChangeForm +from elvis.forms.user import ElvisUserCreationForm, ElvisUserChangeForm from elvis.forms.create import PieceForm diff --git a/elvis/forms/user.py b/elvis/forms/user.py index e1fa29e4..872f7dc6 100644 --- a/elvis/forms/user.py +++ b/elvis/forms/user.py @@ -4,8 +4,9 @@ from elvis.models.user_profile import UserProfile + # A simple extension of the built-in UserCreationForm -class UserForm(UserCreationForm): +class ElvisUserCreationForm(UserCreationForm): # Gather data first_name = forms.CharField(max_length=255, required=False) @@ -18,9 +19,15 @@ class Meta: model = User fields = ['username', 'email', 'password1', 'password2'] + def clean_email(self): + email = self.cleaned_data.get('email') + if email and User.objects.filter(email=email).count() > 0: + raise forms.ValidationError('Account with that email already exists') + return email + # Clean data, create the user using UserCreationForm, return the new user obj for login def save(self, commit=True): - user = super(UserForm, self).save(commit = False) + user = self.instance user.username = self.cleaned_data['username'] user.email = self.cleaned_data['email'] user.first_name = self.cleaned_data['first_name'] @@ -39,16 +46,28 @@ def save(self, commit=True): return user -class UserChangeForm(forms.ModelForm): +class ElvisUserChangeForm(UserChangeForm): class Meta: model = User fields = ['email', 'first_name', 'last_name'] - def __init__(self, *args, **kwargs): - super(UserChangeForm, self).__init__(*args, **kwargs) - f = self.fields.get('user_permissions', None) - if f is not None: - f.queryset = f.queryset.select_related('content_type') + def clean_email(self): + email = self.cleaned_data.get('email') + + if email and any(x != self.instance for x in User.objects.filter(email=email)): + raise forms.ValidationError('Account with that email already exists') + return email + + def clean_password(self): + pass + + def save(self, commit=True): + user = self.instance + user.email = self.cleaned_data['email'] + user.first_name = self.cleaned_data['first_name'] + user.last_name = self.cleaned_data['last_name'] + if commit: + user.save() class InviteUserForm(forms.Form): diff --git a/elvis/urls.py b/elvis/urls.py index 543600e2..8d975d02 100644 --- a/elvis/urls.py +++ b/elvis/urls.py @@ -41,7 +41,6 @@ url(r'^register/$', UserAccount.as_view(), name='register-form'), - #Password resettting won't work until server emails are up. url(r'^password/reset/$', auth_views.password_reset, {'template_name': 'user/password_reset.html'}, name='password_reset'), url(r'^password/reset/done/$', auth_views.password_reset_done, {'template_name': 'user/password_reset_done.html'}, name='password_reset_done'), url(r'^reset/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', auth_views.password_reset_confirm, {'template_name': 'user/password_reset_confirm.html'}, name='password_reset_confirm'), diff --git a/elvis/views/user.py b/elvis/views/user.py index f9b96bac..80a4beb1 100644 --- a/elvis/views/user.py +++ b/elvis/views/user.py @@ -15,7 +15,7 @@ from rest_framework import generics from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer -from elvis.forms import UserForm, UserChangeForm +from elvis.forms import ElvisUserCreationForm, ElvisUserChangeForm from elvis.models.collection import Collection from elvis.models.composer import Composer from elvis.models.movement import Movement @@ -25,7 +25,6 @@ from elvis.serializers.serializers import UserListSerializer - class UserAccountHTMLRenderer(CustomHTMLRenderer): template_name = "user/user_account.html" @@ -51,7 +50,7 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): user = request.user if user.is_anonymous(): - form = UserForm(data=request.POST) + form = ElvisUserCreationForm(data=request.POST) if not form.is_valid(): return render(request, "register.html", {'form': form}) @@ -68,19 +67,11 @@ def post(self, request, *args, **kwargs): login(request, user) return HttpResponseRedirect("/") else: - form = UserChangeForm(data=request.POST, instance=request.user) + form = ElvisUserChangeForm(data=request.POST, instance=request.user) if not form.is_valid(): return render(request, "user/user_update.html", {'form': form}) - clean_form = form.cleaned_data - if clean_form['email']: - user.email = clean_form['email'] - if clean_form['first_name']: - user.first_name = clean_form['first_name'] - if clean_form['last_name']: - user.last_name = clean_form['last_name'] - user.save() - + form.save() return HttpResponseRedirect("/account")