Wednesday, December 18, 2019

Re: Django security releases issued: 3.0.1, 2.2.9, and 1.11.27

Django developers,

We use Django 2.1 and anyway I saw that Django expects each user to have one email address, where on Speedy Net each user can have multiple email addresses. So I had to override def save in class PasswordResetForm on Speedy Net:

https://github.com/speedy-net/speedy-net/blob/master/speedy/core/accounts/forms.py#L228-L279

I also added logging info to let us know who used the password reset form and who received the password reset link.

I also checked and I noticed that if I reset the password of URI@SPEEDY.NET, the email is sent to URI@SPEEDY.NET instead of uri@speedy.net - the email is sent to the email the user submitted instead of the email the user has on the database. This is a mistake. So I also updated the email to be sent to the email the user has on the database - but the one matching the user input and not just the primary email. So if a user has 2 email addresses, and one stopped working, he can reset his password to the second email address too, even if it's not his primary email address.

I decided to keep using Django 2.1 since there is still not a solution to our Hebrew translation problem which I wrote you about in November.

Here is the code we use now (after I updated it today):

class PasswordResetForm(auth_forms.PasswordResetForm):
@property
def helper(self):
helper = FormHelperWithDefaults()
helper.add_input(Submit('submit', _('Submit')))
return helper

def get_users(self, email):
"""
Given an email, return matching user(s) who should receive a reset.
"""
email_addresses = UserEmailAddress.objects.select_related('user').filter(email__iexact=email.lower())
return {e.user for e in email_addresses if ((e.email == email.lower()) and (e.user.has_usable_password()))}

def send_mail(self, subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None):
"""
Send a django.core.mail.EmailMultiAlternatives to `to_email`.
"""
send_mail(to=[to_email], template_name_prefix='email/accounts/password_reset', context=context)

def save(self, domain_override=None, subject_template_name='registration/password_reset_subject.txt', email_template_name='registration/password_reset_email.html', use_https=False, token_generator=default_token_generator, from_email=None, request=None, html_email_template_name=None, extra_email_context=None):
"""
Generate a one-use only link for resetting password and send it to the user.
"""
email = self.cleaned_data["email"]
site = Site.objects.get_current()
users_list = self.get_users(email)
logger.info("PasswordResetForm::User submitted form, site_name={site_name}, email={email}, matching_users={matching_users}".format(site_name=_(site.name), email=email, matching_users=len(users_list)))
for user in users_list:
if not domain_override:
current_site = get_current_site(request)
site_name = current_site.name
domain = current_site.domain
else:
site_name = domain = domain_override
user_email_list = [e.email for e in user.email_addresses.all() if (e.email == email.lower())]
if (len(user_email_list) == 1):
user_email = user_email_list[0]
logger.info("PasswordResetForm::Sending reset link to the user, site_name={site_name}, user={user}, user_email={user_email}".format(site_name=_(site_name), user=user, user_email=user_email))
context = {
'email': user_email,
'domain': domain,
'site_name': site_name,
'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),
'user': user,
'token': token_generator.make_token(user),
'protocol': 'https' if use_https else 'http',
**(extra_email_context or {}),
}
self.send_mail(subject_template_name, email_template_name, context, from_email, user_email, html_email_template_name=html_email_template_name)
else:
logger.error("PasswordResetForm::User doesn't have a matching email address, site_name={site_name}, user={user}, email={email}".format(site_name=_(site_name), user=user, email=email))

On Wed, Dec 18, 2019 at 11:23 AM Mariusz Felisiak <felisiak.mariusz@gmail.com> wrote:
Details are available on the Django project weblog:

https://www.djangoproject.com/weblog/2019/dec/18/security-releases/

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/87b42e7f-f80e-bd2b-6217-485b2fe41d37%40gmail.com.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CABD5YeEDBQeX5N1YPdOevtn4td5NfXbDXC%3Dd%2BxfaXU5mVwYGHA%40mail.gmail.com.

No comments:

Post a Comment