From ef72099edd1986bb065fa7fd9650fda41d95fe6c Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Mon, 4 Dec 2017 15:10:47 +0100 Subject: [PATCH 2/3] utils: factorize sending of email change verification email (#19716) --- src/authentic2/manager/forms.py | 2 +- src/authentic2/utils.py | 50 +++++++++++++++++++++++++++++++++++++++++ src/authentic2/views.py | 39 ++------------------------------ 3 files changed, 53 insertions(+), 38 deletions(-) diff --git a/src/authentic2/manager/forms.py b/src/authentic2/manager/forms.py index d78b7c3..93aacc5 100644 --- a/src/authentic2/manager/forms.py +++ b/src/authentic2/manager/forms.py @@ -622,7 +622,7 @@ class OUEditForm(SlugMixin, CssClass, forms.ModelForm): class Meta: model = get_ou_model() - fields = ('name', 'default', 'username_is_unique', 'email_is_unique', 'validate_emails') + fields = ('name', 'default', 'username_is_unique', 'email_is_unique') def get_role_form_class(): diff --git a/src/authentic2/utils.py b/src/authentic2/utils.py index d3383ab..bdcb7b9 100644 --- a/src/authentic2/utils.py +++ b/src/authentic2/utils.py @@ -979,3 +979,53 @@ def simulate_authentication(request, user, method, def get_manager_login_url(): from authentic2.manager import app_settings return app_settings.LOGIN_URL or settings.LOGIN_URL + + +def send_email_change_mail(user, email, request=None, context=None, template_names=None): + '''Send an email to verify that user can take email as its new email''' + assert user + assert email + + logger = logging.getLogger(__name__) + + if template_names is None: + template_names = ['authentic2/change_email_notification'] + legacy_subject_templates = ['profiles/email_change_subject.txt'] + legacy_body_templates = ['profiles/email_change_body.txt'] + else: + legacy_subject_templates = None + legacy_body_templates = None + + # build verify email URL containing a signed token + token = signing.dumps({ + 'email': email, + 'user_pk': user.pk, + }) + link = '{0}?token={1}'.format(reverse('email-change-verify'), token) + link = request.build_absolute_uri(link) + + # check if email should be unique and is not + email_is_not_unique = False + qs = get_user_model().objects.all() + if app_settings.A2_EMAIL_IS_UNIQUE: + email_is_not_unique = qs.filter(email=email).exclude(pk=user.pk).exists() + elif user.ou and user.ou.email_is_unique: + email_is_not_unique = qs.filter(email=email, ou=user.ou).exclude(pk=user.pk).exists() + ctx = context or {} + ctx.update({ + 'email': email, + 'old_email': user.email, + 'user': user, + 'link': link, + 'domain': request.get_host(), + 'token_lifetime': human_duration(app_settings.A2_EMAIL_CHANGE_TOKEN_LIFETIME), + 'password_reset_url': request.build_absolute_uri(reverse('password_reset')), + 'email_is_not_unique': email_is_not_unique, + }) + logger.info(u'sent email verify email to %s for %s', email, user) + send_templated_mail( + email, + template_names, + context=ctx, + legacy_subject_templates=legacy_subject_templates, + legacy_body_templates=legacy_body_templates) diff --git a/src/authentic2/views.py b/src/authentic2/views.py index e4a559e..85874b8 100644 --- a/src/authentic2/views.py +++ b/src/authentic2/views.py @@ -152,9 +152,7 @@ class EmailChangeView(cbv.TemplateNamesMixin, FormView): def get_form_kwargs(self): kwargs = super(EmailChangeView, self).get_form_kwargs() - kwargs.update({ - 'user': self.request.user, - }) + kwargs['user'] = self.request.user return kwargs def post(self, request, *args, **kwargs): @@ -162,42 +160,9 @@ class EmailChangeView(cbv.TemplateNamesMixin, FormView): return utils.redirect(request, 'account_management') return super(EmailChangeView, self).post(request, *args, **kwargs) - @classmethod - def send_email_change_email(cls, request, user, email): - token = signing.dumps({ - 'email': email, - 'user_pk': user.pk, - }) - link = '{0}?token={1}'.format( - reverse('email-change-verify'), - token) - link = request.build_absolute_uri(link) - ctx = { - 'email': email, - 'old_email': user.email, - 'user': user, - 'link': link, - 'domain': request.get_host(), - 'token_lifetime': utils.human_duration(app_settings.A2_EMAIL_CHANGE_TOKEN_LIFETIME), - 'password_reset_url': request.build_absolute_uri(reverse('password_reset')), - } - qs = compat.get_user_model().objects.all() - if app_settings.A2_EMAIL_IS_UNIQUE: - ctx['email_is_not_unique'] = qs.filter(email=email).exclude(pk=user.pk).exists() - elif user.ou and user.ou.email_is_unique: - ctx['email_is_not_unique'] = qs.filter(email=email, - ou=user.ou).exclude(pk=user.pk).exists() - - utils.send_templated_mail( - email, - ['authentic2/change_email_notification'], - context=ctx, - legacy_subject_templates=['profiles/email_change_subject.txt'], - legacy_body_templates=['profiles/email_change_body.txt']) - def form_valid(self, form): email = form.cleaned_data['email'] - self.send_email_change_email(self.request, self.request.user, email) + utils.send_email_change_mail(self.request.user, email, request=self.request) hooks.call_hooks('event', name='change-email', user=self.request.user, email=email) messages.info( self.request, -- 2.1.4