Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@ python:
- "3.6"
- "3.7"
env:
- DJANGO=20
- DJANGO=21
- DJANGO=22
- DJANGO=master
- DJANGO=20-sqlite
- DJANGO=21-sqlite
- DJANGO=22-sqlite
- DJANGO=master-sqlite
- DJANGO=20-pg
- DJANGO=21-pg
- DJANGO=22-pg
- DJANGO=master-pg

addons:
postgresql: "10"

matrix:
fast_finish: true
allow_failures:
- env: DJANGO=master
- env: DJANGO=master-sqlite
- env: DJANGO=master-pg

install: pip install tox-travis codecov
before_script:
Expand Down
39 changes: 39 additions & 0 deletions mailauth/contrib/user/migrations/0003_ci_unique_index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from django.db import migrations

try:
from django.contrib.postgres.fields import CIEmailField
except ImportError:
CIEmailField = None
else:
from django.contrib.postgres.operations import CITextExtension


def _operations():
if CIEmailField:
yield CITextExtension()
yield migrations.AlterField(
model_name='emailuser',
name='email',
field=CIEmailField(
db_index=True, max_length=254, unique=True, verbose_name='email address'
),
)
else:
yield migrations.RunSQL(
sql=(
'CREATE UNIQUE INDEX mailauth_user_emailuser_email_upper_idx'
' ON mailauth_user_emailuser (UPPER("email"));',
)
,
reverse_sql=(
'DROP INDEX mailauth_user_emailuser_email_upper_idx;',
)
)


class Migration(migrations.Migration):
dependencies = [
('mailauth_user', '0002_emailuser_session_salt'),
]

operations = list(_operations())
7 changes: 6 additions & 1 deletion mailauth/contrib/user/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
from django.utils.crypto import get_random_string, salted_hmac
from django.utils.translation import ugettext_lazy as _

try:
from django.contrib.postgres.fields import CIEmailField
except ImportError:
from django.db.models import EmailField as CIEmailField


class EmailUserManager(BaseUserManager):
use_in_migrations = True
Expand Down Expand Up @@ -37,7 +42,7 @@ class AbstractEmailUser(AbstractUser):
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []

email = models.EmailField(_('email address'), unique=True, db_index=True)
email = CIEmailField(_('email address'), unique=True, db_index=True)
username = None
password = None
session_salt = models.CharField(
Expand Down
9 changes: 6 additions & 3 deletions mailauth/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.contrib.auth import get_user_model
from django.contrib.sites.shortcuts import get_current_site
from django.core.mail import EmailMultiAlternatives
from django.db import connection
from django.template import TemplateDoesNotExist, loader
from django.urls import reverse
from django.utils.encoding import iri_to_uri
Expand Down Expand Up @@ -105,9 +106,11 @@ def __init__(self, request, *args, **kwargs):
self.fields[self.field_name] = field

def get_users(self, email=None):
return get_user_model()._default_manager.filter(
**{self.field_name: email}
).iterator()
if connection.vendor == 'postgresql':
query = {self.field_name: email}
else:
query = {'%s__iexact' % self.field_name: email}
return get_user_model()._default_manager.filter(**query).iterator()

def save(self):
"""
Expand Down
6 changes: 5 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,19 @@ addopts = --cov=mailauth --cov-report xml --cov-report term-missing --tb=short
DJANGO_SETTINGS_MODULE = tests.testapp.settings

[tox:tox]
envlist = py{36,37}-dj{22,21,20,master},docs
envlist = py{36,37}-dj{22,11,master}-{sqlite,pg},docs
depencies = psycopg2-binary

[testenv]
passenv=CI
setenv =
pg: DB=pg
deps =
dj20: https://github.com/django/django/archive/stable/2.0.x.tar.gz#egg=django
dj21: https://github.com/django/django/archive/stable/2.1.x.tar.gz#egg=django
dj22: https://github.com/django/django/archive/stable/2.2.x.tar.gz#egg=django
djmaster: https://github.com/django/django/archive/master.tar.gz#egg=django
pg: psycopg2-binary
commands = python setup.py test

[testenv:docs]
Expand Down
5 changes: 5 additions & 0 deletions tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@ class MyEmailLoginForm(EmailLoginForm):

MyEmailLoginForm(request=None).send_mail('spiderman@avengers.com', {})
assert mail.outbox[-1].alternatives

def test_get_users(self, db, user):
assert list(EmailLoginForm(request=None).get_users('spiderman@avengers.com'))
assert list(EmailLoginForm(request=None).get_users('SpiderMan@Avengers.com'))
assert not list(EmailLoginForm(request=None).get_users('SpiderMan@dc.com'))
12 changes: 12 additions & 0 deletions tests/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import pytest
from django.db import IntegrityError

from mailauth.contrib.user import models


class TestEmailUser:

def test_email__ci_unique(self, db):
models.EmailUser.objects.create_user('IronMan@avengers.com')
with pytest.raises(IntegrityError):
models.EmailUser.objects.create_user('ironman@avengers.com')
19 changes: 14 additions & 5 deletions tests/testapp/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,21 @@
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
DB = os.getenv('DB', 'sqlite')
if DB == 'sqlite':
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
elif DB == 'pg':
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'django-test',
}
}
}


LANGUAGE_CODE = 'en-us'
Expand Down