Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django-allauth change user email with/without verification

I am using plain django-allauth without any social accounts. Every user should have exactly one email address associated with his account, i.e. the one that was used for registration/verification. I would like to enable my users to change this email.

So my first question is, should I have the new email being verified again by sending out the verifcation email? My gut feeling says, I better have this new email being verified. But I have no real arguments for that.

My second question is, if if want that to be verified, is that process somehow supported already with django-allauth? I have seen the EmailView and AddEmailForm. But those are based on the assumption that one account can have more than 1 email address (which is not what I want).

Thanks

like image 582
schacki Avatar asked Nov 03 '13 16:11

schacki


2 Answers

I think the new email address should be verified. If your application sends periodic emails, you don't want to fire off loads of emails to just any email address that a user enters.

What I did was allow multiple email addresses until the second email is verified. Then, listen for django-allauth's email_confirmed signal as elssar suggested. As soon as the address is verified, set the new email address as the primary email, then delete any previous EmailAddess. Here's a simplified example of what I ended up doing:

models:

from django.dispatch import receiver
from allauth.account.models import EmailAddress
from allauth.account.signals import email_confirmed

class CustomUser(models.Model):
    ...
    def add_email_address(self, request, new_email):
        # Add a new email address for the user, and send email confirmation.
        # Old email will remain the primary until the new one is confirmed.
        return EmailAddress.objects.add_email(request, self.user, new_email, confirm=True)

@receiver(email_confirmed)
def update_user_email(sender, request, email_address, **kwargs):
    # Once the email address is confirmed, make new email_address primary.
    # This also sets user.email to the new email address.
    # email_address is an instance of allauth.account.models.EmailAddress
    email_address.set_as_primary()
    # Get rid of old email addresses
    stale_addresses = EmailAddress.objects.filter(
        user=email_address.user).exclude(primary=True).delete()

views:

def update_user_details(request):
    user = request.user
    new_email = request.POST.get('new_email')
    user.custom_user.add_email_address(request, new_email)
    ...
like image 171
evan_schmevan Avatar answered Oct 22 '22 05:10

evan_schmevan


There are a few ways you could go about doing this.

Either listen to the email_confirmed signal handler, and have a function that checks whether user has two EmailAccount objects associated with his account, and if so, delete the other EmailAccount object.

The other would be set EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL and EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL in your settings and have related view delete the extra email address, if it exists.

Another way would be to just override the EmailView and/or AddEmailForm and have them do what you want.

For changing email without confirmation, you could just have your view call the EmailAddress.change method.

like image 42
elssar Avatar answered Oct 22 '22 04:10

elssar