From 6f4e0cc04a7c0ca19042bb05e5cc1d371fa4f658 Mon Sep 17 00:00:00 2001 From: Denis Novikov Date: Thu, 1 Dec 2022 16:04:03 +0300 Subject: [PATCH 01/10] feat(apps): add app config --- simple_email_confirmation/apps.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 simple_email_confirmation/apps.py diff --git a/simple_email_confirmation/apps.py b/simple_email_confirmation/apps.py new file mode 100644 index 0000000..4939e75 --- /dev/null +++ b/simple_email_confirmation/apps.py @@ -0,0 +1,15 @@ +"""Application configuration.""" + +from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ + +__all__ = ['EmailAddressConfig'] + + +class EmailAddressConfig(AppConfig): + """Default configuration for the simple_email_confirmation app.""" + + name = 'simple_email_confirmation' + label = 'simple_email_confirmation' + verbose_name = _('EmailAddress') + default_auto_field = 'django.db.models.AutoField' From d779bebb6cc8a30de2ef9cba1e0e79da3cf6f155 Mon Sep 17 00:00:00 2001 From: Denis Novikov Date: Thu, 1 Dec 2022 16:04:34 +0300 Subject: [PATCH 02/10] feat(init): handle config for old django --- simple_email_confirmation/__init__.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/simple_email_confirmation/__init__.py b/simple_email_confirmation/__init__.py index 0bc25cd..ab83e95 100644 --- a/simple_email_confirmation/__init__.py +++ b/simple_email_confirmation/__init__.py @@ -1,4 +1,4 @@ -__version__ = '0.12' +__version__ = '0.13' __all__ = [ 'SimpleEmailConfirmationUserMixin', 'EmailAddress', @@ -7,7 +7,12 @@ 'primary_email_changed', ] +import django + from .models import SimpleEmailConfirmationUserMixin, EmailAddress from .signals import ( email_confirmed, unconfirmed_email_created, primary_email_changed, ) + +if django.get_version() < '4': + default_app_config = 'simple_email_confirmation.apps.EmailAddress' From d651f2860c29eff02b200a699dbccc93181a4d17 Mon Sep 17 00:00:00 2001 From: Denis Novikov Date: Thu, 1 Dec 2022 16:04:48 +0300 Subject: [PATCH 03/10] feat(models): handle gettext for old django --- simple_email_confirmation/models.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/simple_email_confirmation/models.py b/simple_email_confirmation/models.py index 5501162..4aaced8 100644 --- a/simple_email_confirmation/models.py +++ b/simple_email_confirmation/models.py @@ -1,12 +1,17 @@ from __future__ import unicode_literals +import django from django.conf import settings from django.contrib.auth import get_user_model from django.db import models from django.db.models.signals import post_save -from django.utils.crypto import get_random_string from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ +from django.utils.crypto import get_random_string + +if django.get_version() > '4': + from django.utils.translation import gettext_lazy as _ +else: + from django.utils.translation import ugettext_lazy as _ from .exceptions import ( EmailConfirmationExpired, EmailIsPrimary, EmailNotConfirmed, @@ -279,6 +284,7 @@ def auto_add(sender, **kwargs): else: user.email_address_set.create_unconfirmed(email) + # TODO: try to only connect this to the User model. We can't use # get_user_model() here - results in import loop. From d2046110803e5fbd2725fe4538a37fea4974e4ad Mon Sep 17 00:00:00 2001 From: Denis Novikov Date: Thu, 1 Dec 2022 16:05:07 +0300 Subject: [PATCH 04/10] feat(signals): handle signal for new django --- simple_email_confirmation/signals.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/simple_email_confirmation/signals.py b/simple_email_confirmation/signals.py index f45ec28..354596c 100644 --- a/simple_email_confirmation/signals.py +++ b/simple_email_confirmation/signals.py @@ -1,7 +1,10 @@ from django.dispatch import Signal -email_confirmed = Signal(providing_args=['user', 'email']) -unconfirmed_email_created = Signal(providing_args=['user', 'email']) -primary_email_changed = Signal( - providing_args=['user', 'new_email', 'old_email'], -) +try: + email_confirmed = Signal(providing_args=['user', 'email']) + unconfirmed_email_created = Signal(providing_args=['user', 'email']) + primary_email_changed = Signal(providing_args=['user', 'new_email', 'old_email']) +except TypeError: + email_confirmed = Signal() + unconfirmed_email_created = Signal() + primary_email_changed = Signal() From 2a0e47ac403e2df50ce5fff3291ba96254a35a3a Mon Sep 17 00:00:00 2001 From: Denis Novikov Date: Thu, 1 Dec 2022 16:09:37 +0300 Subject: [PATCH 05/10] feat(models): add on delete for email model --- simple_email_confirmation/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simple_email_confirmation/models.py b/simple_email_confirmation/models.py index 4aaced8..da1747d 100644 --- a/simple_email_confirmation/models.py +++ b/simple_email_confirmation/models.py @@ -209,7 +209,7 @@ class EmailAddress(models.Model): "An email address belonging to a User" user = models.ForeignKey( - settings.AUTH_USER_MODEL, related_name='email_address_set', + settings.AUTH_USER_MODEL, related_name='email_address_set', on_delete=models.CASCADE ) email = models.EmailField(max_length=255) key = models.CharField(max_length=40, unique=True) From 1afd860713e708367770206d004195b1e50b2243 Mon Sep 17 00:00:00 2001 From: Denis Novikov Date: Thu, 1 Dec 2022 16:15:22 +0300 Subject: [PATCH 06/10] feat(init): return get_email_address_model --- simple_email_confirmation/__init__.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/simple_email_confirmation/__init__.py b/simple_email_confirmation/__init__.py index ab83e95..13a6a19 100644 --- a/simple_email_confirmation/__init__.py +++ b/simple_email_confirmation/__init__.py @@ -8,6 +8,8 @@ ] import django +from django.apps import apps +from django.conf import settings from .models import SimpleEmailConfirmationUserMixin, EmailAddress from .signals import ( @@ -16,3 +18,12 @@ if django.get_version() < '4': default_app_config = 'simple_email_confirmation.apps.EmailAddress' + + +def get_email_address_model(): + """Convenience method to return the email model being used.""" + return apps.get_model(getattr( + settings, + 'SIMPLE_EMAIL_CONFIRMATION_EMAIL_ADDRESS_MODEL', + 'simple_email_confirmation.EmailAddress' + )) From 560e10ea5f8b4d857864627c4aaff1464bf9b8fb Mon Sep 17 00:00:00 2001 From: Denis Novikov Date: Thu, 1 Dec 2022 16:59:02 +0300 Subject: [PATCH 07/10] feat(init): remove import models --- simple_email_confirmation/__init__.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/simple_email_confirmation/__init__.py b/simple_email_confirmation/__init__.py index 13a6a19..14aecd3 100644 --- a/simple_email_confirmation/__init__.py +++ b/simple_email_confirmation/__init__.py @@ -1,7 +1,5 @@ __version__ = '0.13' __all__ = [ - 'SimpleEmailConfirmationUserMixin', - 'EmailAddress', 'email_confirmed', 'unconfirmed_email_created', 'primary_email_changed', @@ -11,13 +9,12 @@ from django.apps import apps from django.conf import settings -from .models import SimpleEmailConfirmationUserMixin, EmailAddress from .signals import ( email_confirmed, unconfirmed_email_created, primary_email_changed, ) if django.get_version() < '4': - default_app_config = 'simple_email_confirmation.apps.EmailAddress' + default_app_config = 'simple_email_confirmation.apps.EmailAddressConfig' def get_email_address_model(): From 510b67a71edb4ec7ef242682d593d285d26f1b04 Mon Sep 17 00:00:00 2001 From: Denis Novikov Date: Thu, 1 Dec 2022 16:59:34 +0300 Subject: [PATCH 08/10] style(admin): format admin.py --- simple_email_confirmation/admin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/simple_email_confirmation/admin.py b/simple_email_confirmation/admin.py index 7df7926..529671a 100644 --- a/simple_email_confirmation/admin.py +++ b/simple_email_confirmation/admin.py @@ -7,4 +7,5 @@ class EmailAddressAdmin(admin.ModelAdmin): list_display = ('user', 'email', 'key', 'set_at', 'confirmed_at') search_fields = ('email', 'key') + admin.site.register((EmailAddress,), EmailAddressAdmin) From 2e06cc73a80969d25f7ff4997d40eff53290d83d Mon Sep 17 00:00:00 2001 From: Denis Novikov Date: Thu, 1 Dec 2022 17:21:01 +0300 Subject: [PATCH 09/10] feat(migrations): add in delete mode --- simple_email_confirmation/migrations/0001_initial.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simple_email_confirmation/migrations/0001_initial.py b/simple_email_confirmation/migrations/0001_initial.py index 8b9d130..9b99c82 100644 --- a/simple_email_confirmation/migrations/0001_initial.py +++ b/simple_email_confirmation/migrations/0001_initial.py @@ -21,7 +21,7 @@ class Migration(migrations.Migration): ('key', models.CharField(unique=True, max_length=40)), ('set_at', models.DateTimeField(default=django.utils.timezone.now, help_text='When the confirmation key expiration was set')), ('confirmed_at', models.DateTimeField(help_text='First time this email was confirmed', null=True, blank=True)), - ('user', models.ForeignKey(related_name='email_address_set', to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(related_name='email_address_set', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'verbose_name_plural': 'email addresses', From 36d2123b76dfdadc67c3017154e337b405bf6030 Mon Sep 17 00:00:00 2001 From: Denis Novikov Date: Thu, 1 Dec 2022 17:21:47 +0300 Subject: [PATCH 10/10] fix(models): fix calling get random string pass random length --- simple_email_confirmation/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/simple_email_confirmation/models.py b/simple_email_confirmation/models.py index da1747d..f35c20f 100644 --- a/simple_email_confirmation/models.py +++ b/simple_email_confirmation/models.py @@ -1,5 +1,7 @@ from __future__ import unicode_literals +from random import randint + import django from django.conf import settings from django.contrib.auth import get_user_model @@ -160,7 +162,7 @@ class EmailAddressManager(models.Manager): def generate_key(self): "Generate a new random key and return it" # sticking with the django defaults - return get_random_string() + return get_random_string(length=randint(15, 20)) def create_confirmed(self, email, user=None): "Create an email address in the confirmed state"