Skip to content
This repository has been archived by the owner on Mar 22, 2024. It is now read-only.

Multiple users with same email causes barf #463

Open
hazraa opened this issue Nov 12, 2021 · 1 comment
Open

Multiple users with same email causes barf #463

hazraa opened this issue Nov 12, 2021 · 1 comment

Comments

@hazraa
Copy link
Contributor

hazraa commented Nov 12, 2021

.../site-packages/microsoft_auth/backends.py in _verify_microsoft_user
169. user = User.objects.get(email=data["email"])

Maybe particular to our 'incorrect' use case where django admin users can be setup manually and then
are tied to their AD user by the previously manually entered email address. The 'get()' ofcourse barfs on multiples.

@bartTC
Copy link

bartTC commented Dec 23, 2021

We had the same problem, I've overwritten the Backend to make a case insensitive check. I wouldn't say its incorrect. On MS we store emails CamelCase while Django uses lowercase.

import logging

from django.contrib.auth import get_user_model
from microsoft_auth.backends import MicrosoftAuthenticationBackend

logger = logging.getLogger("django")
User = get_user_model()


class CIUserMicrosoftAuthenticationBackend(MicrosoftAuthenticationBackend):
    """
    Extend the original auth backend to use and compare lowercase
    usernames/emails. These methods might need to be updated if the
    upstream class changes.
    """

    def _verify_microsoft_user(self, microsoft_user, data):
        user = microsoft_user.user

        if user is None:
            fullname = data.get("name")
            first_name, last_name = "", ""
            if fullname is not None:
                try:
                    # LastName, FirstName format
                    last_name, first_name = fullname.split(", ")
                except ValueError:
                    try:
                        first_name, last_name = fullname.split(" ", 1)
                    except ValueError:
                        firstname = fullname

            try:
                # create new Django user from provided data
                user = User.objects.get(
                    username__iexact=data["email"].lower()
                )  # ⚠️ Change here

                if user.first_name == "" and user.last_name == "":
                    user.first_name = first_name
                    user.last_name = last_name
                    user.save()
            except User.DoesNotExist:
                user = User(
                    username=data["email"].lower(),  # ⚠️ Change here
                    first_name=first_name,
                    last_name=last_name,
                    email=data["email"].lower(),  # ⚠️ Change here
                )
                user.save()

            existing_account = self._get_existing_microsoft_account(user)
            if existing_account is not None:
                if self.config.MICROSOFT_AUTH_AUTO_REPLACE_ACCOUNTS:
                    existing_account.user = None
                    existing_account.save()
                else:
                    logger.warning(
                        (
                            "User {} already has linked Microsoft "
                            "account and MICROSOFT_AUTH_AUTO_REPLACE_ACCOUNTS "
                            "is False"
                        ).format(user.email)
                    )
                    return None

            microsoft_user.user = user
            microsoft_user.save()

        return user

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants