Skip to content

Commit

Permalink
Fix #285
Browse files Browse the repository at this point in the history
  • Loading branch information
seav committed Jul 5, 2016
1 parent bc43e5b commit b0aa841
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 9 deletions.
18 changes: 14 additions & 4 deletions cadasta/accounts/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,31 @@ class RegisterForm(forms.ModelForm):
password1 = forms.CharField(widget=forms.PasswordInput())
password2 = forms.CharField(widget=forms.PasswordInput())

INVALID_USERNAMES = ('add', 'new')

class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2',
'full_name']

def clean_username(self):
username = self.data.get('username')
if username.lower() in self.INVALID_USERNAMES:
raise forms.ValidationError(
_("Username cannot be “add” or “new”."))
return username

def clean_password1(self):
password = self.data.get('password1')
if password != self.data.get('password2'):
raise forms.ValidationError(_("Passwords do not match"))

return password

def clean_email(self):
email = self.data.get('email')
if User.objects.filter(email=email).exists():
raise forms.ValidationError(
_("Another user with this email already exists"))

return email

def save(self, *args, **kwargs):
Expand All @@ -37,6 +44,8 @@ def save(self, *args, **kwargs):


class ProfileForm(forms.ModelForm):
INVALID_USERNAMES = ('add', 'new')

class Meta:
model = User
fields = ['username', 'email', 'full_name']
Expand All @@ -47,7 +56,9 @@ def clean_username(self):
User.objects.filter(username=username).exists()):
raise forms.ValidationError(
_("Another user with this username already exists"))

if username.lower() in self.INVALID_USERNAMES:
raise forms.ValidationError(
_("Username cannot be “add” or “new”."))
return username

def clean_email(self):
Expand All @@ -56,5 +67,4 @@ def clean_email(self):
User.objects.filter(email=email).exists()):
raise forms.ValidationError(
_("Another user with this email already exists"))

return email
13 changes: 13 additions & 0 deletions cadasta/accounts/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class RegistrationSerializer(djoser_serializers.UserRegistrationSerializer):
)]
)

INVALID_USERNAMES = ('add', 'new')

class Meta:
model = User
fields = (
Expand All @@ -33,6 +35,12 @@ class Meta:
'email': {'required': True, 'unique': True}
}

def validate_username(self, username):
if username.lower() in self.INVALID_USERNAMES:
raise ValidationError(
_("Username cannot be “add” or “new”."))
return username


class UserSerializer(djoser_serializers.UserSerializer):
email = EmailField(
Expand All @@ -43,6 +51,8 @@ class UserSerializer(djoser_serializers.UserSerializer):
)]
)

INVALID_USERNAMES = ('add', 'new')

class Meta:
model = User
fields = (
Expand All @@ -64,6 +74,9 @@ def validate_username(self, username):
username != instance.username and
self.context['request'].user != instance):
raise ValidationError('Cannot update username')
if username.lower() in self.INVALID_USERNAMES:
raise ValidationError(
_("Username cannot be “add” or “new”."))
return username

def validate_last_login(self, last_login):
Expand Down
30 changes: 30 additions & 0 deletions cadasta/accounts/tests/test_forms.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import random

from django.utils.translation import gettext as _

from ..models import User
Expand Down Expand Up @@ -55,6 +57,22 @@ def test_signup_with_existing_email(self):
in form.errors.get('email'))
assert User.objects.count() == 1

def test_signup_with_restricted_username(self):
invalid_usernames = ('add', 'ADD', 'Add', 'new', 'NEW', 'New')
data = {
'username': random.choice(invalid_usernames),
'email': '[email protected]',
'password1': 'iloveyoko79',
'password2': 'iloveyoko68',
'full_name': 'John Lennon',
}
form = RegisterForm(data)

assert form.is_valid() is False
assert (_("Username cannot be “add” or “new”.")
in form.errors.get('username'))
assert User.objects.count() == 0


class ProfileFormTest(UserTestCase):
def test_update_user(self):
Expand Down Expand Up @@ -94,3 +112,15 @@ def test_update_user_with_existing_email(self):
}
form = ProfileForm(data, instance=user)
assert form.is_valid() is False

def test_update_user_with_restricted_username(self):
user = UserFactory.create(username='imagine71',
email='[email protected]')
invalid_usernames = ('add', 'ADD', 'Add', 'new', 'NEW', 'New')
data = {
'username': random.choice(invalid_usernames),
'email': '[email protected]',
'full_name': 'John Lennon',
}
form = ProfileForm(data, instance=user)
assert form.is_valid() is False
38 changes: 36 additions & 2 deletions cadasta/accounts/tests/test_serializers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import random
import pytest
from datetime import datetime
from django.utils.translation import gettext as _
Expand Down Expand Up @@ -73,6 +74,21 @@ def test_create_with_existing_email(self):
assert (_("Another user is already registered with this email address")
in serializer._errors['email'])

def test_create_with_restricted_username(self):
invalid_usernames = ('add', 'ADD', 'Add', 'new', 'NEW', 'New')
data = {
'username': random.choice(invalid_usernames),
'email': '[email protected]',
'password': 'iloveyoko79',
'password_repeat': 'iloveyoko79',
'full_name': 'John Lennon',
}

serializer = RegistrationSerializer(data=data)
assert not serializer.is_valid()
assert (_("Username cannot be “add” or “new”.")
in serializer._errors['username'])


class UserSerializerTest(UserTestCase):
def test_field_serialization(self):
Expand Down Expand Up @@ -102,8 +118,7 @@ def test_create_with_valid_data(self):
def test_update_username_fails(self):
serializer = UserSerializer(data=BASIC_TEST_DATA)
assert serializer.is_valid()
serializer.save()
user = User.objects.first()
user = serializer.save()
other_user = UserFactory.create()
update_data = {'username': 'bad-update'}
request = APIRequestFactory().patch('/user/imagine71', update_data)
Expand All @@ -125,6 +140,25 @@ def test_update_last_login_fails(self):
assert not serializer2.is_valid()
assert serializer2.errors['last_login'] == ['Cannot update last_login']

def test_update_with_restricted_username(self):
serializer = UserSerializer(data=BASIC_TEST_DATA)
assert serializer.is_valid()
user = serializer.save()
invalid_usernames = ('add', 'ADD', 'Add', 'new', 'NEW', 'New')
data = {
'username': random.choice(invalid_usernames),
'email': '[email protected]',
'full_name': 'John Lennon',
}
request = APIRequestFactory().patch('/user/imagine71', data)
force_authenticate(request, user=user)
serializer2 = UserSerializer(
user, data=data, context={'request': Request(request)}
)
assert not serializer2.is_valid()
assert serializer2.errors['username'] == [
_("Username cannot be “add” or “new”.")]


class AccountLoginSerializerTest(UserTestCase):
def test_unverified_account(self):
Expand Down
24 changes: 22 additions & 2 deletions cadasta/organization/forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django import forms
from django.contrib.postgres import forms as pg_forms
from django.contrib.gis import forms as gisforms
from django.utils.text import slugify
from django.utils.translation import ugettext as _
from django.db import transaction

Expand Down Expand Up @@ -79,6 +80,8 @@ class OrganizationForm(forms.ModelForm):
contacts = ContactsField(form=ContactsForm, required=False)
access = PublicPrivateField()

INVALID_NAMES = ('add', 'new')

class Meta:
model = Organization
fields = ['name', 'description', 'urls', 'contacts', 'access']
Expand All @@ -96,13 +99,21 @@ def to_list(self, value):
def clean_urls(self):
return self.to_list(self.data.get('urls'))

def clean_name(self):
is_create = not self.instance.id
name = self.cleaned_data['name']
if is_create and slugify(name) in self.INVALID_NAMES:
raise forms.ValidationError(
_("Organization name cannot be “Add” or “New”."))
return name

def save(self, *args, **kwargs):
instance = super(OrganizationForm, self).save(commit=False)
create = not instance.id
is_create = not instance.id

instance.save()

if create:
if is_create:
OrganizationRole.objects.create(
organization=instance,
user=self.user,
Expand Down Expand Up @@ -201,13 +212,22 @@ class ProjectAddDetails(forms.Form):
questionaire = forms.CharField(required=False, widget=S3FileUploadWidget)
contacts = ContactsField(form=ContactsForm, required=False)

INVALID_NAMES = ('add', 'new')

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.fields['organization'].choices = [
(o.slug, o.name) for o in Organization.objects.order_by('name')
]

def clean_name(self):
name = self.cleaned_data['name']
if slugify(name) in self.INVALID_NAMES:
raise forms.ValidationError(
_("Project name cannot be “Add” or “New”."))
return name


class ProjectEditDetails(forms.ModelForm):
urls = pg_forms.SimpleArrayField(forms.URLField(), required=False)
Expand Down
19 changes: 19 additions & 0 deletions cadasta/organization/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.db.models import Q
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.utils.text import slugify
from django.utils.translation import ugettext as _
from django.template.loader import get_template
from django.template import Context
Expand All @@ -19,13 +20,22 @@ class OrganizationSerializer(DetailSerializer, FieldSelectorSerializer,
serializers.ModelSerializer):
users = UserSerializer(many=True, read_only=True)

INVALID_NAMES = ('add', 'new')

class Meta:
model = Organization
fields = ('id', 'slug', 'name', 'description', 'archived', 'urls',
'contacts', 'users',)
read_only_fields = ('id', 'slug',)
detail_only_fields = ('users',)

def validate_name(self, value):
is_create = not self.instance
if is_create and slugify(value) in self.INVALID_NAMES:
raise serializers.ValidationError(
_("Organization name cannot be “Add” or “New”."))
return value

def create(self, *args, **kwargs):
org = super(OrganizationSerializer, self).create(*args, **kwargs)

Expand All @@ -43,6 +53,15 @@ class ProjectSerializer(DetailSerializer, serializers.ModelSerializer):
organization = OrganizationSerializer(read_only=True)
country = CountryField(required=False)

INVALID_NAMES = ('add', 'new')

def validate_name(self, value):
is_create = not self.instance
if is_create and slugify(value) in self.INVALID_NAMES:
raise serializers.ValidationError(
_("Project name cannot be “Add” or “New”."))
return value

class Meta:
model = Project
fields = ('id', 'organization', 'country', 'name', 'description',
Expand Down
40 changes: 39 additions & 1 deletion cadasta/organization/tests/test_forms.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import random
from pytest import raises

from django.conf import settings
Expand All @@ -18,7 +19,7 @@
from tutelary.models import Policy


class OrganzationTest(UserTestCase):
class OrganizationTest(UserTestCase):
def setUp(self):
super().setUp()
self.data = {
Expand Down Expand Up @@ -77,6 +78,23 @@ def test_add_organization_with_contact(self):
'email': '[email protected]'
}]

def test_add_organization_with_restricted_name(self):
invalid_names = ('add', 'ADD', 'Add', 'new', 'NEW', 'New')
data = {
'name': random.choice(invalid_names),
'contacts-TOTAL_FORMS': 1,
'contacts-INITIAL_FORMS': 0,
'contacts-0-name': '',
'contacts-0-email': '',
'contacts-0-tel': ''
}
form = forms.OrganizationForm(data, user=UserFactory.create())
assert not form.is_valid()
assert form.errors == {
'name': ["Organization name cannot be “Add” or “New”."]
}
assert not Organization.objects.exists()

def test_update_organization(self):
org = OrganizationFactory.create(slug='some-org')
self.data['description'] = 'Org description'
Expand Down Expand Up @@ -216,6 +234,26 @@ def test_edit_project_roles(self):
is False)


class ProjectAddDetailsTest(UserTestCase):
def test_add_new_project_with_restricted_name(self):
org = OrganizationFactory.create()
invalid_names = ('add', 'ADD', 'Add', 'new', 'NEW', 'New')
data = {
'organization': org.slug,
'name': random.choice(invalid_names),
'contacts-TOTAL_FORMS': 1,
'contacts-INITIAL_FORMS': 0,
'contacts-0-name': '',
'contacts-0-email': '',
'contacts-0-tel': ''
}
form = forms.ProjectAddDetails(data=data)
assert not form.is_valid()
assert form.errors == {
'name': ["Project name cannot be “Add” or “New”."]
}


class ProjectEditDetailsTest(UserTestCase):
def _get_form(self, form_name):
path = os.path.dirname(settings.BASE_DIR)
Expand Down
Loading

0 comments on commit b0aa841

Please sign in to comment.